Commit 6b2be99133073dc9ffbdddfc8afd03f3bab61547
1 parent
538df2a2
added utility functions: image2class, generate_traiing, prob2class and example script
Showing
3 changed files
with
91 additions
and
1 deletions
Show diff stats
python/classify.py
... | ... | @@ -7,6 +7,8 @@ Created on Sun Jul 23 16:04:33 2017 |
7 | 7 | |
8 | 8 | import numpy |
9 | 9 | import colorsys |
10 | +from scipy import misc | |
11 | +from envi import envi | |
10 | 12 | |
11 | 13 | #generate a 2D color class map using a stack of binary class images |
12 | 14 | def classcolor2(C): |
... | ... | @@ -29,15 +31,72 @@ def classcolor2(C): |
29 | 31 | #input: list of class image names |
30 | 32 | #output: X x Y x C stack of binary mask images |
31 | 33 | #example: image2class(("class_coll.bmp", "class_epith.bmp")) |
34 | +def image2class(*masks): | |
35 | + #get num of mask file names | |
36 | + num_masks = len(masks) | |
37 | + | |
38 | + if num_masks == 0: | |
39 | + print("ERROR: mask filenames not provided") | |
40 | + print("Usage example: image2class(('class_coll.bmp', 'class_epith.bmp'))") | |
41 | + return | |
42 | + | |
43 | + #load first mask to get dimensions -- assuming all masks have same dimensions | |
44 | + mask = misc.imread(masks[0], flatten=True).astype(numpy.bool) | |
45 | + | |
46 | + mask_stack = numpy.zeros((mask.shape[0], mask.shape[1], num_masks), dtype=numpy.bool) | |
47 | + mask_stack[:,:,0] = mask | |
48 | + | |
49 | + #load the rest of masks | |
50 | + for i in range(1, num_masks): | |
51 | + mask_stack[:,:,i] = misc.imread(masks[i], flatten=True).astype(numpy.bool) | |
52 | + | |
53 | + return mask_stack | |
54 | + | |
32 | 55 | |
33 | 56 | #create a set of feature/target pairs for classification |
34 | 57 | #input: envi file object, stack of class masks, list of class names |
35 | 58 | #output: feature matrix (features x pixels), target matrix (1 x pixels) |
36 | 59 | #example: generate_training(("class_coll.bmp", "class_epith.bmp"), (1, 2)) |
60 | +def generate_training(filename, mask_stack): | |
61 | + #create envi file object | |
62 | + E = envi(filename) | |
63 | + | |
64 | + # get number of classes | |
65 | + C = mask_stack.shape[2] | |
66 | + | |
67 | + #get number of annotated pixels | |
68 | + num_pixels = 0 | |
69 | + for i in range(0,C): | |
70 | + num_pixels += numpy.count_nonzero(mask_stack[:,:,i]) | |
71 | + | |
72 | + feature_matrix = numpy.zeros((E.header.bands, num_pixels), dtype=E.header.data_type) | |
73 | + target_matrix = numpy.zeros((1, num_pixels)) | |
74 | + | |
75 | + #load masks and append the corresponding pixels to feature matrix and labels to target_matrix | |
76 | + idx = 0 | |
77 | + for i in range(0,C): | |
78 | + mask = E.loadmask(mask_stack[:,:,i]) | |
79 | + feature_matrix[:, idx:idx + mask.shape[1]] = mask | |
80 | + target_matrix[idx:idx+mask.shape[1]] = (i+1) | |
81 | + idx += mask.shape[1] | |
82 | + | |
83 | + return feature_matrix, target_matrix | |
37 | 84 | |
38 | 85 | #create a class mask stack from an X x Y x C probability image |
39 | 86 | #input: X x Y x C image giving the probability P(c |x,y) |
40 | 87 | #output: X x Y x C binary class image |
88 | +def prob2class(prob_image): | |
89 | + class_image = numpy.zeros_like(prob_image) | |
90 | + #get nonzero indices | |
91 | + nnz_idx = numpy.transpose(numpy.nonzero(numpy.sum(prob_image, axis=0))) | |
92 | + | |
93 | + #set pixel corresponding to max probability to 1 | |
94 | + for idx in nnz_idx: | |
95 | + idx_max_prob = numpy.argmax(prob_image[:, idx[0], idx[1]]) | |
96 | + class_image[idx_max_prob, idx[0], idx[1]] = 1 | |
97 | + | |
98 | + return class_image | |
99 | + | |
41 | 100 | |
42 | 101 | #create an ROC curve calculator |
43 | 102 | #input: X x Y x C image giving the probability P(c | x,y) | ... | ... |
python/envi.py
... | ... | @@ -139,9 +139,18 @@ class envi_header: |
139 | 139 | #handle the complicated conditions |
140 | 140 | elif l[li].startswith("description"): |
141 | 141 | desc = [l[li]] |
142 | - while l[li].strip()[-1] != '}': | |
142 | + ''' | |
143 | + while l[li].strip()[-1] != '}': #will fail if l[li].strip() is empty | |
144 | + li += 1 | |
145 | + desc.append(l[li]) | |
146 | + ''' | |
147 | + while True: | |
148 | + if l[li].strip(): | |
149 | + if l[li].strip()[-1] == '}': | |
150 | + break | |
143 | 151 | li += 1 |
144 | 152 | desc.append(l[li]) |
153 | + | |
145 | 154 | desc = ''.join(list(map(str.strip, desc))) #strip all white space from the string list |
146 | 155 | i0 = desc.rindex('{') |
147 | 156 | i1 = desc.rindex('}') | ... | ... |
1 | +import numpy | |
2 | +import classify | |
3 | +import matplotlib.pyplot as plt | |
4 | +from envi import envi | |
5 | + | |
6 | +mask_path = '/home/sberisha/data/masks/' | |
7 | +mask_stack = classify.image2class(mask_path + "class_blood.png", mask_path + "class_coll.png", mask_path + "class_epith.png", | |
8 | + mask_path + "class_lymph.png", mask_path + "class_necrosis.png") | |
9 | + | |
10 | +color_image = classify.classcolor2(mask_stack) | |
11 | +plt.imshow(color_image) | |
12 | + | |
13 | +data_path ='/home/sberisha/data/cnn/brc961-nfp8/envi/' | |
14 | + | |
15 | +feature_matrix, target_matrix = classify.generate_training(data_path + 'brc961-nfp8-project-br1003', mask_stack) | |
16 | + | |
17 | +prob_path = '/home/sberisha/data/' | |
18 | +prob_envi= envi(prob_path + "cnn-response") | |
19 | +prob_image = prob_envi.loadall() | |
20 | + | |
21 | +class_image = classify.prob2class(prob_image) | |
22 | +plt.imshow(class_image[4,:,:]) | |
0 | 23 | \ No newline at end of file | ... | ... |