classify.py
4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# -*- coding: utf-8 -*-
"""
Created on Sun Jul 23 16:04:33 2017
@author: david
"""
import numpy
import colorsys
import sklearn
import sklearn.metrics
import scipy
import scipy.misc
import envi
#generate a 2D color class map using a stack of binary class images
#input: C is a C x Y x X binary image
#output: an RGB color image with a unique color for each class
def class2color(C):
#determine the number of classes
nc = C.shape[0]
s = C.shape[1:]
s = numpy.append(s, 3)
#generate an RGB image
RGB = numpy.zeros(s, dtype=numpy.ubyte)
#for each class
for c in range(0, nc):
hsv = (c * 1.0 / nc, 1, 1)
color = numpy.asarray(colorsys.hsv_to_rgb(hsv[0], hsv[1], hsv[2])) * 255
RGB[C[c, ...], :] = color
return RGB
#create a function that loads a set of class images as a stack of binary masks
#input: list of class image names
#output: C x Y x X binary image specifying class/pixel membership
#example: image2class(("class_coll.bmp", "class_epith.bmp"))
def image2class(masks):
#get num of mask file names
num_masks = len(masks)
if num_masks == 0:
print("ERROR: mask filenames not provided")
print("Usage example: image2class(('class_coll.bmp', 'class_epith.bmp'))")
return
classimages = []
for m in masks:
img = scipy.misc.imread(m, flatten=True).astype(numpy.bool)
classimages.append(img)
result = numpy.stack(classimages)
sum_images = numpy.sum(result.astype(numpy.uint32), 0)
#identify and remove redundant pixels
bad_idx = sum_images > 1
result[:, bad_idx] = 0
return result
#create a class mask stack from an C x Y x X probability image
#input: C x Y x X image giving the probability P(c |x,y)
#output: C x Y x X binary class image
def prob2class(prob_image):
class_image = numpy.zeros(prob_image.shape, dtype=numpy.bool)
#get nonzero indices
nnz_idx = numpy.transpose(numpy.nonzero(numpy.sum(prob_image, axis=0)))
#set pixel corresponding to max probability to 1
for idx in nnz_idx:
idx_max_prob = numpy.argmax(prob_image[:, idx[0], idx[1]])
class_image[idx_max_prob, idx[0], idx[1]] = 1
return class_image
#calculate an ROC curve given a probability image and mask of "True" values
#input:
# P is a Y x X probability image specifying P(c | x,y)
# t_vals is a Y x X binary image specifying points where x,y = c
# mask is a mask specifying all pixels to be considered (positives and negatives)
# use this mask to limit analysis to regions of the image that have been classified
#output: fpr, tpr, thresholds
# fpr is the false-positive rate (x-axis of an ROC curve)
# tpr is the true-positive rate (y-axis of an ROC curve)
# thresholds stores the threshold associated with each point on the ROC curve
#
#note: the AUC can be calculated as auc = sklearn.metrics.auc(fpr, tpr)
def prob2roc(P, t_vals, mask=[]):
if not P.shape == t_vals.shape:
print("ERROR: the probability and mask images must be the same shape")
return
#if a mask image isn't provided, create one for the entire image
if mask == []:
mask = numpy.ones(t_vals.shape, dtype=numpy.bool)
#create masks for the positive and negative probability scores
mask_p = t_vals
mask_n = mask - mask * t_vals
#calculate the indices for the positive and negative scores
idx_p = numpy.nonzero(mask_p)
idx_n = numpy.nonzero(mask_n)
Pp = P[idx_p]
Pn = P[idx_n]
Lp = numpy.ones((Pp.shape), dtype=numpy.bool)
Ln = numpy.zeros((Pn.shape), dtype=numpy.bool)
scores = numpy.concatenate((Pp, Pn))
labels = numpy.concatenate((Lp, Ln))
return sklearn.metrics.roc_curve(labels, scores)
#convert a label image to a C x Y x X class image
def label2class(L):
unique = numpy.unique(L)
s = L.shape
s = numpy.append(numpy.array((len(unique)-1)), s)
print(s)
C = numpy.zeros(s, dtype=numpy.bool)
for i in range(1, len(unique)):
C[i-1, :, :] = L == unique[i]
return C
#Function to convert a set of class labels to a matrix of neuron responses for an ANN
#Function CNN extraction function