Merge pull request #20910 from lukasalexanderweber:sift_fix
[platform/upstream/opencv.git] / modules / dnn / test / test_darknet_importer.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //                        (3-clause BSD License)
13 //
14 // Copyright (C) 2017, Intel Corporation, all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 // * Redistributions of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
22 //
23 // * Redistributions in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
26 //
27 // * Neither the names of the copyright holders nor the names of the contributors
28 // may be used to endorse or promote products derived from this software
29 // without specific prior written permission.
30 //
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall copyright holders or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
41 //
42 //M*/
43
44 #include "test_precomp.hpp"
45 #include "npy_blob.hpp"
46 #include <opencv2/dnn/shape_utils.hpp>
47
48 namespace opencv_test { namespace {
49
50 template<typename TString>
51 static std::string _tf(TString filename)
52 {
53     return (getOpenCVExtraDir() + "/dnn/") + filename;
54 }
55
56 TEST(Test_Darknet, read_tiny_yolo_voc)
57 {
58     Net net = readNetFromDarknet(_tf("tiny-yolo-voc.cfg"));
59     ASSERT_FALSE(net.empty());
60 }
61
62 TEST(Test_Darknet, read_yolo_voc)
63 {
64     Net net = readNetFromDarknet(_tf("yolo-voc.cfg"));
65     ASSERT_FALSE(net.empty());
66 }
67
68 TEST(Test_Darknet, read_yolo_voc_stream)
69 {
70     applyTestTag(CV_TEST_TAG_MEMORY_1GB);
71     Mat ref;
72     Mat sample = imread(_tf("dog416.png"));
73     Mat inp = blobFromImage(sample, 1.0/255, Size(416, 416), Scalar(), true, false);
74     const std::string cfgFile = findDataFile("dnn/yolo-voc.cfg");
75     const std::string weightsFile = findDataFile("dnn/yolo-voc.weights", false);
76     // Import by paths.
77     {
78         Net net = readNetFromDarknet(cfgFile, weightsFile);
79         net.setInput(inp);
80         net.setPreferableBackend(DNN_BACKEND_OPENCV);
81         ref = net.forward();
82     }
83     // Import from bytes array.
84     {
85         std::vector<char> cfg, weights;
86         readFileContent(cfgFile, cfg);
87         readFileContent(weightsFile, weights);
88
89         Net net = readNetFromDarknet(cfg.data(), cfg.size(), weights.data(), weights.size());
90         net.setInput(inp);
91         net.setPreferableBackend(DNN_BACKEND_OPENCV);
92         Mat out = net.forward();
93         normAssert(ref, out);
94     }
95 }
96
97 class Test_Darknet_layers : public DNNTestLayer
98 {
99 public:
100     void testDarknetLayer(const std::string& name, bool hasWeights = false, bool testBatchProcessing = true)
101     {
102         SCOPED_TRACE(name);
103         Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy"));
104         Mat ref = blobFromNPY(findDataFile("dnn/darknet/" + name + "_out.npy"));
105
106         std::string cfg = findDataFile("dnn/darknet/" + name + ".cfg");
107         std::string model = "";
108         if (hasWeights)
109             model = findDataFile("dnn/darknet/" + name + ".weights");
110
111         checkBackend(&inp, &ref);
112
113         Net net = readNet(cfg, model);
114         net.setPreferableBackend(backend);
115         net.setPreferableTarget(target);
116         net.setInput(inp);
117         Mat out = net.forward();
118         normAssert(out, ref, "", default_l1, default_lInf);
119
120         if (inp.size[0] == 1 && testBatchProcessing)  // test handling of batch size
121         {
122             SCOPED_TRACE("batch size 2");
123
124 #if defined(INF_ENGINE_RELEASE)
125             if (target == DNN_TARGET_MYRIAD && name == "shortcut")
126                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
127 #endif
128
129             std::vector<int> sz2 = shape(inp);
130             sz2[0] = 2;
131
132             Net net2 = readNet(cfg, model);
133             net2.setPreferableBackend(backend);
134             net2.setPreferableTarget(target);
135             Range ranges0[4] = { Range(0, 1), Range::all(), Range::all(), Range::all() };
136             Range ranges1[4] = { Range(1, 2), Range::all(), Range::all(), Range::all() };
137             Mat inp2(sz2, inp.type(), Scalar::all(0));
138             inp.copyTo(inp2(ranges0));
139             inp.copyTo(inp2(ranges1));
140             net2.setInput(inp2);
141             Mat out2 = net2.forward();
142             EXPECT_EQ(0, cv::norm(out2(ranges0), out2(ranges1), NORM_INF)) << "Batch result is not equal: " << name;
143
144             Mat ref2 = ref;
145             if (ref.dims == 2 && out2.dims == 3)
146             {
147                 int ref_3d_sizes[3] = {1, ref.rows, ref.cols};
148                 ref2 = Mat(3, ref_3d_sizes, ref.type(), (void*)ref.data);
149             }
150             /*else if (ref.dims == 3 && out2.dims == 4)
151             {
152                 int ref_4d_sizes[4] = {1, ref.size[0], ref.size[1], ref.size[2]};
153                 ref2 = Mat(4, ref_4d_sizes, ref.type(), (void*)ref.data);
154             }*/
155             ASSERT_EQ(out2.dims, ref2.dims) << ref.dims;
156
157             normAssert(out2(ranges0), ref2, "", default_l1, default_lInf);
158             normAssert(out2(ranges1), ref2, "", default_l1, default_lInf);
159         }
160     }
161 };
162
163 class Test_Darknet_nets : public DNNTestLayer
164 {
165 public:
166     // Test object detection network from Darknet framework.
167     void testDarknetModel(const std::string& cfg, const std::string& weights,
168                           const std::vector<std::vector<int> >& refClassIds,
169                           const std::vector<std::vector<float> >& refConfidences,
170                           const std::vector<std::vector<Rect2d> >& refBoxes,
171                           double scoreDiff, double iouDiff, float confThreshold = 0.24, float nmsThreshold = 0.4)
172     {
173         checkBackend();
174
175         Mat img1 = imread(_tf("dog416.png"));
176         Mat img2 = imread(_tf("street.png"));
177         std::vector<Mat> samples(2);
178         samples[0] = img1; samples[1] = img2;
179
180         // determine test type, whether batch or single img
181         int batch_size = refClassIds.size();
182         CV_Assert(batch_size == 1 || batch_size == 2);
183         samples.resize(batch_size);
184
185         Mat inp = blobFromImages(samples, 1.0/255, Size(416, 416), Scalar(), true, false);
186
187         Net net = readNet(findDataFile("dnn/" + cfg),
188                           findDataFile("dnn/" + weights, false));
189         net.setPreferableBackend(backend);
190         net.setPreferableTarget(target);
191         net.setInput(inp);
192         std::vector<Mat> outs;
193         net.forward(outs, net.getUnconnectedOutLayersNames());
194
195         for (int b = 0; b < batch_size; ++b)
196         {
197             std::vector<int> classIds;
198             std::vector<float> confidences;
199             std::vector<Rect2d> boxes;
200             for (int i = 0; i < outs.size(); ++i)
201             {
202                 Mat out;
203                 if (batch_size > 1){
204                     // get the sample slice from 3D matrix (batch, box, classes+5)
205                     Range ranges[3] = {Range(b, b+1), Range::all(), Range::all()};
206                     out = outs[i](ranges).reshape(1, outs[i].size[1]);
207                 }else{
208                     out = outs[i];
209                 }
210                 for (int j = 0; j < out.rows; ++j)
211                 {
212                     Mat scores = out.row(j).colRange(5, out.cols);
213                     double confidence;
214                     Point maxLoc;
215                     minMaxLoc(scores, 0, &confidence, 0, &maxLoc);
216
217                     if (confidence > confThreshold) {
218                         float* detection = out.ptr<float>(j);
219                         double centerX = detection[0];
220                         double centerY = detection[1];
221                         double width = detection[2];
222                         double height = detection[3];
223                         boxes.push_back(Rect2d(centerX - 0.5 * width, centerY - 0.5 * height,
224                                             width, height));
225                         confidences.push_back(confidence);
226                         classIds.push_back(maxLoc.x);
227                     }
228                 }
229             }
230
231             // here we need NMS of boxes
232             std::vector<int> indices;
233             NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);
234
235             std::vector<int> nms_classIds;
236             std::vector<float> nms_confidences;
237             std::vector<Rect2d> nms_boxes;
238
239             for (size_t i = 0; i < indices.size(); ++i)
240             {
241                 int idx = indices[i];
242                 Rect2d box = boxes[idx];
243                 float conf = confidences[idx];
244                 int class_id = classIds[idx];
245                 nms_boxes.push_back(box);
246                 nms_confidences.push_back(conf);
247                 nms_classIds.push_back(class_id);
248 #if 0  // use to update test reference data
249                 std::cout << b << ", " << class_id << ", " << conf << "f, "
250                           << box.x << "f, " << box.y << "f, "
251                           << box.x + box.width << "f, " << box.y + box.height << "f,"
252                           << std::endl;
253 #endif
254
255             }
256
257             if (cvIsNaN(iouDiff))
258             {
259                 if (b == 0)
260                     std::cout << "Skip accuracy checks" << std::endl;
261                 continue;
262             }
263
264             normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
265                              nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
266         }
267     }
268
269     void testDarknetModel(const std::string& cfg, const std::string& weights,
270                           const std::vector<int>& refClassIds,
271                           const std::vector<float>& refConfidences,
272                           const std::vector<Rect2d>& refBoxes,
273                           double scoreDiff, double iouDiff, float confThreshold = 0.24, float nmsThreshold = 0.4)
274     {
275         testDarknetModel(cfg, weights,
276                          std::vector<std::vector<int> >(1, refClassIds),
277                          std::vector<std::vector<float> >(1, refConfidences),
278                          std::vector<std::vector<Rect2d> >(1, refBoxes),
279                          scoreDiff, iouDiff, confThreshold, nmsThreshold);
280     }
281
282     void testDarknetModel(const std::string& cfg, const std::string& weights,
283                           const cv::Mat& ref, double scoreDiff, double iouDiff,
284                           float confThreshold = 0.24, float nmsThreshold = 0.4)
285     {
286         CV_Assert(ref.cols == 7);
287         std::vector<std::vector<int> > refClassIds;
288         std::vector<std::vector<float> > refScores;
289         std::vector<std::vector<Rect2d> > refBoxes;
290         for (int i = 0; i < ref.rows; ++i)
291         {
292             int batchId = static_cast<int>(ref.at<float>(i, 0));
293             int classId = static_cast<int>(ref.at<float>(i, 1));
294             float score = ref.at<float>(i, 2);
295             float left  = ref.at<float>(i, 3);
296             float top   = ref.at<float>(i, 4);
297             float right  = ref.at<float>(i, 5);
298             float bottom = ref.at<float>(i, 6);
299             Rect2d box(left, top, right - left, bottom - top);
300             if (batchId >= refClassIds.size())
301             {
302                 refClassIds.resize(batchId + 1);
303                 refScores.resize(batchId + 1);
304                 refBoxes.resize(batchId + 1);
305             }
306             refClassIds[batchId].push_back(classId);
307             refScores[batchId].push_back(score);
308             refBoxes[batchId].push_back(box);
309         }
310         testDarknetModel(cfg, weights, refClassIds, refScores, refBoxes,
311                          scoreDiff, iouDiff, confThreshold, nmsThreshold);
312     }
313 };
314
315 TEST_P(Test_Darknet_nets, YoloVoc)
316 {
317     applyTestTag(
318 #if defined(OPENCV_32BIT_CONFIGURATION) && defined(HAVE_OPENCL)
319         CV_TEST_TAG_MEMORY_2GB,
320 #else
321         CV_TEST_TAG_MEMORY_1GB,
322 #endif
323         CV_TEST_TAG_LONG
324     );
325
326 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
327     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
328         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
329     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
330         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
331 #endif
332 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
333     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL_FP16)
334         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
335 #endif
336 #if defined(INF_ENGINE_RELEASE)
337     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
338         target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
339         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);  // need to update check function
340 #endif
341
342     // batchId, classId, confidence, left, top, right, bottom
343     Mat ref = (Mat_<float>(6, 7) << 0, 6,  0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f,  // a car
344                                     0, 1,  0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f,  // a bicycle
345                                     0, 11, 0.901615f, 0.1386f,   0.338509f, 0.421337f, 0.938789f,  // a dog
346                                     1, 14, 0.623813f, 0.183179f, 0.381921f, 0.247726f, 0.625847f,  // a person
347                                     1, 6,  0.667770f, 0.446555f, 0.453578f, 0.499986f, 0.519167f,  // a car
348                                     1, 6,  0.844947f, 0.637058f, 0.460398f, 0.828508f, 0.66427f);  // a car
349
350     double nmsThreshold = (target == DNN_TARGET_MYRIAD) ? 0.397 : 0.4;
351     double scoreDiff = 8e-5, iouDiff = 3e-4;
352     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
353     {
354         scoreDiff = 1e-2;
355         iouDiff = 0.018;
356     }
357     else if (target == DNN_TARGET_CUDA_FP16)
358     {
359         scoreDiff = 0.03;
360         iouDiff = 0.018;
361     }
362
363     std::string config_file = "yolo-voc.cfg";
364     std::string weights_file = "yolo-voc.weights";
365
366     {
367     SCOPED_TRACE("batch size 1");
368     testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
369     }
370
371     {
372     SCOPED_TRACE("batch size 2");
373     testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, nmsThreshold);
374     }
375 }
376
377 TEST_P(Test_Darknet_nets, TinyYoloVoc)
378 {
379     applyTestTag(CV_TEST_TAG_MEMORY_512MB);
380
381 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
382     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
383         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
384     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
385         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
386 #endif
387 #if defined(INF_ENGINE_RELEASE)
388     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
389         target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
390         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);  // need to update check function
391 #endif
392     // batchId, classId, confidence, left, top, right, bottom
393     Mat ref = (Mat_<float>(4, 7) << 0, 6,  0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f,   // a car
394                                     0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f,  // a dog
395                                     1, 6,  0.651450f, 0.460526f, 0.458019f, 0.522527f, 0.5341f,    // a car
396                                     1, 6,  0.928758f, 0.651024f, 0.463539f, 0.823784f, 0.654998f); // a car
397
398     double scoreDiff = 8e-5, iouDiff = 3e-4;
399     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
400     {
401         scoreDiff = 8e-3;
402         iouDiff = 0.018;
403     }
404     else if(target == DNN_TARGET_CUDA_FP16)
405     {
406         scoreDiff = 0.008;
407         iouDiff = 0.02;
408     }
409
410     std::string config_file = "tiny-yolo-voc.cfg";
411     std::string weights_file = "tiny-yolo-voc.weights";
412
413     {
414     SCOPED_TRACE("batch size 1");
415     testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
416     }
417
418     {
419     SCOPED_TRACE("batch size 2");
420     testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
421     }
422 }
423
424 #ifdef HAVE_INF_ENGINE
425 static const std::chrono::milliseconds async_timeout(10000);
426
427 typedef testing::TestWithParam<tuple<std::string, tuple<Backend, Target> > > Test_Darknet_nets_async;
428 TEST_P(Test_Darknet_nets_async, Accuracy)
429 {
430     Backend backendId = get<0>(get<1>(GetParam()));
431     Target targetId = get<1>(get<1>(GetParam()));
432
433     if (INF_ENGINE_VER_MAJOR_LT(2019020000) && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
434         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
435     applyTestTag(CV_TEST_TAG_MEMORY_512MB);
436
437     if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
438         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
439
440     std::string prefix = get<0>(GetParam());
441
442     if (targetId == DNN_TARGET_MYRIAD && prefix == "yolov4")  // NC_OUT_OF_MEMORY
443         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
444
445     if (backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
446         throw SkipTestException("No support for async forward");
447
448     const int numInputs = 2;
449     std::vector<Mat> inputs(numInputs);
450     int blobSize[] = {1, 3, 416, 416};
451     for (int i = 0; i < numInputs; ++i)
452     {
453         inputs[i].create(4, &blobSize[0], CV_32F);
454         randu(inputs[i], 0, 1);
455     }
456
457     Net netSync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
458                           findDataFile("dnn/" + prefix + ".weights", false));
459     netSync.setPreferableBackend(backendId);
460     netSync.setPreferableTarget(targetId);
461
462     // Run synchronously.
463     std::vector<Mat> refs(numInputs);
464     for (int i = 0; i < numInputs; ++i)
465     {
466         netSync.setInput(inputs[i]);
467         refs[i] = netSync.forward().clone();
468     }
469
470     Net netAsync = readNet(findDataFile("dnn/" + prefix + ".cfg"),
471                            findDataFile("dnn/" + prefix + ".weights", false));
472     netAsync.setPreferableBackend(backendId);
473     netAsync.setPreferableTarget(targetId);
474
475     // Run asynchronously. To make test more robust, process inputs in the reversed order.
476     for (int i = numInputs - 1; i >= 0; --i)
477     {
478         netAsync.setInput(inputs[i]);
479
480         AsyncArray out = netAsync.forwardAsync();
481         ASSERT_TRUE(out.valid());
482         Mat result;
483         EXPECT_TRUE(out.get(result, async_timeout));
484         normAssert(refs[i], result, format("Index: %d", i).c_str(), 0, 0);
485     }
486 }
487
488 INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
489     Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny"),
490     dnnBackendsAndTargets()
491 ));
492
493 #endif
494
495 TEST_P(Test_Darknet_nets, YOLOv3)
496 {
497     applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
498
499 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
500     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
501         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
502     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
503         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
504 #endif
505
506     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
507         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
508
509     // batchId, classId, confidence, left, top, right, bottom
510     const int N0 = 3;
511     const int N1 = 6;
512     static const float ref_[/* (N0 + N1) * 7 */] = {
513 0, 16, 0.998836f, 0.160024f, 0.389964f, 0.417885f, 0.943716f,
514 0, 1, 0.987908f, 0.150913f, 0.221933f, 0.742255f, 0.746261f,
515 0, 7, 0.952983f, 0.614621f, 0.150257f, 0.901368f, 0.289251f,
516
517 1, 2, 0.997412f, 0.647584f, 0.459939f, 0.821037f, 0.663947f,
518 1, 2, 0.989633f, 0.450719f, 0.463353f, 0.496306f, 0.522258f,
519 1, 0, 0.980053f, 0.195856f, 0.378454f, 0.258626f, 0.629257f,
520 1, 9, 0.785341f, 0.665503f, 0.373543f, 0.688893f, 0.439244f,
521 1, 9, 0.733275f, 0.376029f, 0.315694f, 0.401776f, 0.395165f,
522 1, 9, 0.384815f, 0.659824f, 0.372389f, 0.673927f, 0.429412f,
523     };
524     Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
525
526     double scoreDiff = 8e-5, iouDiff = 3e-4;
527     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
528     {
529         scoreDiff = 0.006;
530         iouDiff = 0.042;
531     }
532     else if (target == DNN_TARGET_CUDA_FP16)
533     {
534         scoreDiff = 0.04;
535         iouDiff = 0.03;
536     }
537     std::string config_file = "yolov3.cfg";
538     std::string weights_file = "yolov3.weights";
539
540 #if defined(INF_ENGINE_RELEASE)
541     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
542          backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
543         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
544     {
545         scoreDiff = 0.04;
546         iouDiff = 0.2;
547     }
548 #endif
549
550     {
551         SCOPED_TRACE("batch size 1");
552         testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
553     }
554
555 #if defined(INF_ENGINE_RELEASE)
556     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
557     {
558         if (target == DNN_TARGET_OPENCL)
559             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
560         else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
561             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
562         else if (target == DNN_TARGET_MYRIAD &&
563                  getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
564             applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
565     }
566 #endif
567
568     {
569         SCOPED_TRACE("batch size 2");
570         testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
571     }
572 }
573
574 TEST_P(Test_Darknet_nets, YOLOv4)
575 {
576     applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
577
578 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
579     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
580         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
581     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
582         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
583 #endif
584 #if defined(INF_ENGINE_RELEASE)
585     if (target == DNN_TARGET_MYRIAD)  // NC_OUT_OF_MEMORY
586         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
587 #endif
588
589     // batchId, classId, confidence, left, top, right, bottom
590     const int N0 = 3;
591     const int N1 = 7;
592     static const float ref_[/* (N0 + N1) * 7 */] = {
593 0, 16, 0.992194f, 0.172375f, 0.402458f, 0.403918f, 0.932801f,
594 0, 1, 0.988326f, 0.166708f, 0.228236f, 0.737208f, 0.735803f,
595 0, 7, 0.94639f, 0.602523f, 0.130399f, 0.901623f, 0.298452f,
596
597 1, 2, 0.99761f, 0.646556f, 0.45985f, 0.816041f, 0.659067f,
598 1, 0, 0.988913f, 0.201726f, 0.360282f, 0.266181f, 0.631728f,
599 1, 2, 0.98233f, 0.452007f, 0.462217f, 0.495612f, 0.521687f,
600 1, 9, 0.919195f, 0.374642f, 0.316524f, 0.398126f, 0.393714f,
601 1, 9, 0.856303f, 0.666842f, 0.372215f, 0.685539f, 0.44141f,
602 1, 9, 0.313516f, 0.656791f, 0.374734f, 0.671959f, 0.438371f,
603 1, 9, 0.256625f, 0.940232f, 0.326931f, 0.967586f, 0.374002f,
604     };
605     Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
606
607     double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.006 : 8e-5;
608     double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.042 : 3e-4;
609     if (target == DNN_TARGET_CUDA_FP16)
610     {
611         scoreDiff = 0.008;
612         iouDiff = 0.03;
613     }
614
615     std::string config_file = "yolov4.cfg";
616     std::string weights_file = "yolov4.weights";
617
618 #if defined(INF_ENGINE_RELEASE)
619     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
620          backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
621         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
622     {
623         scoreDiff = 0.04;
624         iouDiff = 0.2;
625     }
626 #endif
627
628     {
629         SCOPED_TRACE("batch size 1");
630         testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
631     }
632
633     {
634         SCOPED_TRACE("batch size 2");
635
636 #if defined(INF_ENGINE_RELEASE)
637         if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
638         {
639             if (target == DNN_TARGET_OPENCL)
640                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
641             else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
642                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
643             else if (target == DNN_TARGET_MYRIAD &&
644                      getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
645                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
646         }
647 #endif
648
649         testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
650     }
651 }
652
653 TEST_P(Test_Darknet_nets, YOLOv4_tiny)
654 {
655     applyTestTag(
656         target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
657     );
658
659 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000)  // nGraph compilation failure
660     if (target == DNN_TARGET_MYRIAD)
661         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
662 #endif
663
664     const double confThreshold = 0.5;
665     // batchId, classId, confidence, left, top, right, bottom
666     const int N0 = 2;
667     const int N1 = 3;
668     static const float ref_[/* (N0 + N1) * 7 */] = {
669 0, 7, 0.85935f, 0.593484f, 0.141211f, 0.920356f, 0.291593f,
670 0, 16, 0.795188f, 0.169207f, 0.386886f, 0.423753f, 0.933004f,
671
672 1, 2, 0.996832f, 0.653802f, 0.464573f, 0.815193f, 0.653292f,
673 1, 2, 0.963325f, 0.451151f, 0.458915f, 0.496255f, 0.52241f,
674 1, 0, 0.926244f, 0.194851f, 0.361743f, 0.260277f, 0.632364f,
675     };
676     Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
677
678     double scoreDiff = 0.01f;
679     double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.15 : 0.01f;
680     if (target == DNN_TARGET_CUDA_FP16)
681         iouDiff = 0.02;
682
683     std::string config_file = "yolov4-tiny.cfg";
684     std::string weights_file = "yolov4-tiny.weights";
685
686 #if defined(INF_ENGINE_RELEASE)
687     if (target == DNN_TARGET_MYRIAD)  // bad accuracy
688         iouDiff = std::numeric_limits<double>::quiet_NaN();
689     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
690         iouDiff = std::numeric_limits<double>::quiet_NaN();
691     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
692          backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
693         iouDiff = std::numeric_limits<double>::quiet_NaN();
694 #endif
695
696     {
697         SCOPED_TRACE("batch size 1");
698         testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
699     }
700
701     {
702         SCOPED_TRACE("batch size 2");
703         testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
704     }
705
706 #if defined(INF_ENGINE_RELEASE)
707     if (target == DNN_TARGET_MYRIAD)  // bad accuracy
708         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
709     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
710         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
711     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
712          backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_OPENCL_FP16)
713         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
714 #endif
715 }
716
717 TEST_P(Test_Darknet_nets, YOLOv4x_mish)
718 {
719     applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB));
720
721 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000)  // nGraph compilation failure
722     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
723         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
724     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
725         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
726 #endif
727 #if defined(INF_ENGINE_RELEASE)
728     if (target == DNN_TARGET_MYRIAD)  // NC_OUT_OF_MEMORY
729         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
730 #endif
731
732     // batchId, classId, confidence, left, top, right, bottom
733     const int N0 = 3;
734     const int N1 = 5;
735     static const float ref_[/* (N0 + N1) * 7 */] = {
736 0, 16, 0.925536f, 0.17188f,  0.386832f, 0.406138f, 0.941696f,
737 0, 1,  0.912028f, 0.162125f, 0.208863f, 0.741316f, 0.729332f,
738 0, 7,  0.841018f, 0.608953f, 0.128653f, 0.900692f, 0.295657f,
739
740 1, 2, 0.925697f, 0.650438f, 0.458118f, 0.813927f, 0.661775f,
741 1, 0, 0.882156f, 0.203644f, 0.365763f, 0.265473f, 0.632195f,
742 1, 2, 0.848857f, 0.451044f, 0.462997f, 0.496629f, 0.522719f,
743 1, 9, 0.736015f, 0.374503f, 0.316029f, 0.399358f, 0.392883f,
744 1, 9, 0.727129f, 0.662469f, 0.373687f, 0.687877f, 0.441335f,
745     };
746     Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
747
748     double scoreDiff = 8e-5;
749     double iouDiff = 3e-4;
750
751     if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CUDA_FP16)
752     {
753         scoreDiff = 0.006;
754         iouDiff = 0.042;
755     }
756
757     std::string config_file = "yolov4x-mish.cfg";
758     std::string weights_file = "yolov4x-mish.weights";
759
760 #if defined(INF_ENGINE_RELEASE)
761     if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
762          backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && target == DNN_TARGET_MYRIAD &&
763         getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
764     {
765         scoreDiff = 0.04;
766         iouDiff = 0.2;
767     }
768 #endif
769
770     {
771         SCOPED_TRACE("batch size 1");
772         testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff);
773     }
774
775     {
776         SCOPED_TRACE("batch size 2");
777
778 #if defined(INF_ENGINE_RELEASE)
779         if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
780         {
781             if (target == DNN_TARGET_OPENCL)
782                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
783             else if (target == DNN_TARGET_OPENCL_FP16 && INF_ENGINE_VER_MAJOR_LE(202010000))
784                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
785             else if (target == DNN_TARGET_MYRIAD &&
786                      getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
787                 applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
788         }
789 #endif
790
791         testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
792     }
793 }
794
795
796 INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
797
798 TEST_P(Test_Darknet_layers, shortcut)
799 {
800     testDarknetLayer("shortcut");
801     testDarknetLayer("shortcut_leaky");
802     testDarknetLayer("shortcut_unequal");
803     testDarknetLayer("shortcut_unequal_2");
804 }
805
806 TEST_P(Test_Darknet_layers, upsample)
807 {
808 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
809     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
810         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);  // exception
811 #endif
812     testDarknetLayer("upsample");
813 }
814
815 TEST_P(Test_Darknet_layers, mish)
816 {
817     testDarknetLayer("mish", true);
818 }
819
820 TEST_P(Test_Darknet_layers, tanh)
821 {
822     testDarknetLayer("tanh");
823 }
824
825 TEST_P(Test_Darknet_layers, avgpool_softmax)
826 {
827     testDarknetLayer("avgpool_softmax");
828 }
829
830 TEST_P(Test_Darknet_layers, region)
831 {
832 #if defined(INF_ENGINE_RELEASE)
833      if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && INF_ENGINE_VER_MAJOR_GE(2020020000))
834         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
835 #endif
836     testDarknetLayer("region");
837 }
838
839 TEST_P(Test_Darknet_layers, reorg)
840 {
841     testDarknetLayer("reorg");
842 }
843
844 TEST_P(Test_Darknet_layers, route)
845 {
846     testDarknetLayer("route");
847     testDarknetLayer("route_multi");
848 }
849
850 TEST_P(Test_Darknet_layers, maxpool)
851 {
852 #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)
853     if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
854         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
855 #endif
856     testDarknetLayer("maxpool");
857 }
858
859 TEST_P(Test_Darknet_layers, convolutional)
860 {
861     if (target == DNN_TARGET_MYRIAD)
862     {
863         default_l1 = 0.01f;
864     }
865     testDarknetLayer("convolutional", true);
866 }
867
868 TEST_P(Test_Darknet_layers, scale_channels)
869 {
870     bool testBatches = backend == DNN_BACKEND_CUDA;
871     testDarknetLayer("scale_channels", false, testBatches);
872 }
873
874 TEST_P(Test_Darknet_layers, connected)
875 {
876     if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
877         applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
878     testDarknetLayer("connected", true);
879 }
880
881 TEST_P(Test_Darknet_layers, relu)
882 {
883      if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
884         applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
885     testDarknetLayer("relu");
886 }
887
888 TEST_P(Test_Darknet_layers, sam)
889 {
890     testDarknetLayer("sam", true);
891 }
892
893 INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_layers, dnnBackendsAndTargets());
894
895 }} // namespace