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 12 import scipy
13 13 import scipy.misc
14 14 import envi
  15 +import random
15 16  
16 17 #generate a 2D color class map using a stack of binary class images
17 18 #input: C is a C x Y x X binary image
... ... @@ -120,16 +121,27 @@ def prob2roc(P, t_vals, mask=[]):
120 121 return sklearn.metrics.roc_curve(labels, scores)
121 122  
122 123 #convert a label image to a C x Y x X class image
123   -def label2class(L):
  124 +def label2class(L, background=[]):
124 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 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 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 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 145 #Function to convert a set of class labels to a matrix of neuron responses for an ANN
134 146  
135 147 #Function CNN extraction function
136 148 \ No newline at end of file
... ...
python/envi.py
... ... @@ -185,7 +185,7 @@ class envi:
185 185 def __init__(self, filename, headername = "", mask = []):
186 186 self.open(filename, headername)
187 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 189 else:
190 190 self.mask = mask
191 191 self.idx = 0 #initialize the batch IDX to 0 for batch reading
... ... @@ -304,7 +304,9 @@ class envi:
304 304 #read a batch of data based on the mask
305 305 def loadbatch(self, npixels):
306 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 310 B = self.header.bands
309 311  
310 312 batch = numpy.zeros((B, npixels), dtype=self.header.data_type) #allocate space for the batch
... ... @@ -316,8 +318,6 @@ class envi:
316 318 self.file.readinto(pixel) #read a single pixel
317 319 batch[:, n] = pixel #save the pixel into the batch matrix
318 320 self.idx = self.idx + 1
319   - #print("idx: " + str(self.idx))
320   - #print("tell(): " + str(self.file.tell()))
321 321 return batch
322 322 elif self.header.interleave == "bsq":
323 323 print("ERROR: BSQ batch loading isn't implemented yet!")
... ... @@ -327,6 +327,18 @@ class envi:
327 327 #returns the current batch index
328 328 def getidx(self):
329 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 343 def __del__(self):
332 344 self.file.close()
333 345 \ No newline at end of file
... ...
python/spectral.py
... ... @@ -13,14 +13,14 @@ def sift2(I, mask = []):
13 13 S = I.shape
14 14  
15 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 18 #gif no mask is provided, just return all pixels
19 19 if mask == []:
20 20 return M
21 21  
22 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 24 i = numpy.flatnonzero(flatmask) #get the nonzero indices
25 25 return M[:, i] #return pixels corresponding to the masked values
26 26  
... ...