Commit 777fef6ce76d87292ef89f1b03db1b7655c3b080
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 |
python/envi.py
@@ -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 |