Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/python/test/test_dnn.py
16337 views
1
#!/usr/bin/env python
2
import os
3
import cv2 as cv
4
import numpy as np
5
6
from tests_common import NewOpenCVTests, unittest
7
8
def normAssert(test, a, b, lInf=1e-5):
9
test.assertLess(np.max(np.abs(a - b)), lInf)
10
11
def inter_area(box1, box2):
12
x_min, x_max = max(box1[0], box2[0]), min(box1[2], box2[2])
13
y_min, y_max = max(box1[1], box2[1]), min(box1[3], box2[3])
14
return (x_max - x_min) * (y_max - y_min)
15
16
def area(box):
17
return (box[2] - box[0]) * (box[3] - box[1])
18
19
def box2str(box):
20
left, top = box[0], box[1]
21
width, height = box[2] - left, box[3] - top
22
return '[%f x %f from (%f, %f)]' % (width, height, left, top)
23
24
def normAssertDetections(test, ref, out, confThreshold=0.0, scores_diff=1e-5, boxes_iou_diff=1e-4):
25
ref = np.array(ref, np.float32)
26
refClassIds, testClassIds = ref[:, 1], out[:, 1]
27
refScores, testScores = ref[:, 2], out[:, 2]
28
refBoxes, testBoxes = ref[:, 3:], out[:, 3:]
29
30
matchedRefBoxes = [False] * len(refBoxes)
31
errMsg = ''
32
for i in range(len(refBoxes)):
33
testScore = testScores[i]
34
if testScore < confThreshold:
35
continue
36
37
testClassId, testBox = testClassIds[i], testBoxes[i]
38
matched = False
39
for j in range(len(refBoxes)):
40
if (not matchedRefBoxes[j]) and testClassId == refClassIds[j] and \
41
abs(testScore - refScores[j]) < scores_diff:
42
interArea = inter_area(testBox, refBoxes[j])
43
iou = interArea / (area(testBox) + area(refBoxes[j]) - interArea)
44
if abs(iou - 1.0) < boxes_iou_diff:
45
matched = True
46
matchedRefBoxes[j] = True
47
if not matched:
48
errMsg += '\nUnmatched prediction: class %d score %f box %s' % (testClassId, testScore, box2str(testBox))
49
50
for i in range(len(refBoxes)):
51
if (not matchedRefBoxes[i]) and refScores[i] > confThreshold:
52
errMsg += '\nUnmatched reference: class %d score %f box %s' % (refClassIds[i], refScores[i], box2str(refBoxes[i]))
53
if errMsg:
54
test.fail(errMsg)
55
56
57
# Returns a simple one-layer network created from Caffe's format
58
def getSimpleNet():
59
prototxt = """
60
name: "simpleNet"
61
input: "data"
62
layer {
63
type: "Identity"
64
name: "testLayer"
65
top: "testLayer"
66
bottom: "data"
67
}
68
"""
69
return cv.dnn.readNetFromCaffe(bytearray(prototxt, 'utf8'))
70
71
72
def testBackendAndTarget(backend, target):
73
net = getSimpleNet()
74
net.setPreferableBackend(backend)
75
net.setPreferableTarget(target)
76
inp = np.random.standard_normal([1, 2, 3, 4]).astype(np.float32)
77
try:
78
net.setInput(inp)
79
net.forward()
80
except BaseException as e:
81
return False
82
return True
83
84
85
haveInfEngine = testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU)
86
dnnBackendsAndTargets = [
87
[cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU],
88
]
89
90
if haveInfEngine:
91
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_CPU])
92
if testBackendAndTarget(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD):
93
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_MYRIAD])
94
95
if cv.ocl.haveOpenCL() and cv.ocl.useOpenCL():
96
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL])
97
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_OPENCL_FP16])
98
if haveInfEngine and cv.ocl_Device.getDefault().isIntel():
99
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL])
100
dnnBackendsAndTargets.append([cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_TARGET_OPENCL_FP16])
101
102
103
def printParams(backend, target):
104
backendNames = {
105
cv.dnn.DNN_BACKEND_OPENCV: 'OCV',
106
cv.dnn.DNN_BACKEND_INFERENCE_ENGINE: 'DLIE'
107
}
108
targetNames = {
109
cv.dnn.DNN_TARGET_CPU: 'CPU',
110
cv.dnn.DNN_TARGET_OPENCL: 'OCL',
111
cv.dnn.DNN_TARGET_OPENCL_FP16: 'OCL_FP16',
112
cv.dnn.DNN_TARGET_MYRIAD: 'MYRIAD'
113
}
114
print('%s/%s' % (backendNames[backend], targetNames[target]))
115
116
117
class dnn_test(NewOpenCVTests):
118
119
def find_dnn_file(self, filename, required=True):
120
return self.find_file(filename, [os.environ.get('OPENCV_DNN_TEST_DATA_PATH', os.getcwd())], required=required)
121
122
def test_blobFromImage(self):
123
np.random.seed(324)
124
125
width = 6
126
height = 7
127
scale = 1.0/127.5
128
mean = (10, 20, 30)
129
130
# Test arguments names.
131
img = np.random.randint(0, 255, [4, 5, 3]).astype(np.uint8)
132
blob = cv.dnn.blobFromImage(img, scale, (width, height), mean, True, False)
133
blob_args = cv.dnn.blobFromImage(img, scalefactor=scale, size=(width, height),
134
mean=mean, swapRB=True, crop=False)
135
normAssert(self, blob, blob_args)
136
137
# Test values.
138
target = cv.resize(img, (width, height), interpolation=cv.INTER_LINEAR)
139
target = target.astype(np.float32)
140
target = target[:,:,[2, 1, 0]] # BGR2RGB
141
target[:,:,0] -= mean[0]
142
target[:,:,1] -= mean[1]
143
target[:,:,2] -= mean[2]
144
target *= scale
145
target = target.transpose(2, 0, 1).reshape(1, 3, height, width) # to NCHW
146
normAssert(self, blob, target)
147
148
149
def test_face_detection(self):
150
testdata_required = bool(os.environ.get('OPENCV_DNN_TEST_REQUIRE_TESTDATA', False))
151
proto = self.find_dnn_file('dnn/opencv_face_detector.prototxt2', required=testdata_required)
152
model = self.find_dnn_file('dnn/opencv_face_detector.caffemodel', required=testdata_required)
153
if proto is None or model is None:
154
raise unittest.SkipTest("Missing DNN test files (dnn/opencv_face_detector.{prototxt/caffemodel}). Verify OPENCV_DNN_TEST_DATA_PATH configuration parameter.")
155
156
img = self.get_sample('gpu/lbpcascade/er.png')
157
blob = cv.dnn.blobFromImage(img, mean=(104, 177, 123), swapRB=False, crop=False)
158
159
ref = [[0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631],
160
[0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168],
161
[0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290],
162
[0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477],
163
[0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494],
164
[0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801]]
165
166
print('\n')
167
for backend, target in dnnBackendsAndTargets:
168
printParams(backend, target)
169
170
net = cv.dnn.readNet(proto, model)
171
net.setPreferableBackend(backend)
172
net.setPreferableTarget(target)
173
net.setInput(blob)
174
out = net.forward().reshape(-1, 7)
175
176
scoresDiff = 4e-3 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-5
177
iouDiff = 2e-2 if target in [cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD] else 1e-4
178
179
normAssertDetections(self, ref, out, 0.5, scoresDiff, iouDiff)
180
181
if __name__ == '__main__':
182
NewOpenCVTests.bootstrap()
183
184