From 777fef6ce76d87292ef89f1b03db1b7655c3b080 Mon Sep 17 00:00:00 2001 From: David Mayerich Date: Tue, 25 Jul 2017 18:48:00 -0500 Subject: [PATCH] added digital staining functions in Python --- python/classify.py | 22 +++++++++++++++++----- python/envi.py | 20 ++++++++++++++++---- python/spectral.py | 4 ++-- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/python/classify.py b/python/classify.py index ef6e610..2cf4388 100644 --- a/python/classify.py +++ b/python/classify.py @@ -12,6 +12,7 @@ import sklearn.metrics import scipy import scipy.misc import envi +import random #generate a 2D color class map using a stack of binary class images #input: C is a C x Y x X binary image @@ -120,16 +121,27 @@ def prob2roc(P, t_vals, mask=[]): return sklearn.metrics.roc_curve(labels, scores) #convert a label image to a C x Y x X class image -def label2class(L): +def label2class(L, background=[]): unique = numpy.unique(L) + + if not background == []: #if a background value is specified + unique = numpy.delete(unique, numpy.nonzero(unique == background)) #remove it from the label array s = L.shape - s = numpy.append(numpy.array((len(unique)-1)), s) - print(s) + s = numpy.append(numpy.array((len(unique))), s) C = numpy.zeros(s, dtype=numpy.bool) - for i in range(1, len(unique)): - C[i-1, :, :] = L == unique[i] + for i in range(0, len(unique)): + C[i, :, :] = L == unique[i] return C +#randomizes a given mask to include a subset of n pixels in the original +def random_mask(M, n): + idx = numpy.flatnonzero(M) + new_idx = numpy.random.permutation(idx) + new_mask = numpy.zeros(M.shape, dtype=numpy.bool) + new_mask[numpy.unravel_index(new_idx[0:n], new_mask.shape)] = True + return new_mask + + #Function to convert a set of class labels to a matrix of neuron responses for an ANN #Function CNN extraction function \ No newline at end of file diff --git a/python/envi.py b/python/envi.py index b4619fc..cbfc82a 100644 --- a/python/envi.py +++ b/python/envi.py @@ -185,7 +185,7 @@ class envi: def __init__(self, filename, headername = "", mask = []): self.open(filename, headername) if mask == []: - self.mask = numpy.ones((self.header.samples, self.header.lines), dtype=numpy.bool) + self.mask = numpy.ones((self.header.lines, self.header.samples), dtype=numpy.bool) else: self.mask = mask self.idx = 0 #initialize the batch IDX to 0 for batch reading @@ -304,7 +304,9 @@ class envi: #read a batch of data based on the mask def loadbatch(self, npixels): i = numpy.flatnonzero(self.mask) #get the indices of valid pixels - npixels = min(npixels, len(i) - self.idx - 1) #if there aren't enough pixels, change the batch size + if len(i) == self.idx: #if all of the pixels have been read, return an empyt array + return [] + npixels = min(npixels, len(i) - self.idx) #if there aren't enough pixels, change the batch size B = self.header.bands batch = numpy.zeros((B, npixels), dtype=self.header.data_type) #allocate space for the batch @@ -316,8 +318,6 @@ class envi: self.file.readinto(pixel) #read a single pixel batch[:, n] = pixel #save the pixel into the batch matrix self.idx = self.idx + 1 - #print("idx: " + str(self.idx)) - #print("tell(): " + str(self.file.tell())) return batch elif self.header.interleave == "bsq": print("ERROR: BSQ batch loading isn't implemented yet!") @@ -327,6 +327,18 @@ class envi: #returns the current batch index def getidx(self): return self.idx + + #returns an image of the pixels that have been read using batch loading + def batchmask(self): + #allocate a new mask + outmask = numpy.zeros(self.mask.shape, dtype=numpy.bool) + + #zero out any unclassified pixels + idx = self.getidx() + i = numpy.nonzero(self.mask) + outmask[i[0][0:idx], i[1][0:idx]] = self.mask[i[0][0:idx], i[1][0:idx]] + return outmask + def __del__(self): self.file.close() \ No newline at end of file diff --git a/python/spectral.py b/python/spectral.py index ee94dff..6f56001 100644 --- a/python/spectral.py +++ b/python/spectral.py @@ -13,14 +13,14 @@ def sift2(I, mask = []): S = I.shape #convert that array into a 1D matrix - M = numpy.reshape(I, (S[2], S[0] * S[1])) + M = numpy.reshape(I, (S[0], S[1] * S[2])) #gif no mask is provided, just return all pixels if mask == []: return M #if a mask is provided, only return pixels corresponding to that mask - flatmask = numpy.reshape(mask, (S[0] * S[1])) + flatmask = numpy.reshape(mask, (S[1] * S[2])) i = numpy.flatnonzero(flatmask) #get the nonzero indices return M[:, i] #return pixels corresponding to the masked values -- libgit2 0.21.4