classify.py
3.84 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
# -*- 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 classcolor2(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)
#Function to convert a set of class labels to a matrix of neuron responses for an ANN
#Function CNN extraction function