1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
5 // Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
9 Test for Tensorflow models loading
12 #include "test_precomp.hpp"
13 #include "npy_blob.hpp"
15 #include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
21 using namespace cv::dnn;
23 template<typename TString>
24 static std::string _tf(TString filename)
26 return (getOpenCVExtraDir() + "/dnn/") + filename;
29 TEST(Test_TensorFlow, read_inception)
33 const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
34 net = readNetFromTensorflow(model);
35 ASSERT_FALSE(net.empty());
37 net.setPreferableBackend(DNN_BACKEND_OPENCV);
39 Mat sample = imread(_tf("grace_hopper_227.png"));
40 ASSERT_TRUE(!sample.empty());
42 resize(sample, input, Size(224, 224));
43 input -= Scalar::all(117); // mean sub
45 Mat inputBlob = blobFromImage(input);
47 net.setInput(inputBlob, "input");
48 Mat out = net.forward("softmax2");
50 std::cout << out.dims << std::endl;
53 TEST(Test_TensorFlow, inception_accuracy)
57 const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
58 net = readNetFromTensorflow(model);
59 ASSERT_FALSE(net.empty());
61 net.setPreferableBackend(DNN_BACKEND_OPENCV);
63 Mat sample = imread(_tf("grace_hopper_227.png"));
64 ASSERT_TRUE(!sample.empty());
65 Mat inputBlob = blobFromImage(sample, 1.0, Size(224, 224), Scalar(), /*swapRB*/true);
67 net.setInput(inputBlob, "input");
68 Mat out = net.forward("softmax2");
70 Mat ref = blobFromNPY(_tf("tf_inception_prob.npy"));
75 static std::string path(const std::string& file)
77 return findDataFile("dnn/tensorflow/" + file);
80 class Test_TensorFlow_layers : public DNNTestLayer
83 void runTensorFlowNet(const std::string& prefix, bool hasText = false,
84 double l1 = 0.0, double lInf = 0.0, bool memoryLoad = false)
86 std::string netPath = path(prefix + "_net.pb");
87 std::string netConfig = (hasText ? path(prefix + "_net.pbtxt") : "");
88 std::string inpPath = path(prefix + "_in.npy");
89 std::string outPath = path(prefix + "_out.npy");
91 cv::Mat input = blobFromNPY(inpPath);
92 cv::Mat ref = blobFromNPY(outPath);
93 checkBackend(&input, &ref);
98 // Load files into a memory buffers
99 std::vector<char> dataModel;
100 readFileContent(netPath, dataModel);
102 std::vector<char> dataConfig;
105 readFileContent(netConfig, dataConfig);
108 net = readNetFromTensorflow(dataModel.data(), dataModel.size(),
109 dataConfig.data(), dataConfig.size());
112 net = readNetFromTensorflow(netPath, netConfig);
114 ASSERT_FALSE(net.empty());
116 net.setPreferableBackend(backend);
117 net.setPreferableTarget(target);
119 cv::Mat output = net.forward();
120 normAssert(ref, output, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
124 TEST_P(Test_TensorFlow_layers, conv)
126 runTensorFlowNet("single_conv");
127 runTensorFlowNet("atrous_conv2d_valid");
128 runTensorFlowNet("atrous_conv2d_same");
129 runTensorFlowNet("depthwise_conv2d");
130 runTensorFlowNet("keras_atrous_conv2d_same");
131 runTensorFlowNet("conv_pool_nchw");
134 TEST_P(Test_TensorFlow_layers, Convolution3D)
136 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
137 throw SkipTestException("Test is enabled starts from 2019R1");
139 if (target != DNN_TARGET_CPU)
140 throw SkipTestException("Only CPU is supported");
141 runTensorFlowNet("conv3d");
144 TEST_P(Test_TensorFlow_layers, padding)
146 runTensorFlowNet("padding_valid");
147 runTensorFlowNet("spatial_padding");
148 runTensorFlowNet("keras_pad_concat");
149 runTensorFlowNet("mirror_pad");
152 TEST_P(Test_TensorFlow_layers, padding_same)
154 // Reference output values are in range [0.0006, 2.798]
155 runTensorFlowNet("padding_same");
158 TEST_P(Test_TensorFlow_layers, eltwise)
160 runTensorFlowNet("eltwise_add_mul");
161 runTensorFlowNet("eltwise_sub");
164 TEST_P(Test_TensorFlow_layers, pad_and_concat)
166 runTensorFlowNet("pad_and_concat");
169 TEST_P(Test_TensorFlow_layers, concat_axis_1)
171 runTensorFlowNet("concat_axis_1");
174 TEST_P(Test_TensorFlow_layers, batch_norm)
176 runTensorFlowNet("batch_norm");
177 runTensorFlowNet("batch_norm", false, 0.0, 0.0, true);
178 runTensorFlowNet("fused_batch_norm");
179 runTensorFlowNet("fused_batch_norm", false, 0.0, 0.0, true);
180 runTensorFlowNet("batch_norm_text", true);
181 runTensorFlowNet("batch_norm_text", true, 0.0, 0.0, true);
182 runTensorFlowNet("unfused_batch_norm");
183 runTensorFlowNet("fused_batch_norm_no_gamma");
184 runTensorFlowNet("unfused_batch_norm_no_gamma");
185 runTensorFlowNet("mvn_batch_norm");
186 runTensorFlowNet("mvn_batch_norm_1x1");
187 runTensorFlowNet("switch_identity");
188 runTensorFlowNet("keras_batch_norm_training");
191 TEST_P(Test_TensorFlow_layers, batch_norm3D)
193 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
195 if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
196 if (target == DNN_TARGET_OPENCL) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL);
197 if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
198 throw SkipTestException("");
200 runTensorFlowNet("batch_norm3d");
203 TEST_P(Test_TensorFlow_layers, slim_batch_norm)
205 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
206 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
207 // Output values range: [-40.0597, 207.827]
208 double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.041 : default_l1;
209 double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.33 : default_lInf;
210 runTensorFlowNet("slim_batch_norm", false, l1, lInf);
213 TEST_P(Test_TensorFlow_layers, pooling)
215 runTensorFlowNet("max_pool_even");
216 runTensorFlowNet("max_pool_odd_valid");
217 runTensorFlowNet("max_pool_odd_same");
218 runTensorFlowNet("reduce_mean"); // an average pooling over all spatial dimensions.
221 TEST_P(Test_TensorFlow_layers, max_pool_grad)
223 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
224 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
225 runTensorFlowNet("max_pool_grad");
228 // TODO: fix tests and replace to pooling
229 TEST_P(Test_TensorFlow_layers, ave_pool_same)
231 // Reference output values are in range [-0.519531, 0.112976]
232 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
233 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
234 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
236 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
238 runTensorFlowNet("ave_pool_same");
241 TEST_P(Test_TensorFlow_layers, MaxPooling3D)
243 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
244 throw SkipTestException("Test is enabled starts from 2019R1");
246 if (target != DNN_TARGET_CPU)
247 throw SkipTestException("Only CPU is supported");
248 runTensorFlowNet("max_pool3d");
251 TEST_P(Test_TensorFlow_layers, AvePooling3D)
253 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
254 throw SkipTestException("Test is enabled starts from 2019R1");
256 if (target != DNN_TARGET_CPU)
257 throw SkipTestException("Only CPU is supported");
258 runTensorFlowNet("ave_pool3d");
261 TEST_P(Test_TensorFlow_layers, deconvolution)
263 runTensorFlowNet("deconvolution");
264 runTensorFlowNet("deconvolution_same");
265 runTensorFlowNet("deconvolution_stride_2_same");
266 runTensorFlowNet("deconvolution_adj_pad_valid");
267 runTensorFlowNet("deconvolution_adj_pad_same");
268 runTensorFlowNet("keras_deconv_valid");
269 runTensorFlowNet("keras_deconv_same");
270 runTensorFlowNet("keras_deconv_same_v2");
273 TEST_P(Test_TensorFlow_layers, matmul)
275 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
276 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
277 runTensorFlowNet("matmul");
278 runTensorFlowNet("nhwc_transpose_reshape_matmul");
279 // Reference output values are in range [-5.688, 4.484]
280 double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
281 runTensorFlowNet("nhwc_reshape_matmul", false, l1);
285 TEST_P(Test_TensorFlow_layers, reshape)
287 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
288 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
289 runTensorFlowNet("shift_reshape_no_reorder");
290 runTensorFlowNet("reshape_no_reorder");
291 runTensorFlowNet("reshape_reduce");
292 runTensorFlowNet("reshape_as_shape");
295 TEST_P(Test_TensorFlow_layers, flatten)
297 #if defined(INF_ENGINE_RELEASE)
298 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
299 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
301 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
304 runTensorFlowNet("flatten", true);
307 TEST_P(Test_TensorFlow_layers, unfused_flatten)
309 runTensorFlowNet("unfused_flatten");
310 runTensorFlowNet("unfused_flatten_unknown_batch");
313 TEST_P(Test_TensorFlow_layers, leaky_relu)
315 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
316 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
317 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_2018R5);
319 runTensorFlowNet("leaky_relu_order1");
320 runTensorFlowNet("leaky_relu_order2");
321 runTensorFlowNet("leaky_relu_order3");
324 TEST_P(Test_TensorFlow_layers, l2_normalize)
326 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
327 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
328 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
330 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
333 runTensorFlowNet("l2_normalize");
336 // TODO: fix it and add to l2_normalize
337 TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
339 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
340 if (backend == DNN_BACKEND_INFERENCE_ENGINE
341 && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
343 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
345 #if defined(INF_ENGINE_RELEASE)
346 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
347 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
350 runTensorFlowNet("l2_normalize_3d");
353 TEST_P(Test_TensorFlow_layers, Split)
355 runTensorFlowNet("split");
358 class Test_TensorFlow_nets : public DNNTestLayer {};
360 TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
362 #if defined(INF_ENGINE_RELEASE)
363 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
365 #if INF_ENGINE_VER_MAJOR_GE(2019010000)
366 if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
367 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
369 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
375 std::string imgPath = findDataFile("dnn/street.png");
376 std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt");
377 std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
380 resize(imread(imgPath), inp, Size(300, 300));
381 inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
383 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy"));
385 Net net = readNetFromTensorflow(netPath, netConfig);
386 net.setPreferableBackend(backend);
387 net.setPreferableTarget(target);
390 Mat out = net.forward();
392 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0043 : default_l1;
393 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.037 : default_lInf;
394 normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
395 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2019010000
396 expectNoFallbacksFromIE(net);
400 TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
402 applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
404 #if defined(INF_ENGINE_RELEASE)
405 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
406 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
408 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
412 Mat img = imread(findDataFile("dnn/street.png"));
413 std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt");
414 std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
416 Net net = readNetFromTensorflow(model, proto);
417 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
419 net.setPreferableBackend(backend);
420 net.setPreferableTarget(target);
423 // Output has shape 1x1xNx7 where N - number of detections.
424 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
425 Mat out = net.forward();
426 Mat ref = (Mat_<float>(5, 7) << 0, 1, 0.90176028, 0.19872092, 0.36311883, 0.26461923, 0.63498729,
427 0, 3, 0.93569964, 0.64865261, 0.45906419, 0.80675775, 0.65708131,
428 0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
429 0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
430 0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
432 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0097 : default_l1;
433 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : default_lInf;
434 normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
435 expectNoFallbacksFromIE(net);
438 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
441 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt");
442 std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
444 Net net = readNetFromTensorflow(model, proto);
445 Mat img = imread(findDataFile("dnn/dog416.png"));
446 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
448 net.setPreferableBackend(backend);
449 net.setPreferableTarget(target);
452 Mat out = net.forward();
454 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco_2017_11_17.detection_out.npy"));
455 float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 7e-3 : 1.5e-5;
456 float iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 1e-3;
457 float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.35 : 0.3;
459 #if defined(INF_ENGINE_RELEASE)
460 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
461 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
465 detectionConfThresh = 0.36;
467 normAssertDetections(ref, out, "", detectionConfThresh, scoreDiff, iouDiff);
468 expectNoFallbacksFromIE(net);
471 TEST_P(Test_TensorFlow_nets, Faster_RCNN)
475 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
477 CV_TEST_TAG_DEBUG_VERYLONG
479 static std::string names[] = {"faster_rcnn_inception_v2_coco_2018_01_28",
480 "faster_rcnn_resnet50_coco_2018_01_28"};
483 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
484 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
485 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
486 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
488 double scoresDiff = backend == DNN_BACKEND_INFERENCE_ENGINE ? 2.9e-5 : 1e-5;
489 for (int i = 0; i < 2; ++i)
491 std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt");
492 std::string model = findDataFile("dnn/" + names[i] + ".pb", false);
494 Net net = readNetFromTensorflow(model, proto);
495 net.setPreferableBackend(backend);
496 net.setPreferableTarget(target);
497 Mat img = imread(findDataFile("dnn/dog416.png"));
498 Mat blob = blobFromImage(img, 1.0f, Size(800, 600), Scalar(), true, false);
501 Mat out = net.forward();
503 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/" + names[i] + ".detection_out.npy"));
504 normAssertDetections(ref, out, names[i].c_str(), 0.3, scoresDiff);
508 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
510 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
511 if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
512 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
516 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt");
517 std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
519 Net net = readNetFromTensorflow(model, proto);
520 Mat img = imread(findDataFile("dnn/dog416.png"));
521 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy"));
522 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
524 net.setPreferableBackend(backend);
525 net.setPreferableTarget(target);
528 Mat out = net.forward();
530 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.048 : 1.1e-5;
531 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.058 : default_lInf;
532 normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
533 expectNoFallbacksFromIE(net);
536 TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
539 std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt");
540 std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false);
542 Net net = readNetFromTensorflow(model, proto);
543 Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
544 Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
546 net.setPreferableBackend(backend);
547 net.setPreferableTarget(target);
549 // Output has shape 1x1xNx7 where N - number of detections.
550 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
551 Mat out = net.forward();
553 // References are from test for Caffe model.
554 Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
555 0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
556 0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
557 0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
558 0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
559 0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
560 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 4e-3 : 3.4e-3;
561 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.024 : 1e-2;
562 normAssertDetections(ref, out, "", 0.9, scoreDiff, iouDiff);
563 expectNoFallbacksFromIE(net);
566 // inp = cv.imread('opencv_extra/testdata/cv/ximgproc/sources/08.png')
567 // inp = inp[:,:,[2, 1, 0]].astype(np.float32).reshape(1, 512, 512, 3)
568 // outs = sess.run([sess.graph.get_tensor_by_name('feature_fusion/Conv_7/Sigmoid:0'),
569 // sess.graph.get_tensor_by_name('feature_fusion/concat_3:0')],
570 // feed_dict={'input_images:0': inp})
571 // scores = np.ascontiguousarray(outs[0].transpose(0, 3, 1, 2))
572 // geometry = np.ascontiguousarray(outs[1].transpose(0, 3, 1, 2))
573 // np.save('east_text_detection.scores.npy', scores)
574 // np.save('east_text_detection.geometry.npy', geometry)
575 TEST_P(Test_TensorFlow_nets, EAST_text_detection)
578 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
579 CV_TEST_TAG_DEBUG_LONG
582 #if defined(INF_ENGINE_RELEASE)
583 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
584 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
589 std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
590 std::string imgPath = findDataFile("cv/ximgproc/sources/08.png");
591 std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy");
592 std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy");
594 Net net = readNet(netPath);
596 net.setPreferableBackend(backend);
597 net.setPreferableTarget(target);
599 Mat img = imread(imgPath);
600 Mat inp = blobFromImage(img, 1.0, Size(), Scalar(123.68, 116.78, 103.94), true, false);
603 std::vector<Mat> outs;
604 std::vector<String> outNames(2);
605 outNames[0] = "feature_fusion/Conv_7/Sigmoid";
606 outNames[1] = "feature_fusion/concat_3";
607 net.forward(outs, outNames);
609 Mat scores = outs[0];
610 Mat geometry = outs[1];
612 // Scores are in range [0, 1]. Geometry values are in range [-0.23, 290]
613 double l1_scores = default_l1, lInf_scores = default_lInf;
614 double l1_geometry = default_l1, lInf_geometry = default_lInf;
615 if (target == DNN_TARGET_OPENCL_FP16)
617 lInf_scores = backend == DNN_BACKEND_INFERENCE_ENGINE ? 0.16 : 0.11;
618 l1_geometry = 0.28; lInf_geometry = 5.94;
620 else if (target == DNN_TARGET_MYRIAD)
623 l1_geometry = 0.28; lInf_geometry = 5.94;
627 l1_geometry = 1e-4, lInf_geometry = 3e-3;
629 normAssert(scores, blobFromNPY(refScoresPath), "scores", l1_scores, lInf_scores);
630 normAssert(geometry, blobFromNPY(refGeometryPath), "geometry", l1_geometry, lInf_geometry);
631 expectNoFallbacksFromIE(net);
634 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
636 TEST_P(Test_TensorFlow_layers, fp16_weights)
640 runTensorFlowNet("fp16_single_conv", false, l1, lInf);
641 runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
642 runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
643 runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
644 runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
645 // Reference output values are in range [0.0889, 1.651]
646 runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
647 if (target == DNN_TARGET_MYRIAD) {
651 // Reference output values are in range [0, 10.75]
652 runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
653 // Reference output values are in range [0.418, 2.297]
654 runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
657 TEST_P(Test_TensorFlow_layers, fp16_padding_same)
659 // Reference output values are in range [-3.504, -0.002]
660 runTensorFlowNet("fp16_padding_same", false, 7e-4, 4e-3);
663 TEST_P(Test_TensorFlow_layers, defun)
665 runTensorFlowNet("defun_dropout");
668 TEST_P(Test_TensorFlow_layers, quantized)
670 runTensorFlowNet("uint8_single_conv");
673 TEST_P(Test_TensorFlow_layers, lstm)
675 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
676 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
677 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
678 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
679 runTensorFlowNet("lstm", true);
680 runTensorFlowNet("lstm", true, 0.0, 0.0, true);
683 TEST_P(Test_TensorFlow_layers, split)
685 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
686 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
687 runTensorFlowNet("split_equals");
690 TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor)
692 runTensorFlowNet("resize_nearest_neighbor");
693 runTensorFlowNet("keras_upsampling2d");
696 TEST_P(Test_TensorFlow_layers, slice)
698 if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
699 (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
700 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
701 runTensorFlowNet("slice_4d");
702 runTensorFlowNet("strided_slice");
705 TEST_P(Test_TensorFlow_layers, softmax)
707 runTensorFlowNet("keras_softmax");
708 runTensorFlowNet("slim_softmax");
711 TEST_P(Test_TensorFlow_layers, slim_softmax_v2)
713 #if defined(INF_ENGINE_RELEASE)
714 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD &&
715 getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
717 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
719 runTensorFlowNet("slim_softmax_v2");
722 TEST_P(Test_TensorFlow_layers, relu6)
724 runTensorFlowNet("keras_relu6");
725 runTensorFlowNet("keras_relu6", /*hasText*/ true);
728 TEST_P(Test_TensorFlow_layers, subpixel)
730 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
731 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
732 runTensorFlowNet("subpixel");
735 TEST_P(Test_TensorFlow_layers, keras_mobilenet_head)
737 runTensorFlowNet("keras_mobilenet_head");
740 TEST_P(Test_TensorFlow_layers, resize_bilinear)
742 runTensorFlowNet("resize_bilinear");
743 runTensorFlowNet("resize_bilinear_factor");
746 TEST_P(Test_TensorFlow_layers, squeeze)
748 #if defined(INF_ENGINE_RELEASE)
749 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
750 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
752 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
754 int inpShapes[][4] = {{1, 3, 4, 2}, {1, 3, 1, 2}, {1, 3, 4, 1}, {1, 3, 4, 1}}; // TensorFlow's shape (NHWC)
755 int outShapes[][3] = {{3, 4, 2}, {1, 3, 2}, {1, 3, 4}, {1, 3, 4}};
756 int squeeze_dims[] = {0, 2, 3, -1};
757 for (int i = 0; i < 4; ++i)
759 SCOPED_TRACE(format("i=%d", i));
761 "node { name: \"input\" op: \"Placeholder\""
762 "attr { key: \"data_format\" value { s: \"NHWC\" } } }"
763 "node { name: \"squeeze\" op: \"Squeeze\" input: \"input\""
764 "attr { key: \"squeeze_dims\" value { list { i:" + format("%d", squeeze_dims[i]) + "}}}}";
765 Net net = readNetFromTensorflow(0, 0, pbtxt.c_str(), pbtxt.size());
766 net.setPreferableBackend(backend);
767 net.setPreferableTarget(target);
768 Mat tfInp(4, &inpShapes[i][0], CV_32F);
772 CV_Assert(inpShapes[i][0] == 1);
773 std::swap(inpShapes[i][2], inpShapes[i][3]);
774 std::swap(inpShapes[i][1], inpShapes[i][2]);
775 Mat cvInp = tfInp.reshape(1, tfInp.total() / inpShapes[i][1]).t();
776 cvInp = cvInp.reshape(1, 4, &inpShapes[i][0]);
779 Mat out = net.forward();
780 normAssert(tfInp.reshape(1, 3, &outShapes[i][0]), out, "", default_l1, default_lInf);
784 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_layers, dnnBackendsAndTargets());
786 TEST(Test_TensorFlow, two_inputs)
788 Net net = readNet(path("two_inputs_net.pbtxt"));
789 net.setPreferableBackend(DNN_BACKEND_OPENCV);
791 Mat firstInput(2, 3, CV_32FC1), secondInput(2, 3, CV_32FC1);
792 randu(firstInput, -1, 1);
793 randu(secondInput, -1, 1);
795 net.setInput(firstInput, "first_input");
796 net.setInput(secondInput, "second_input");
797 Mat out = net.forward();
799 normAssert(out, firstInput + secondInput);
802 TEST(Test_TensorFlow, Mask_RCNN)
804 applyTestTag(CV_TEST_TAG_MEMORY_1GB, CV_TEST_TAG_DEBUG_VERYLONG);
805 Mat img = imread(findDataFile("dnn/street.png"));
806 std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt");
807 std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false);
809 Net net = readNetFromTensorflow(model, proto);
810 Mat refDetections = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_out.npy"));
811 Mat refMasks = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_masks.npy"));
812 Mat blob = blobFromImage(img, 1.0f, Size(800, 800), Scalar(), true, false);
814 net.setPreferableBackend(DNN_BACKEND_OPENCV);
818 // Mask-RCNN predicts bounding boxes and segmentation masks.
819 std::vector<String> outNames(2);
820 outNames[0] = "detection_out_final";
821 outNames[1] = "detection_masks";
823 std::vector<Mat> outs;
824 net.forward(outs, outNames);
826 Mat outDetections = outs[0];
827 Mat outMasks = outs[1];
828 normAssertDetections(refDetections, outDetections, "", /*threshold for zero confidence*/1e-5);
830 // Output size of masks is NxCxHxW where
831 // N - number of detected boxes
832 // C - number of classes (excluding background)
833 // HxW - segmentation shape
834 const int numDetections = outDetections.size[2];
836 int masksSize[] = {1, numDetections, outMasks.size[2], outMasks.size[3]};
837 Mat masks(4, &masksSize[0], CV_32F);
839 std::vector<cv::Range> srcRanges(4, cv::Range::all());
840 std::vector<cv::Range> dstRanges(4, cv::Range::all());
842 outDetections = outDetections.reshape(1, outDetections.total() / 7);
843 for (int i = 0; i < numDetections; ++i)
845 // Get a class id for this bounding box and copy mask only for that class.
846 int classId = static_cast<int>(outDetections.at<float>(i, 1));
847 srcRanges[0] = dstRanges[1] = cv::Range(i, i + 1);
848 srcRanges[1] = cv::Range(classId, classId + 1);
849 outMasks(srcRanges).copyTo(masks(dstRanges));
851 cv::Range topRefMasks[] = {Range::all(), Range(0, numDetections), Range::all(), Range::all()};
852 normAssert(masks, refMasks(&topRefMasks[0]));