Commit 777fef6ce76d87292ef89f1b03db1b7655c3b080

Authored by David Mayerich
1 parent 71ee1c23

added digital staining functions in Python

Showing 3 changed files with 35 additions and 11 deletions   Show diff stats
python/classify.py
@@ -12,6 +12,7 @@ import sklearn.metrics @@ -12,6 +12,7 @@ import sklearn.metrics
12 import scipy 12 import scipy
13 import scipy.misc 13 import scipy.misc
14 import envi 14 import envi
  15 +import random
15 16
16 #generate a 2D color class map using a stack of binary class images 17 #generate a 2D color class map using a stack of binary class images
17 #input: C is a C x Y x X binary image 18 #input: C is a C x Y x X binary image
@@ -120,16 +121,27 @@ def prob2roc(P, t_vals, mask=[]): @@ -120,16 +121,27 @@ def prob2roc(P, t_vals, mask=[]):
120 return sklearn.metrics.roc_curve(labels, scores) 121 return sklearn.metrics.roc_curve(labels, scores)
121 122
122 #convert a label image to a C x Y x X class image 123 #convert a label image to a C x Y x X class image
123 -def label2class(L): 124 +def label2class(L, background=[]):
124 unique = numpy.unique(L) 125 unique = numpy.unique(L)
  126 +
  127 + if not background == []: #if a background value is specified
  128 + unique = numpy.delete(unique, numpy.nonzero(unique == background)) #remove it from the label array
125 s = L.shape 129 s = L.shape
126 - s = numpy.append(numpy.array((len(unique)-1)), s)  
127 - print(s) 130 + s = numpy.append(numpy.array((len(unique))), s)
128 C = numpy.zeros(s, dtype=numpy.bool) 131 C = numpy.zeros(s, dtype=numpy.bool)
129 - for i in range(1, len(unique)):  
130 - C[i-1, :, :] = L == unique[i] 132 + for i in range(0, len(unique)):
  133 + C[i, :, :] = L == unique[i]
131 return C 134 return C
132 135
  136 +#randomizes a given mask to include a subset of n pixels in the original
  137 +def random_mask(M, n):
  138 + idx = numpy.flatnonzero(M)
  139 + new_idx = numpy.random.permutation(idx)
  140 + new_mask = numpy.zeros(M.shape, dtype=numpy.bool)
  141 + new_mask[numpy.unravel_index(new_idx[0:n], new_mask.shape)] = True
  142 + return new_mask
  143 +
  144 +
133 #Function to convert a set of class labels to a matrix of neuron responses for an ANN 145 #Function to convert a set of class labels to a matrix of neuron responses for an ANN
134 146
135 #Function CNN extraction function 147 #Function CNN extraction function
136 \ No newline at end of file 148 \ No newline at end of file
@@ -185,7 +185,7 @@ class envi: @@ -185,7 +185,7 @@ class envi:
185 def __init__(self, filename, headername = "", mask = []): 185 def __init__(self, filename, headername = "", mask = []):
186 self.open(filename, headername) 186 self.open(filename, headername)
187 if mask == []: 187 if mask == []:
188 - self.mask = numpy.ones((self.header.samples, self.header.lines), dtype=numpy.bool) 188 + self.mask = numpy.ones((self.header.lines, self.header.samples), dtype=numpy.bool)
189 else: 189 else:
190 self.mask = mask 190 self.mask = mask
191 self.idx = 0 #initialize the batch IDX to 0 for batch reading 191 self.idx = 0 #initialize the batch IDX to 0 for batch reading
@@ -304,7 +304,9 @@ class envi: @@ -304,7 +304,9 @@ class envi:
304 #read a batch of data based on the mask 304 #read a batch of data based on the mask
305 def loadbatch(self, npixels): 305 def loadbatch(self, npixels):
306 i = numpy.flatnonzero(self.mask) #get the indices of valid pixels 306 i = numpy.flatnonzero(self.mask) #get the indices of valid pixels
307 - npixels = min(npixels, len(i) - self.idx - 1) #if there aren't enough pixels, change the batch size 307 + if len(i) == self.idx: #if all of the pixels have been read, return an empyt array
  308 + return []
  309 + npixels = min(npixels, len(i) - self.idx) #if there aren't enough pixels, change the batch size
308 B = self.header.bands 310 B = self.header.bands
309 311
310 batch = numpy.zeros((B, npixels), dtype=self.header.data_type) #allocate space for the batch 312 batch = numpy.zeros((B, npixels), dtype=self.header.data_type) #allocate space for the batch
@@ -316,8 +318,6 @@ class envi: @@ -316,8 +318,6 @@ class envi:
316 self.file.readinto(pixel) #read a single pixel 318 self.file.readinto(pixel) #read a single pixel
317 batch[:, n] = pixel #save the pixel into the batch matrix 319 batch[:, n] = pixel #save the pixel into the batch matrix
318 self.idx = self.idx + 1 320 self.idx = self.idx + 1
319 - #print("idx: " + str(self.idx))  
320 - #print("tell(): " + str(self.file.tell()))  
321 return batch 321 return batch
322 elif self.header.interleave == "bsq": 322 elif self.header.interleave == "bsq":
323 print("ERROR: BSQ batch loading isn't implemented yet!") 323 print("ERROR: BSQ batch loading isn't implemented yet!")
@@ -327,6 +327,18 @@ class envi: @@ -327,6 +327,18 @@ class envi:
327 #returns the current batch index 327 #returns the current batch index
328 def getidx(self): 328 def getidx(self):
329 return self.idx 329 return self.idx
  330 +
  331 + #returns an image of the pixels that have been read using batch loading
  332 + def batchmask(self):
  333 + #allocate a new mask
  334 + outmask = numpy.zeros(self.mask.shape, dtype=numpy.bool)
  335 +
  336 + #zero out any unclassified pixels
  337 + idx = self.getidx()
  338 + i = numpy.nonzero(self.mask)
  339 + outmask[i[0][0:idx], i[1][0:idx]] = self.mask[i[0][0:idx], i[1][0:idx]]
  340 + return outmask
  341 +
330 342
331 def __del__(self): 343 def __del__(self):
332 self.file.close() 344 self.file.close()
333 \ No newline at end of file 345 \ No newline at end of file
python/spectral.py
@@ -13,14 +13,14 @@ def sift2(I, mask = []): @@ -13,14 +13,14 @@ def sift2(I, mask = []):
13 S = I.shape 13 S = I.shape
14 14
15 #convert that array into a 1D matrix 15 #convert that array into a 1D matrix
16 - M = numpy.reshape(I, (S[2], S[0] * S[1])) 16 + M = numpy.reshape(I, (S[0], S[1] * S[2]))
17 17
18 #gif no mask is provided, just return all pixels 18 #gif no mask is provided, just return all pixels
19 if mask == []: 19 if mask == []:
20 return M 20 return M
21 21
22 #if a mask is provided, only return pixels corresponding to that mask 22 #if a mask is provided, only return pixels corresponding to that mask
23 - flatmask = numpy.reshape(mask, (S[0] * S[1])) 23 + flatmask = numpy.reshape(mask, (S[1] * S[2]))
24 i = numpy.flatnonzero(flatmask) #get the nonzero indices 24 i = numpy.flatnonzero(flatmask) #get the nonzero indices
25 return M[:, i] #return pixels corresponding to the masked values 25 return M[:, i] #return pixels corresponding to the masked values
26 26