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 (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
140 throw SkipTestException("Only DLIE backend on 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 // TODO: fix tests and replace to pooling
222 TEST_P(Test_TensorFlow_layers, ave_pool_same)
224 // Reference output values are in range [-0.519531, 0.112976]
225 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
226 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
227 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
229 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
231 runTensorFlowNet("ave_pool_same");
234 TEST_P(Test_TensorFlow_layers, MaxPooling3D)
236 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
237 throw SkipTestException("Test is enabled starts from 2019R1");
239 if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
240 throw SkipTestException("Only DLIE backend on CPU is supported");
241 runTensorFlowNet("max_pool3d");
244 TEST_P(Test_TensorFlow_layers, AvePooling3D)
246 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
247 throw SkipTestException("Test is enabled starts from 2019R1");
249 if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
250 throw SkipTestException("Only DLIE backend on CPU is supported");
251 runTensorFlowNet("ave_pool3d");
254 TEST_P(Test_TensorFlow_layers, deconvolution)
256 runTensorFlowNet("deconvolution");
257 runTensorFlowNet("deconvolution_same");
258 runTensorFlowNet("deconvolution_stride_2_same");
259 runTensorFlowNet("deconvolution_adj_pad_valid");
260 runTensorFlowNet("deconvolution_adj_pad_same");
261 runTensorFlowNet("keras_deconv_valid");
262 runTensorFlowNet("keras_deconv_same");
263 runTensorFlowNet("keras_deconv_same_v2");
266 TEST_P(Test_TensorFlow_layers, matmul)
268 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
269 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
270 runTensorFlowNet("matmul");
271 runTensorFlowNet("nhwc_transpose_reshape_matmul");
272 // Reference output values are in range [-5.688, 4.484]
273 double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
274 runTensorFlowNet("nhwc_reshape_matmul", false, l1);
278 TEST_P(Test_TensorFlow_layers, reshape)
280 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
281 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
282 runTensorFlowNet("shift_reshape_no_reorder");
283 runTensorFlowNet("reshape_no_reorder");
284 runTensorFlowNet("reshape_reduce");
285 runTensorFlowNet("reshape_as_shape");
288 TEST_P(Test_TensorFlow_layers, flatten)
290 #if defined(INF_ENGINE_RELEASE)
291 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
292 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
294 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
297 runTensorFlowNet("flatten", true);
300 TEST_P(Test_TensorFlow_layers, unfused_flatten)
302 runTensorFlowNet("unfused_flatten");
303 runTensorFlowNet("unfused_flatten_unknown_batch");
306 TEST_P(Test_TensorFlow_layers, leaky_relu)
308 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
309 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
310 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_2018R5);
312 runTensorFlowNet("leaky_relu_order1");
313 runTensorFlowNet("leaky_relu_order2");
314 runTensorFlowNet("leaky_relu_order3");
317 TEST_P(Test_TensorFlow_layers, l2_normalize)
319 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
320 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
321 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
323 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
326 runTensorFlowNet("l2_normalize");
329 // TODO: fix it and add to l2_normalize
330 TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
332 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
333 if (backend == DNN_BACKEND_INFERENCE_ENGINE
334 && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
336 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
338 #if defined(INF_ENGINE_RELEASE)
339 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
340 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
343 runTensorFlowNet("l2_normalize_3d");
346 class Test_TensorFlow_nets : public DNNTestLayer {};
348 TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
350 #if defined(INF_ENGINE_RELEASE)
351 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
353 #if INF_ENGINE_VER_MAJOR_GE(2019010000)
354 if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
355 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
357 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
363 std::string imgPath = findDataFile("dnn/street.png");
364 std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt");
365 std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
368 resize(imread(imgPath), inp, Size(300, 300));
369 inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
371 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy"));
373 Net net = readNetFromTensorflow(netPath, netConfig);
374 net.setPreferableBackend(backend);
375 net.setPreferableTarget(target);
378 Mat out = net.forward();
380 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0043 : default_l1;
381 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.037 : default_lInf;
382 normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
383 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2019010000
384 expectNoFallbacksFromIE(net);
388 TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
390 applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
392 #if defined(INF_ENGINE_RELEASE)
393 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
394 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
396 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
400 Mat img = imread(findDataFile("dnn/street.png"));
401 std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt");
402 std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
404 Net net = readNetFromTensorflow(model, proto);
405 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
407 net.setPreferableBackend(backend);
408 net.setPreferableTarget(target);
411 // Output has shape 1x1xNx7 where N - number of detections.
412 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
413 Mat out = net.forward();
414 Mat ref = (Mat_<float>(5, 7) << 0, 1, 0.90176028, 0.19872092, 0.36311883, 0.26461923, 0.63498729,
415 0, 3, 0.93569964, 0.64865261, 0.45906419, 0.80675775, 0.65708131,
416 0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
417 0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
418 0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
420 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0097 : default_l1;
421 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : default_lInf;
422 normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
423 expectNoFallbacksFromIE(net);
426 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
429 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt");
430 std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
432 Net net = readNetFromTensorflow(model, proto);
433 Mat img = imread(findDataFile("dnn/dog416.png"));
434 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
436 net.setPreferableBackend(backend);
437 net.setPreferableTarget(target);
440 Mat out = net.forward();
442 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco_2017_11_17.detection_out.npy"));
443 float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 7e-3 : 1.5e-5;
444 float iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 1e-3;
445 float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.35 : 0.3;
447 #if defined(INF_ENGINE_RELEASE)
448 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
449 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
453 detectionConfThresh = 0.36;
455 normAssertDetections(ref, out, "", detectionConfThresh, scoreDiff, iouDiff);
456 expectNoFallbacksFromIE(net);
459 TEST_P(Test_TensorFlow_nets, Faster_RCNN)
463 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
465 CV_TEST_TAG_DEBUG_VERYLONG
467 static std::string names[] = {"faster_rcnn_inception_v2_coco_2018_01_28",
468 "faster_rcnn_resnet50_coco_2018_01_28"};
471 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
472 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
473 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
474 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
476 double scoresDiff = backend == DNN_BACKEND_INFERENCE_ENGINE ? 2.9e-5 : 1e-5;
477 for (int i = 0; i < 2; ++i)
479 std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt");
480 std::string model = findDataFile("dnn/" + names[i] + ".pb", false);
482 Net net = readNetFromTensorflow(model, proto);
483 net.setPreferableBackend(backend);
484 net.setPreferableTarget(target);
485 Mat img = imread(findDataFile("dnn/dog416.png"));
486 Mat blob = blobFromImage(img, 1.0f, Size(800, 600), Scalar(), true, false);
489 Mat out = net.forward();
491 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/" + names[i] + ".detection_out.npy"));
492 normAssertDetections(ref, out, names[i].c_str(), 0.3, scoresDiff);
496 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
498 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
499 if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
500 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
504 std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt");
505 std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
507 Net net = readNetFromTensorflow(model, proto);
508 Mat img = imread(findDataFile("dnn/dog416.png"));
509 Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy"));
510 Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
512 net.setPreferableBackend(backend);
513 net.setPreferableTarget(target);
516 Mat out = net.forward();
518 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.048 : 1.1e-5;
519 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.058 : default_lInf;
520 normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
521 expectNoFallbacksFromIE(net);
524 TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
527 std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt");
528 std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false);
530 Net net = readNetFromTensorflow(model, proto);
531 Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
532 Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
534 net.setPreferableBackend(backend);
535 net.setPreferableTarget(target);
537 // Output has shape 1x1xNx7 where N - number of detections.
538 // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
539 Mat out = net.forward();
541 // References are from test for Caffe model.
542 Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
543 0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
544 0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
545 0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
546 0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
547 0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
548 double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 4e-3 : 3.4e-3;
549 double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.024 : 1e-2;
550 normAssertDetections(ref, out, "", 0.9, scoreDiff, iouDiff);
551 expectNoFallbacksFromIE(net);
554 // inp = cv.imread('opencv_extra/testdata/cv/ximgproc/sources/08.png')
555 // inp = inp[:,:,[2, 1, 0]].astype(np.float32).reshape(1, 512, 512, 3)
556 // outs = sess.run([sess.graph.get_tensor_by_name('feature_fusion/Conv_7/Sigmoid:0'),
557 // sess.graph.get_tensor_by_name('feature_fusion/concat_3:0')],
558 // feed_dict={'input_images:0': inp})
559 // scores = np.ascontiguousarray(outs[0].transpose(0, 3, 1, 2))
560 // geometry = np.ascontiguousarray(outs[1].transpose(0, 3, 1, 2))
561 // np.save('east_text_detection.scores.npy', scores)
562 // np.save('east_text_detection.geometry.npy', geometry)
563 TEST_P(Test_TensorFlow_nets, EAST_text_detection)
566 (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
567 CV_TEST_TAG_DEBUG_LONG
570 #if defined(INF_ENGINE_RELEASE)
571 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
572 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
577 std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
578 std::string imgPath = findDataFile("cv/ximgproc/sources/08.png");
579 std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy");
580 std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy");
582 Net net = readNet(netPath);
584 net.setPreferableBackend(backend);
585 net.setPreferableTarget(target);
587 Mat img = imread(imgPath);
588 Mat inp = blobFromImage(img, 1.0, Size(), Scalar(123.68, 116.78, 103.94), true, false);
591 std::vector<Mat> outs;
592 std::vector<String> outNames(2);
593 outNames[0] = "feature_fusion/Conv_7/Sigmoid";
594 outNames[1] = "feature_fusion/concat_3";
595 net.forward(outs, outNames);
597 Mat scores = outs[0];
598 Mat geometry = outs[1];
600 // Scores are in range [0, 1]. Geometry values are in range [-0.23, 290]
601 double l1_scores = default_l1, lInf_scores = default_lInf;
602 double l1_geometry = default_l1, lInf_geometry = default_lInf;
603 if (target == DNN_TARGET_OPENCL_FP16)
605 lInf_scores = backend == DNN_BACKEND_INFERENCE_ENGINE ? 0.16 : 0.11;
606 l1_geometry = 0.28; lInf_geometry = 5.94;
608 else if (target == DNN_TARGET_MYRIAD)
611 l1_geometry = 0.28; lInf_geometry = 5.94;
615 l1_geometry = 1e-4, lInf_geometry = 3e-3;
617 normAssert(scores, blobFromNPY(refScoresPath), "scores", l1_scores, lInf_scores);
618 normAssert(geometry, blobFromNPY(refGeometryPath), "geometry", l1_geometry, lInf_geometry);
619 expectNoFallbacksFromIE(net);
622 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
624 TEST_P(Test_TensorFlow_layers, fp16_weights)
628 runTensorFlowNet("fp16_single_conv", false, l1, lInf);
629 runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
630 runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
631 runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
632 runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
633 // Reference output values are in range [0.0889, 1.651]
634 runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
635 if (target == DNN_TARGET_MYRIAD) {
639 // Reference output values are in range [0, 10.75]
640 runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
641 // Reference output values are in range [0.418, 2.297]
642 runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
645 TEST_P(Test_TensorFlow_layers, fp16_padding_same)
647 // Reference output values are in range [-3.504, -0.002]
648 runTensorFlowNet("fp16_padding_same", false, 7e-4, 4e-3);
651 TEST_P(Test_TensorFlow_layers, defun)
653 runTensorFlowNet("defun_dropout");
656 TEST_P(Test_TensorFlow_layers, quantized)
658 runTensorFlowNet("uint8_single_conv");
661 TEST_P(Test_TensorFlow_layers, lstm)
663 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
664 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
665 if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
666 applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
667 runTensorFlowNet("lstm", true);
668 runTensorFlowNet("lstm", true, 0.0, 0.0, true);
671 TEST_P(Test_TensorFlow_layers, split)
673 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
674 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
675 runTensorFlowNet("split_equals");
678 TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor)
680 runTensorFlowNet("resize_nearest_neighbor");
681 runTensorFlowNet("keras_upsampling2d");
684 TEST_P(Test_TensorFlow_layers, slice)
686 if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
687 (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
688 applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
689 runTensorFlowNet("slice_4d");
690 runTensorFlowNet("strided_slice");
693 TEST_P(Test_TensorFlow_layers, softmax)
695 runTensorFlowNet("keras_softmax");
696 runTensorFlowNet("slim_softmax");
699 TEST_P(Test_TensorFlow_layers, slim_softmax_v2)
701 #if defined(INF_ENGINE_RELEASE)
702 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD &&
703 getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
705 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
707 runTensorFlowNet("slim_softmax_v2");
710 TEST_P(Test_TensorFlow_layers, relu6)
712 runTensorFlowNet("keras_relu6");
713 runTensorFlowNet("keras_relu6", /*hasText*/ true);
716 TEST_P(Test_TensorFlow_layers, subpixel)
718 if (backend == DNN_BACKEND_INFERENCE_ENGINE)
719 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
720 runTensorFlowNet("subpixel");
723 TEST_P(Test_TensorFlow_layers, keras_mobilenet_head)
725 runTensorFlowNet("keras_mobilenet_head");
728 TEST_P(Test_TensorFlow_layers, resize_bilinear)
730 runTensorFlowNet("resize_bilinear");
731 runTensorFlowNet("resize_bilinear_factor");
734 TEST_P(Test_TensorFlow_layers, squeeze)
736 #if defined(INF_ENGINE_RELEASE)
737 if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
738 && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
740 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
742 int inpShapes[][4] = {{1, 3, 4, 2}, {1, 3, 1, 2}, {1, 3, 4, 1}, {1, 3, 4, 1}}; // TensorFlow's shape (NHWC)
743 int outShapes[][3] = {{3, 4, 2}, {1, 3, 2}, {1, 3, 4}, {1, 3, 4}};
744 int squeeze_dims[] = {0, 2, 3, -1};
745 for (int i = 0; i < 4; ++i)
747 SCOPED_TRACE(format("i=%d", i));
749 "node { name: \"input\" op: \"Placeholder\""
750 "attr { key: \"data_format\" value { s: \"NHWC\" } } }"
751 "node { name: \"squeeze\" op: \"Squeeze\" input: \"input\""
752 "attr { key: \"squeeze_dims\" value { list { i:" + format("%d", squeeze_dims[i]) + "}}}}";
753 Net net = readNetFromTensorflow(0, 0, pbtxt.c_str(), pbtxt.size());
754 net.setPreferableBackend(backend);
755 net.setPreferableTarget(target);
756 Mat tfInp(4, &inpShapes[i][0], CV_32F);
760 CV_Assert(inpShapes[i][0] == 1);
761 std::swap(inpShapes[i][2], inpShapes[i][3]);
762 std::swap(inpShapes[i][1], inpShapes[i][2]);
763 Mat cvInp = tfInp.reshape(1, tfInp.total() / inpShapes[i][1]).t();
764 cvInp = cvInp.reshape(1, 4, &inpShapes[i][0]);
767 Mat out = net.forward();
768 normAssert(tfInp.reshape(1, 3, &outShapes[i][0]), out, "", default_l1, default_lInf);
772 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_layers, dnnBackendsAndTargets());
774 TEST(Test_TensorFlow, two_inputs)
776 Net net = readNet(path("two_inputs_net.pbtxt"));
777 net.setPreferableBackend(DNN_BACKEND_OPENCV);
779 Mat firstInput(2, 3, CV_32FC1), secondInput(2, 3, CV_32FC1);
780 randu(firstInput, -1, 1);
781 randu(secondInput, -1, 1);
783 net.setInput(firstInput, "first_input");
784 net.setInput(secondInput, "second_input");
785 Mat out = net.forward();
787 normAssert(out, firstInput + secondInput);
790 TEST(Test_TensorFlow, Mask_RCNN)
792 applyTestTag(CV_TEST_TAG_MEMORY_1GB, CV_TEST_TAG_DEBUG_VERYLONG);
793 Mat img = imread(findDataFile("dnn/street.png"));
794 std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt");
795 std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false);
797 Net net = readNetFromTensorflow(model, proto);
798 Mat refDetections = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_out.npy"));
799 Mat refMasks = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_masks.npy"));
800 Mat blob = blobFromImage(img, 1.0f, Size(800, 800), Scalar(), true, false);
802 net.setPreferableBackend(DNN_BACKEND_OPENCV);
806 // Mask-RCNN predicts bounding boxes and segmentation masks.
807 std::vector<String> outNames(2);
808 outNames[0] = "detection_out_final";
809 outNames[1] = "detection_masks";
811 std::vector<Mat> outs;
812 net.forward(outs, outNames);
814 Mat outDetections = outs[0];
815 Mat outMasks = outs[1];
816 normAssertDetections(refDetections, outDetections, "", /*threshold for zero confidence*/1e-5);
818 // Output size of masks is NxCxHxW where
819 // N - number of detected boxes
820 // C - number of classes (excluding background)
821 // HxW - segmentation shape
822 const int numDetections = outDetections.size[2];
824 int masksSize[] = {1, numDetections, outMasks.size[2], outMasks.size[3]};
825 Mat masks(4, &masksSize[0], CV_32F);
827 std::vector<cv::Range> srcRanges(4, cv::Range::all());
828 std::vector<cv::Range> dstRanges(4, cv::Range::all());
830 outDetections = outDetections.reshape(1, outDetections.total() / 7);
831 for (int i = 0; i < numDetections; ++i)
833 // Get a class id for this bounding box and copy mask only for that class.
834 int classId = static_cast<int>(outDetections.at<float>(i, 1));
835 srcRanges[0] = dstRanges[1] = cv::Range(i, i + 1);
836 srcRanges[1] = cv::Range(classId, classId + 1);
837 outMasks(srcRanges).copyTo(masks(dstRanges));
839 cv::Range topRefMasks[] = {Range::all(), Range(0, numDetections), Range::all(), Range::all()};
840 normAssert(masks, refMasks(&topRefMasks[0]));