Merge pull request #16010 from YashasSamaga:cuda4dnn-fp16-tests
[platform/upstream/opencv.git] / modules / dnn / test / test_tf_importer.cpp
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.
4
5 // Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
7
8 /*
9 Test for Tensorflow models loading
10 */
11
12 #include "test_precomp.hpp"
13 #include "npy_blob.hpp"
14
15 #include <opencv2/dnn/layer.details.hpp>  // CV_DNN_REGISTER_LAYER_CLASS
16
17 namespace opencv_test
18 {
19
20 using namespace cv;
21 using namespace cv::dnn;
22
23 template<typename TString>
24 static std::string _tf(TString filename)
25 {
26     return (getOpenCVExtraDir() + "/dnn/") + filename;
27 }
28
29 TEST(Test_TensorFlow, read_inception)
30 {
31     Net net;
32     {
33         const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
34         net = readNetFromTensorflow(model);
35         ASSERT_FALSE(net.empty());
36     }
37     net.setPreferableBackend(DNN_BACKEND_OPENCV);
38
39     Mat sample = imread(_tf("grace_hopper_227.png"));
40     ASSERT_TRUE(!sample.empty());
41     Mat input;
42     resize(sample, input, Size(224, 224));
43     input -= Scalar::all(117); // mean sub
44
45     Mat inputBlob = blobFromImage(input);
46
47     net.setInput(inputBlob, "input");
48     Mat out = net.forward("softmax2");
49
50     std::cout << out.dims << std::endl;
51 }
52
53 TEST(Test_TensorFlow, inception_accuracy)
54 {
55     Net net;
56     {
57         const string model = findDataFile("dnn/tensorflow_inception_graph.pb", false);
58         net = readNetFromTensorflow(model);
59         ASSERT_FALSE(net.empty());
60     }
61     net.setPreferableBackend(DNN_BACKEND_OPENCV);
62
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);
66
67     net.setInput(inputBlob, "input");
68     Mat out = net.forward("softmax2");
69
70     Mat ref = blobFromNPY(_tf("tf_inception_prob.npy"));
71
72     normAssert(ref, out);
73 }
74
75 static std::string path(const std::string& file)
76 {
77     return findDataFile("dnn/tensorflow/" + file);
78 }
79
80 class Test_TensorFlow_layers : public DNNTestLayer
81 {
82 public:
83     void runTensorFlowNet(const std::string& prefix, bool hasText = false,
84                           double l1 = 0.0, double lInf = 0.0, bool memoryLoad = false)
85     {
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");
90
91         cv::Mat input = blobFromNPY(inpPath);
92         cv::Mat ref = blobFromNPY(outPath);
93         checkBackend(&input, &ref);
94
95         Net net;
96         if (memoryLoad)
97         {
98             // Load files into a memory buffers
99             std::vector<char> dataModel;
100             readFileContent(netPath, dataModel);
101
102             std::vector<char> dataConfig;
103             if (hasText)
104             {
105                 readFileContent(netConfig, dataConfig);
106             }
107
108             net = readNetFromTensorflow(dataModel.data(), dataModel.size(),
109                                         dataConfig.data(), dataConfig.size());
110         }
111         else
112             net = readNetFromTensorflow(netPath, netConfig);
113
114         ASSERT_FALSE(net.empty());
115
116         net.setPreferableBackend(backend);
117         net.setPreferableTarget(target);
118         net.setInput(input);
119         cv::Mat output = net.forward();
120         normAssert(ref, output, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
121     }
122 };
123
124 TEST_P(Test_TensorFlow_layers, conv)
125 {
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");
132 }
133
134 TEST_P(Test_TensorFlow_layers, Convolution3D)
135 {
136 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
137     applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
138 #endif
139     if (backend == DNN_BACKEND_CUDA)
140     {
141         // ok
142     }
143     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
144         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);  // Only CPU on DLIE backend is supported
145     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
146         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);  // Only CPU on DLIE backend is supported
147     else if (target != DNN_TARGET_CPU)
148         throw SkipTestException("Only CPU is supported");
149
150     runTensorFlowNet("conv3d");
151 }
152
153 TEST_P(Test_TensorFlow_layers, padding)
154 {
155     runTensorFlowNet("padding_valid");
156     runTensorFlowNet("spatial_padding");
157     runTensorFlowNet("mirror_pad");
158 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019020000)
159     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
160     {
161         if (target == DNN_TARGET_MYRIAD)
162             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
163         if (target == DNN_TARGET_OPENCL_FP16)
164             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
165     }
166 #endif
167     runTensorFlowNet("keras_pad_concat");
168 }
169
170 TEST_P(Test_TensorFlow_layers, padding_same)
171 {
172     // Reference output values are in range [0.0006, 2.798]
173     runTensorFlowNet("padding_same");
174 }
175
176 TEST_P(Test_TensorFlow_layers, eltwise)
177 {
178     runTensorFlowNet("eltwise_add_mul");
179     runTensorFlowNet("eltwise_sub");
180 }
181
182 TEST_P(Test_TensorFlow_layers, pad_and_concat)
183 {
184     runTensorFlowNet("pad_and_concat");
185 }
186
187 TEST_P(Test_TensorFlow_layers, concat_axis_1)
188 {
189     runTensorFlowNet("concat_axis_1");
190 }
191
192 TEST_P(Test_TensorFlow_layers, batch_norm)
193 {
194     runTensorFlowNet("batch_norm");
195     runTensorFlowNet("batch_norm", false, 0.0, 0.0, true);
196     runTensorFlowNet("fused_batch_norm");
197     runTensorFlowNet("fused_batch_norm", false, 0.0, 0.0, true);
198     runTensorFlowNet("batch_norm_text", true);
199     runTensorFlowNet("batch_norm_text", true, 0.0, 0.0, true);
200     runTensorFlowNet("unfused_batch_norm");
201     runTensorFlowNet("fused_batch_norm_no_gamma");
202     runTensorFlowNet("unfused_batch_norm_no_gamma");
203     runTensorFlowNet("mvn_batch_norm");
204     runTensorFlowNet("mvn_batch_norm_1x1");
205     runTensorFlowNet("switch_identity");
206     runTensorFlowNet("keras_batch_norm_training");
207 }
208
209 TEST_P(Test_TensorFlow_layers, batch_norm3D)
210 {
211     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
212     {
213         if (target == DNN_TARGET_OPENCL_FP16) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
214         if (target == DNN_TARGET_OPENCL)      applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
215         if (target == DNN_TARGET_MYRIAD)      applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
216         throw SkipTestException("");
217     }
218     runTensorFlowNet("batch_norm3d");
219 }
220
221 TEST_P(Test_TensorFlow_layers, slim_batch_norm)
222 {
223     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
224         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
225     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
226         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
227     // Output values range: [-40.0597, 207.827]
228     double l1 =  default_l1, lInf = default_lInf;
229     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
230     {
231         l1 = 0.041;
232         lInf = 0.33;
233     }
234     else if (target == DNN_TARGET_CUDA_FP16)
235     {
236         l1 = 0.005;
237         lInf = 0.33;
238     }
239     runTensorFlowNet("slim_batch_norm", false, l1, lInf);
240 }
241
242 TEST_P(Test_TensorFlow_layers, pooling)
243 {
244     runTensorFlowNet("max_pool_even");
245     runTensorFlowNet("max_pool_odd_valid");
246     runTensorFlowNet("max_pool_odd_same");
247     runTensorFlowNet("reduce_mean");  // an average pooling over all spatial dimensions.
248 }
249
250 TEST_P(Test_TensorFlow_layers, max_pool_grad)
251 {
252     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
253         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
254     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
255         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
256     runTensorFlowNet("max_pool_grad");
257 }
258
259 // TODO: fix tests and replace to pooling
260 TEST_P(Test_TensorFlow_layers, ave_pool_same)
261 {
262     // Reference output values are in range [-0.519531, 0.112976]
263 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
264     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
265             && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
266     )
267         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
268 #endif
269     runTensorFlowNet("ave_pool_same");
270 }
271
272 TEST_P(Test_TensorFlow_layers, MaxPooling3D)
273 {
274 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
275     applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
276 #endif
277     if (backend == DNN_BACKEND_CUDA)
278     {
279         // ok
280     }
281     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
282         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);  // Only CPU on DLIE backend is supported
283     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
284         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);  // Only CPU on DLIE backend is supported
285     else if (target != DNN_TARGET_CPU)
286         throw SkipTestException("Only CPU is supported");
287
288     runTensorFlowNet("max_pool3d");
289 }
290
291 TEST_P(Test_TensorFlow_layers, AvePooling3D)
292 {
293 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
294     applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_VERSION);
295 #endif
296     if (backend == DNN_BACKEND_CUDA)
297     {
298         // ok
299     }
300     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU)
301         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);  // Only CPU on DLIE backend is supported
302     else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target != DNN_TARGET_CPU)
303         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);  // Only CPU on DLIE backend is supported
304     else if (target != DNN_TARGET_CPU)
305         throw SkipTestException("Only CPU is supported");
306
307     runTensorFlowNet("ave_pool3d");
308 }
309
310 TEST_P(Test_TensorFlow_layers, deconvolution)
311 {
312     if (backend == DNN_BACKEND_CUDA)
313         applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA);
314     runTensorFlowNet("deconvolution");
315     runTensorFlowNet("deconvolution_same");
316     runTensorFlowNet("deconvolution_stride_2_same");
317     runTensorFlowNet("deconvolution_adj_pad_valid");
318     runTensorFlowNet("deconvolution_adj_pad_same");
319     runTensorFlowNet("keras_deconv_valid");
320     runTensorFlowNet("keras_deconv_same");
321     runTensorFlowNet("keras_deconv_same_v2");
322 }
323
324 TEST_P(Test_TensorFlow_layers, matmul)
325 {
326     if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
327         applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
328     runTensorFlowNet("matmul");
329     runTensorFlowNet("nhwc_transpose_reshape_matmul");
330     // Reference output values are in range [-5.688, 4.484]
331     double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
332     runTensorFlowNet("nhwc_reshape_matmul", false, l1);
333     runTensorFlowNet("matmul_layout");
334 }
335
336 TEST_P(Test_TensorFlow_layers, reshape)
337 {
338     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
339         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
340     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
341         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
342     runTensorFlowNet("shift_reshape_no_reorder");
343     runTensorFlowNet("reshape_no_reorder");
344     runTensorFlowNet("reshape_reduce");
345     runTensorFlowNet("reshape_as_shape");
346 }
347
348 TEST_P(Test_TensorFlow_layers, flatten)
349 {
350 #if defined(INF_ENGINE_RELEASE)
351     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
352             && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
353     )
354         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
355 #endif
356
357     runTensorFlowNet("flatten", true);
358 }
359
360 TEST_P(Test_TensorFlow_layers, unfused_flatten)
361 {
362     runTensorFlowNet("unfused_flatten");
363     runTensorFlowNet("unfused_flatten_unknown_batch");
364 }
365
366 TEST_P(Test_TensorFlow_layers, leaky_relu)
367 {
368 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
369     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
370         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
371 #endif
372     runTensorFlowNet("leaky_relu_order1");
373     runTensorFlowNet("leaky_relu_order2");
374     runTensorFlowNet("leaky_relu_order3");
375 }
376
377 TEST_P(Test_TensorFlow_layers, l2_normalize)
378 {
379 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
380     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
381             && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
382     )
383         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
384 #endif
385
386     runTensorFlowNet("l2_normalize");
387 }
388
389 // TODO: fix it and add to l2_normalize
390 TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
391 {
392 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
393     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019
394             && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
395     )
396         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
397                      CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
398 #endif
399 #if defined(INF_ENGINE_RELEASE)
400     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
401         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
402 #endif
403
404     runTensorFlowNet("l2_normalize_3d");
405 }
406
407 class Test_TensorFlow_nets : public DNNTestLayer {};
408
409 TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
410 {
411 #if defined(INF_ENGINE_RELEASE)
412     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
413     {
414 #if INF_ENGINE_VER_MAJOR_GE(2019020000)
415         if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
416             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
417 #endif
418     }
419 #endif
420
421     checkBackend();
422     std::string imgPath = findDataFile("dnn/street.png");
423     std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt");
424     std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
425
426     Mat inp;
427     resize(imread(imgPath), inp, Size(300, 300));
428     inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
429
430     Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco.detection_out.npy"));
431
432     Net net = readNetFromTensorflow(netPath, netConfig);
433     net.setPreferableBackend(backend);
434     net.setPreferableTarget(target);
435
436     net.setInput(inp);
437     Mat out = net.forward();
438
439     double scoreDiff = default_l1, iouDiff = default_lInf;
440     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
441     {
442         scoreDiff = 0.0043;
443         iouDiff = 0.037;
444     }
445     else if (target == DNN_TARGET_CUDA_FP16)
446     {
447         iouDiff = 0.04;
448     }
449     normAssertDetections(ref, out, "", 0.2, scoreDiff, iouDiff);
450 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2019010000
451     expectNoFallbacksFromIE(net);
452 #endif
453 }
454
455 TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
456 {
457     applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
458 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2019010000)
459     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
460         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
461         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
462 #endif
463
464     checkBackend();
465     Mat img = imread(findDataFile("dnn/street.png"));
466     std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt");
467     std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
468
469     Net net = readNetFromTensorflow(model, proto);
470     Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
471
472     net.setPreferableBackend(backend);
473     net.setPreferableTarget(target);
474
475     net.setInput(blob);
476     // Output has shape 1x1xNx7 where N - number of detections.
477     // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
478     Mat out = net.forward();
479     Mat ref = (Mat_<float>(5, 7) << 0, 1, 0.90176028, 0.19872092, 0.36311883, 0.26461923, 0.63498729,
480                                     0, 3, 0.93569964, 0.64865261, 0.45906419, 0.80675775, 0.65708131,
481                                     0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
482                                     0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
483                                     0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
484
485     double scoreDiff = default_l1, iouDiff = default_lInf;
486     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
487     {
488         scoreDiff = 0.0097;
489         iouDiff = 0.09;
490     }
491     else if (target == DNN_TARGET_CUDA_FP16)
492     {
493         scoreDiff = 6e-3;
494         iouDiff = 0.05;
495     }
496     normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
497     expectNoFallbacksFromIE(net);
498 }
499
500 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
501 {
502     checkBackend();
503     std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt");
504     std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
505
506     Net net = readNetFromTensorflow(model, proto);
507     Mat img = imread(findDataFile("dnn/dog416.png"));
508     Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
509
510     net.setPreferableBackend(backend);
511     net.setPreferableTarget(target);
512
513     net.setInput(blob);
514     Mat out = net.forward();
515
516     Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco_2017_11_17.detection_out.npy"));
517     float scoreDiff = 1.5e-5, iouDiff = 1e-3;
518     float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.35 : 0.3;
519     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
520     {
521         scoreDiff = 0.011;
522         iouDiff = 0.012;
523     }
524     else if (target == DNN_TARGET_CUDA_FP16)
525     {
526         scoreDiff = 0.006;
527         iouDiff = 0.01;
528     }
529 #if defined(INF_ENGINE_RELEASE)
530     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
531         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
532     {
533         scoreDiff = 0.061;
534         iouDiff = 0.12;
535         detectionConfThresh = 0.36;
536     }
537 #endif
538     normAssertDetections(ref, out, "", detectionConfThresh, scoreDiff, iouDiff);
539     expectNoFallbacksFromIE(net);
540 }
541
542 TEST_P(Test_TensorFlow_nets, Faster_RCNN)
543 {
544     // FIXIT split test
545     applyTestTag(
546         (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
547         CV_TEST_TAG_LONG,
548         CV_TEST_TAG_DEBUG_VERYLONG
549     );
550     static std::string names[] = {"faster_rcnn_inception_v2_coco_2018_01_28",
551                                   "faster_rcnn_resnet50_coco_2018_01_28"};
552
553 #ifdef INF_ENGINE_RELEASE
554     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
555         (INF_ENGINE_VER_MAJOR_LT(2019020000) || target != DNN_TARGET_CPU))
556         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
557 #endif
558     // segfault: inference-engine/thirdparty/clDNN/src/gpu/detection_output_cpu.cpp:111:
559     // Assertion `prior_height > 0' failed.
560     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
561         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
562
563     if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
564         applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
565
566     if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
567         applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
568
569     checkBackend();
570
571     double scoresDiff = backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ? 2.9e-5 : 1e-5;
572     for (int i = 0; i < 2; ++i)
573     {
574         std::string proto = findDataFile("dnn/" + names[i] + ".pbtxt");
575         std::string model = findDataFile("dnn/" + names[i] + ".pb", false);
576
577         Net net = readNetFromTensorflow(model, proto);
578         net.setPreferableBackend(backend);
579         net.setPreferableTarget(target);
580         Mat img = imread(findDataFile("dnn/dog416.png"));
581         Mat blob = blobFromImage(img, 1.0f, Size(800, 600), Scalar(), true, false);
582
583         net.setInput(blob);
584         Mat out = net.forward();
585
586         Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/" + names[i] + ".detection_out.npy"));
587         normAssertDetections(ref, out, names[i].c_str(), 0.3, scoresDiff);
588     }
589 }
590
591 TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
592 {
593 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
594     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
595         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
596                      CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
597 #endif
598     checkBackend();
599     std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt");
600     std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
601
602     Net net = readNetFromTensorflow(model, proto);
603     Mat img = imread(findDataFile("dnn/dog416.png"));
604     Mat ref = blobFromNPY(findDataFile("dnn/tensorflow/ssd_mobilenet_v1_ppn_coco.detection_out.npy"));
605     Mat blob = blobFromImage(img, 1.0f, Size(300, 300), Scalar(), true, false);
606
607     net.setPreferableBackend(backend);
608     net.setPreferableTarget(target);
609
610     net.setInput(blob);
611     Mat out = net.forward();
612
613     double scoreDiff = 1.1e-5, iouDiff = default_lInf;
614     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
615     {
616         scoreDiff = 0.048;
617         iouDiff = 0.058;
618     }
619     else if (target == DNN_TARGET_CUDA_FP16)
620     {
621         scoreDiff = 0.006;
622         iouDiff = 0.05;
623     }
624     normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
625     expectNoFallbacksFromIE(net);
626 }
627
628 TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
629 {
630     checkBackend();
631     std::string proto = findDataFile("dnn/opencv_face_detector.pbtxt");
632     std::string model = findDataFile("dnn/opencv_face_detector_uint8.pb", false);
633
634     Net net = readNetFromTensorflow(model, proto);
635     Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
636     Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
637
638     net.setPreferableBackend(backend);
639     net.setPreferableTarget(target);
640     net.setInput(blob);
641     // Output has shape 1x1xNx7 where N - number of detections.
642     // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
643     Mat out = net.forward();
644
645     // References are from test for Caffe model.
646     Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
647                                     0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
648                                     0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
649                                     0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
650                                     0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
651                                     0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
652     double scoreDiff = 3.4e-3, iouDiff = 1e-2;
653     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
654     {
655         scoreDiff = 4e-3;
656         iouDiff = 0.024;
657     }
658     else if (target == DNN_TARGET_CUDA_FP16)
659     {
660         scoreDiff = 4e-3;
661         iouDiff = 0.02;
662     }
663     normAssertDetections(ref, out, "", 0.9, scoreDiff, iouDiff);
664     expectNoFallbacksFromIE(net);
665 }
666
667 // inp = cv.imread('opencv_extra/testdata/cv/ximgproc/sources/08.png')
668 // inp = inp[:,:,[2, 1, 0]].astype(np.float32).reshape(1, 512, 512, 3)
669 // outs = sess.run([sess.graph.get_tensor_by_name('feature_fusion/Conv_7/Sigmoid:0'),
670 //                  sess.graph.get_tensor_by_name('feature_fusion/concat_3:0')],
671 //                 feed_dict={'input_images:0': inp})
672 // scores = np.ascontiguousarray(outs[0].transpose(0, 3, 1, 2))
673 // geometry = np.ascontiguousarray(outs[1].transpose(0, 3, 1, 2))
674 // np.save('east_text_detection.scores.npy', scores)
675 // np.save('east_text_detection.geometry.npy', geometry)
676 TEST_P(Test_TensorFlow_nets, EAST_text_detection)
677 {
678     applyTestTag(
679         (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
680         CV_TEST_TAG_DEBUG_LONG
681     );
682
683 #if defined(INF_ENGINE_RELEASE)
684     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
685         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
686
687     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16 &&
688         INF_ENGINE_VER_MAJOR_EQ(2019020000))
689         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
690 #endif
691
692     checkBackend();
693
694     std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
695     std::string imgPath = findDataFile("cv/ximgproc/sources/08.png");
696     std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy");
697     std::string refGeometryPath = findDataFile("dnn/east_text_detection.geometry.npy");
698
699     Net net = readNet(netPath);
700
701     net.setPreferableBackend(backend);
702     net.setPreferableTarget(target);
703
704     Mat img = imread(imgPath);
705     Mat inp = blobFromImage(img, 1.0, Size(), Scalar(123.68, 116.78, 103.94), true, false);
706     net.setInput(inp);
707
708     std::vector<Mat> outs;
709     std::vector<String> outNames(2);
710     outNames[0] = "feature_fusion/Conv_7/Sigmoid";
711     outNames[1] = "feature_fusion/concat_3";
712     net.forward(outs, outNames);
713
714     Mat scores = outs[0];
715     Mat geometry = outs[1];
716
717     // Scores are in range [0, 1]. Geometry values are in range [-0.23, 290]
718     double l1_scores = default_l1, lInf_scores = default_lInf;
719     double l1_geometry = default_l1, lInf_geometry = default_lInf;
720     if (target == DNN_TARGET_OPENCL_FP16)
721     {
722         lInf_scores = backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ? 0.16 : 0.11;
723         l1_geometry = 0.28; lInf_geometry = 5.94;
724     }
725     else if (target == DNN_TARGET_MYRIAD)
726     {
727         lInf_scores = 0.41;
728         l1_geometry = 0.28; lInf_geometry = 5.94;
729     }
730     else if (target == DNN_TARGET_CUDA_FP16)
731     {
732         lInf_scores = 0.1;
733         l1_geometry = 0.3; lInf_geometry = 7;
734     }
735     else
736     {
737         l1_geometry = 1e-4, lInf_geometry = 3e-3;
738     }
739     normAssert(scores, blobFromNPY(refScoresPath), "scores", l1_scores, lInf_scores);
740     normAssert(geometry, blobFromNPY(refGeometryPath), "geometry", l1_geometry, lInf_geometry);
741     expectNoFallbacksFromIE(net);
742 }
743
744 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
745
746 TEST_P(Test_TensorFlow_layers, fp16_weights)
747 {
748     float l1 = 0.00078;
749     float lInf = 0.012;
750     runTensorFlowNet("fp16_single_conv", false, l1, lInf);
751     runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
752     runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
753     runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
754     runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
755     // Reference output values are in range [0.0889, 1.651]
756     runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
757     if (target == DNN_TARGET_MYRIAD)
758     {
759         l1 = 0.0041;
760         lInf = 0.024;
761     }
762     // Reference output values are in range [0, 10.75]
763     runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
764     // Reference output values are in range [0.418, 2.297]
765     runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
766 }
767
768 TEST_P(Test_TensorFlow_layers, fp16_padding_same)
769 {
770     // Reference output values are in range [-3.504, -0.002]
771     runTensorFlowNet("fp16_padding_same", false, 7e-4, 4e-3);
772 }
773
774 TEST_P(Test_TensorFlow_layers, defun)
775 {
776     runTensorFlowNet("defun_dropout");
777 }
778
779 TEST_P(Test_TensorFlow_layers, quantized)
780 {
781     runTensorFlowNet("uint8_single_conv");
782 }
783
784 TEST_P(Test_TensorFlow_layers, lstm)
785 {
786     if(backend == DNN_BACKEND_CUDA)
787         applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA); /* not supported */
788     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
789         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
790     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
791         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
792     if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
793         applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
794     runTensorFlowNet("lstm", true);
795     runTensorFlowNet("lstm", true, 0.0, 0.0, true);
796 }
797
798 TEST_P(Test_TensorFlow_layers, split)
799 {
800     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
801         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
802     runTensorFlowNet("split");
803 }
804
805 TEST_P(Test_TensorFlow_layers, split_equals)
806 {
807     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
808         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
809     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
810         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
811     runTensorFlowNet("split_equals");
812 }
813
814 TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor)
815 {
816     runTensorFlowNet("resize_nearest_neighbor");
817     runTensorFlowNet("keras_upsampling2d");
818 }
819
820 TEST_P(Test_TensorFlow_layers, slice)
821 {
822     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 &&
823         (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
824         applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16,
825                      CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
826     runTensorFlowNet("slice_4d");
827     runTensorFlowNet("strided_slice");
828 }
829
830 TEST_P(Test_TensorFlow_layers, softmax)
831 {
832     runTensorFlowNet("keras_softmax");
833     runTensorFlowNet("slim_softmax");
834 }
835
836 TEST_P(Test_TensorFlow_layers, slim_softmax_v2)
837 {
838 #if defined(INF_ENGINE_RELEASE)
839     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD &&
840         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
841     )
842         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
843 #endif
844     runTensorFlowNet("slim_softmax_v2");
845 }
846
847 TEST_P(Test_TensorFlow_layers, relu6)
848 {
849     runTensorFlowNet("keras_relu6");
850     runTensorFlowNet("keras_relu6", /*hasText*/ true);
851 }
852
853 TEST_P(Test_TensorFlow_layers, subpixel)
854 {
855     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
856         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
857     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
858         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
859     runTensorFlowNet("subpixel");
860 }
861
862 TEST_P(Test_TensorFlow_layers, keras_mobilenet_head)
863 {
864     runTensorFlowNet("keras_mobilenet_head");
865     runTensorFlowNet("keras_learning_phase");
866 }
867
868 TEST_P(Test_TensorFlow_layers, resize_bilinear)
869 {
870     runTensorFlowNet("resize_bilinear");
871     runTensorFlowNet("resize_bilinear_factor");
872 }
873
874 TEST_P(Test_TensorFlow_layers, squeeze)
875 {
876 #if defined(INF_ENGINE_RELEASE)
877     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
878             && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
879     )
880         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
881 #endif
882     int inpShapes[][4] = {{1, 3, 4, 2}, {1, 3, 1, 2}, {1, 3, 4, 1}, {1, 3, 4, 1}};  // TensorFlow's shape (NHWC)
883     int outShapes[][3] = {{3, 4, 2}, {1, 3, 2}, {1, 3, 4}, {1, 3, 4}};
884     int squeeze_dims[] = {0, 2, 3, -1};
885     for (int i = 0; i < 4; ++i)
886     {
887         SCOPED_TRACE(format("i=%d", i));
888         std::string pbtxt =
889             "node { name: \"input\" op: \"Placeholder\""
890             "attr { key: \"data_format\" value { s: \"NHWC\" } } }"
891             "node { name: \"squeeze\" op: \"Squeeze\" input: \"input\""
892               "attr { key: \"squeeze_dims\" value { list { i:" + format("%d", squeeze_dims[i]) + "}}}}";
893         Net net = readNetFromTensorflow(0, 0, pbtxt.c_str(), pbtxt.size());
894         net.setPreferableBackend(backend);
895         net.setPreferableTarget(target);
896         Mat tfInp(4, &inpShapes[i][0], CV_32F);
897         randu(tfInp, -1, 1);
898
899         // NHWC to NCHW
900         CV_Assert(inpShapes[i][0] == 1);
901         std::swap(inpShapes[i][2], inpShapes[i][3]);
902         std::swap(inpShapes[i][1], inpShapes[i][2]);
903         Mat cvInp = tfInp.reshape(1, tfInp.total() / inpShapes[i][1]).t();
904         cvInp = cvInp.reshape(1, 4, &inpShapes[i][0]);
905
906         net.setInput(cvInp);
907         Mat out = net.forward();
908         normAssert(tfInp.reshape(1, 3, &outShapes[i][0]), out, "", default_l1, default_lInf);
909     }
910 }
911
912 INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_layers, dnnBackendsAndTargets());
913
914 TEST(Test_TensorFlow, two_inputs)
915 {
916     Net net = readNet(path("two_inputs_net.pbtxt"));
917     net.setPreferableBackend(DNN_BACKEND_OPENCV);
918
919     Mat firstInput(2, 3, CV_32FC1), secondInput(2, 3, CV_32FC1);
920     randu(firstInput, -1, 1);
921     randu(secondInput, -1, 1);
922
923     net.setInput(firstInput, "first_input");
924     net.setInput(secondInput, "second_input");
925     Mat out = net.forward();
926
927     normAssert(out, firstInput + secondInput);
928 }
929
930 TEST(Test_TensorFlow, Mask_RCNN)
931 {
932     applyTestTag(CV_TEST_TAG_MEMORY_1GB, CV_TEST_TAG_DEBUG_VERYLONG);
933     Mat img = imread(findDataFile("dnn/street.png"));
934     std::string proto = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pbtxt");
935     std::string model = findDataFile("dnn/mask_rcnn_inception_v2_coco_2018_01_28.pb", false);
936
937     Net net = readNetFromTensorflow(model, proto);
938     Mat refDetections = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_out.npy"));
939     Mat refMasks = blobFromNPY(path("mask_rcnn_inception_v2_coco_2018_01_28.detection_masks.npy"));
940     Mat blob = blobFromImage(img, 1.0f, Size(800, 800), Scalar(), true, false);
941
942     net.setPreferableBackend(DNN_BACKEND_OPENCV);
943
944     net.setInput(blob);
945
946     // Mask-RCNN predicts bounding boxes and segmentation masks.
947     std::vector<String> outNames(2);
948     outNames[0] = "detection_out_final";
949     outNames[1] = "detection_masks";
950
951     std::vector<Mat> outs;
952     net.forward(outs, outNames);
953
954     Mat outDetections = outs[0];
955     Mat outMasks = outs[1];
956     normAssertDetections(refDetections, outDetections, "", /*threshold for zero confidence*/1e-5);
957
958     // Output size of masks is NxCxHxW where
959     // N - number of detected boxes
960     // C - number of classes (excluding background)
961     // HxW - segmentation shape
962     const int numDetections = outDetections.size[2];
963
964     int masksSize[] = {1, numDetections, outMasks.size[2], outMasks.size[3]};
965     Mat masks(4, &masksSize[0], CV_32F);
966
967     std::vector<cv::Range> srcRanges(4, cv::Range::all());
968     std::vector<cv::Range> dstRanges(4, cv::Range::all());
969
970     outDetections = outDetections.reshape(1, outDetections.total() / 7);
971     for (int i = 0; i < numDetections; ++i)
972     {
973         // Get a class id for this bounding box and copy mask only for that class.
974         int classId = static_cast<int>(outDetections.at<float>(i, 1));
975         srcRanges[0] = dstRanges[1] = cv::Range(i, i + 1);
976         srcRanges[1] = cv::Range(classId, classId + 1);
977         outMasks(srcRanges).copyTo(masks(dstRanges));
978     }
979     cv::Range topRefMasks[] = {Range::all(), Range(0, numDetections), Range::all(), Range::all()};
980     normAssert(masks, refMasks(&topRefMasks[0]));
981 }
982
983 }