forked from Azure/ImageClassificationUsingCntk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path7_activeLearning_step2.py
158 lines (136 loc) · 6.12 KB
/
7_activeLearning_step2.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# -*- coding: utf-8 -*-
from helpers import *
#from helpers_cntk import *
locals().update(importlib.import_module("PARAMETERS").__dict__)
####################################
# Parameters
####################################
imgOutRootDir = pathJoin(resultsDir, "activeLearning")
####################################
# Main
####################################
# Load data
dnnOutput = readPickle(al_dnnOutputPath)
lutId2Label = readPickle(lutId2LabelPath)
if pathExists(imgOutRootDir):
for subdir in getDirectoriesInDirectory(imgOutRootDir):
assert len(getFilesInDirectory(pathJoin(imgOutRootDir,subdir))) == 0, "ERROR: output directory is not empty."
# Predicted labels and scores
# Example svm scoresMatrix row: array([ 0.08620614, -1.1153569 , -0.08649196])
# Example dnn scoresMatrix row: array([ 0.40908358, -0.74543875, 5.61107969])
scoresMatrix, imgFilenames, _ = runClassifier(classifier, dnnOutput, [], [], svmPath, svm_boL2Normalize)
predLabels = [np.argmax(scores) for scores in scoresMatrix]
predLabels = [lutId2Label[i] for i in predLabels]
predScores = [np.max(scores) for scores in scoresMatrix]
scoresMatrixNormalized = np.array([(row - min(row)) / sum(row - min(row)) for row in scoresMatrix])
predScoresNormalized = [np.max(scores) for scores in scoresMatrixNormalized]
# Select which images to annotate first
print("Selection criteria = " + al_selectionCriteria)
if al_selectionCriteria == "inorder":
imgIndices = range(len(predScores))
imgScores = predScores
if al_selectionCriteria == "random":
imgIndices = randomizeList(list(range(len(predScores))))
imgScores = [predScores[i] for i in imgIndices]
elif al_selectionCriteria == "lowestScore":
imgScores, imgIndices = listSort(np.abs(predScores))
elif al_selectionCriteria == "heighestScore":
imgScores, imgIndices = listSort(np.abs(predScores), reverseSort=True)
elif al_selectionCriteria == "lowestScoreNormalized":
imgScores, imgIndices = listSort(np.abs(predScoresNormalized))
elif al_selectionCriteria == "heighestScoreNormalized":
imgScores, imgIndices = listSort(np.abs(predScoresNormalized), reverseSort=True)
else:
raise Exception("ERROR: selection criteria unknown: " + al_selectionCriteria)
# Load previously provided annotation (if exists)
if pathExists(al_annotationsPath):
print("Loading existing annotations from: " + al_annotationsPath)
annotations = readPickle(al_annotationsPath)
else:
print("No previously provided annotations found.")
annotations = dict()
#-----------------------------------------------------------------------------------------------------------------------
# Instructions
print("""
USAGE:
Press a key at each image, where key can be:
- Any number in range [1-9] to assign the corresponding label.
- 'n' to go to the next image without providing any annotation.
- 'i' to assign the label 'ignore'.
- 'b' to go back to the previous image without changing any annotations.
- 'q' to quit this annotation tool.
""")
# Get human annotation for each image
key = ""
loopImgIndex = 0
historyLoopImgIndex = []
while loopImgIndex < len(imgIndices) and key != 'q':
imgIndex = imgIndices[loopImgIndex]
imgScore = imgScores[loopImgIndex]
imgFilename = imgFilenames[imgIndex]
imgPath = os.path.join(imgUnlabeledDir, imgFilename)
# check if label was already provided during previous annotation
if imgFilename in annotations:
humanLabel = annotations[imgFilename]
if key != 'b': #only go to next image if user did not just go back to previous image
loopImgIndex += 1
print("Skipping image {:4} since already annotated as {:<10}: {}.".format(loopImgIndex, humanLabel, imgFilename))
continue
else:
humanLabel = 'unlabeled'
#show image
img, _ = imresizeMaxDim(imread(imgPath), 800, boUpscale = True)
title = "Score={:2.2f}, Label={}".format(imgScore, humanLabel)
title += " --- " + ", ".join(["{}={}".format(i+1, lutId2Label[i]) for i in sorted(list(lutId2Label.keys()))])
cv2.destroyAllWindows()
cv2.imshow(title, img)
#parse user input
historyLoopImgIndex.append(loopImgIndex)
while (True):
key = chr(cv2.waitKey())
# Provided annotation
if key.isdigit():
label = lutId2Label[int(key)-1]
print("Assigning image {} the label: {}".format(imgIndex,label))
annotations[imgFilename] = label
#cv2.imshow(imgTitle, np.zeros((100, 100, 3), np.uint8))
writePickle(al_annotationsPath, annotations)
loopImgIndex += 1
# Skip to next image
elif key == 'n':
print("Going from image {} to next image.".format(imgIndex))
loopImgIndex +=1
# Annotation ignore
elif key == 'i':
print("Assigning image {} the label: ignore.".format(imgIndex))
annotations[imgFilename] = 'ignore'
writePickle(al_annotationsPath, annotations)
loopImgIndex += 1
# Back to previous image
elif key == 'b':
if len(historyLoopImgIndex) > 1:
print("Going back from image {} to previous image.".format(imgIndex))
loopImgIndex = historyLoopImgIndex[-2]
historyLoopImgIndex = historyLoopImgIndex[:-2]
# Quit
elif key == 'q':
print("Exiting annotation UI")
break
else:
continue
break # user input done for this image.
cv2.destroyAllWindows()
#-----------------------------------------------------------------------------------------------------------------------
# Copy all annotated images
print("Copying images")
makeDirectory(imgOutRootDir)
for imgIndex, imgFilename in enumerate(annotations):
imgLabel = annotations[imgFilename]
srcPath = pathJoin(imgUnlabeledDir, imgFilename)
if imgLabel != 'ignore' and os.path.exists(srcPath):
dstDir = pathJoin(imgOutRootDir, imgLabel)
dstPath = pathJoin(dstDir, imgFilename)
makeDirectory(dstDir)
print("Copying image {} of {}: from {} to {}".format(imgIndex, len(annotations), srcPath, dstPath))
shutil.copy(srcPath, dstPath)
print("DONE.")