4ac3e7e63acbf581be34a456556a698df23c408e
[platform/upstream/opencv.git] / modules / dnn / test / test_caffe_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 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of the copyright holders may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "test_precomp.hpp"
43 #include "npy_blob.hpp"
44 #include <opencv2/dnn/shape_utils.hpp>
45
46 namespace opencv_test { namespace {
47
48 template<typename TString>
49 static std::string _tf(TString filename)
50 {
51     return findDataFile(std::string("dnn/") + filename);
52 }
53
54 class Test_Caffe_nets : public DNNTestLayer
55 {
56 public:
57     void testFaster(const std::string& proto, const std::string& model, const Mat& ref,
58                     double scoreDiff = 0.0, double iouDiff = 0.0)
59     {
60         checkBackend();
61         Net net = readNetFromCaffe(findDataFile("dnn/" + proto),
62                                    findDataFile("dnn/" + model, false));
63         net.setPreferableBackend(backend);
64         net.setPreferableTarget(target);
65         Mat img = imread(findDataFile("dnn/dog416.png"));
66         resize(img, img, Size(800, 600));
67         Mat blob = blobFromImage(img, 1.0, Size(), Scalar(102.9801, 115.9465, 122.7717), false, false);
68         Mat imInfo = (Mat_<float>(1, 3) << img.rows, img.cols, 1.6f);
69
70         net.setInput(blob, "data");
71         net.setInput(imInfo, "im_info");
72         // Output has shape 1x1xNx7 where N - number of detections.
73         // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
74         Mat out = net.forward();
75         scoreDiff = scoreDiff ? scoreDiff : default_l1;
76         iouDiff = iouDiff ? iouDiff : default_lInf;
77         normAssertDetections(ref, out, ("model name: " + model).c_str(), 0.8, scoreDiff, iouDiff);
78     }
79 };
80
81 TEST(Test_Caffe, memory_read)
82 {
83     const string proto = findDataFile("dnn/bvlc_googlenet.prototxt");
84     const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false);
85
86     std::vector<char> dataProto;
87     readFileContent(proto, dataProto);
88
89     std::vector<char> dataModel;
90     readFileContent(model, dataModel);
91
92     Net net = readNetFromCaffe(dataProto.data(), dataProto.size());
93     net.setPreferableBackend(DNN_BACKEND_OPENCV);
94     ASSERT_FALSE(net.empty());
95
96     Net net2 = readNetFromCaffe(dataProto.data(), dataProto.size(),
97                                 dataModel.data(), dataModel.size());
98     ASSERT_FALSE(net2.empty());
99 }
100
101 TEST(Test_Caffe, read_gtsrb)
102 {
103     Net net = readNetFromCaffe(_tf("gtsrb.prototxt"));
104     ASSERT_FALSE(net.empty());
105 }
106
107 TEST(Test_Caffe, read_googlenet)
108 {
109     Net net = readNetFromCaffe(_tf("bvlc_googlenet.prototxt"));
110     ASSERT_FALSE(net.empty());
111 }
112
113 TEST_P(Test_Caffe_nets, Axpy)
114 {
115     if (backend == DNN_BACKEND_INFERENCE_ENGINE)
116         throw SkipTestException("");
117
118     String proto = _tf("axpy.prototxt");
119     Net net = readNetFromCaffe(proto);
120
121     checkBackend();
122     net.setPreferableBackend(backend);
123     net.setPreferableTarget(target);
124
125     int size[] = {1, 2, 3, 4};
126     int scale_size[] = {1, 2, 1, 1};
127     Mat scale(4, &scale_size[0], CV_32F);
128     Mat shift(4, &size[0], CV_32F);
129     Mat inp(4, &size[0], CV_32F);
130     randu(scale, -1.0f, 1.0f);
131     randu(shift, -1.0f, 1.0f);
132     randu(inp, -1.0f, 1.0f);
133
134     net.setInput(scale, "scale");
135     net.setInput(shift, "shift");
136     net.setInput(inp, "data");
137
138     Mat out = net.forward();
139
140     Mat ref(4, &size[0], inp.type());
141     for (int i = 0; i < inp.size[1]; i++) {
142         for (int h = 0; h < inp.size[2]; h++) {
143             for (int w = 0; w < inp.size[3]; w++) {
144                 int idx[] = {0, i, h, w};
145                 int scale_idx[] = {0, i, 0, 0};
146                 ref.at<float>(idx) = inp.at<float>(idx) * scale.at<float>(scale_idx) +
147                                      shift.at<float>(idx);
148             }
149         }
150     }
151     float l1 = (target == DNN_TARGET_OPENCL_FP16) ? 2e-4 : 1e-5;
152     float lInf = (target == DNN_TARGET_OPENCL_FP16) ? 1e-3 : 1e-4;
153     normAssert(ref, out, "", l1, lInf);
154 }
155
156 typedef testing::TestWithParam<tuple<bool, Target> > Reproducibility_AlexNet;
157 TEST_P(Reproducibility_AlexNet, Accuracy)
158 {
159     Target targetId = get<1>(GetParam());
160     applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
161     if (!ocl::useOpenCL() && targetId != DNN_TARGET_CPU)
162         throw SkipTestException("OpenCL is disabled");
163
164     bool readFromMemory = get<0>(GetParam());
165     Net net;
166     {
167         const string proto = findDataFile("dnn/bvlc_alexnet.prototxt");
168         const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
169         if (readFromMemory)
170         {
171             std::vector<char> dataProto;
172             readFileContent(proto, dataProto);
173             std::vector<char> dataModel;
174             readFileContent(model, dataModel);
175
176             net = readNetFromCaffe(dataProto.data(), dataProto.size(),
177                                    dataModel.data(), dataModel.size());
178         }
179         else
180             net = readNetFromCaffe(proto, model);
181         ASSERT_FALSE(net.empty());
182     }
183
184     const float l1 = 1e-5;
185     const float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-3 : 1e-4;
186
187     net.setPreferableBackend(DNN_BACKEND_OPENCV);
188     net.setPreferableTarget(targetId);
189
190     Mat sample = imread(_tf("grace_hopper_227.png"));
191     ASSERT_TRUE(!sample.empty());
192
193     net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar(), false), "data");
194     Mat out = net.forward("prob");
195     Mat ref = blobFromNPY(_tf("caffe_alexnet_prob.npy"));
196     normAssert(ref, out, "", l1, lInf);
197 }
198
199 INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_AlexNet, Combine(testing::Bool(),
200                         Values(DNN_TARGET_CPU, DNN_TARGET_OPENCL, DNN_TARGET_OPENCL_FP16)));
201
202 TEST(Reproducibility_FCN, Accuracy)
203 {
204     applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_DEBUG_VERYLONG, CV_TEST_TAG_MEMORY_2GB);
205
206     Net net;
207     {
208         const string proto = findDataFile("dnn/fcn8s-heavy-pascal.prototxt");
209         const string model = findDataFile("dnn/fcn8s-heavy-pascal.caffemodel");
210         net = readNetFromCaffe(proto, model);
211         ASSERT_FALSE(net.empty());
212     }
213     net.setPreferableBackend(DNN_BACKEND_OPENCV);
214
215     Mat sample = imread(_tf("street.png"));
216     ASSERT_TRUE(!sample.empty());
217
218     std::vector<int> layerIds;
219     std::vector<size_t> weights, blobs;
220     net.getMemoryConsumption(shape(1,3,227,227), layerIds, weights, blobs);
221
222     net.setInput(blobFromImage(sample, 1.0f, Size(500, 500), Scalar(), false), "data");
223     Mat out = net.forward("score");
224
225     Mat refData = imread(_tf("caffe_fcn8s_prob.png"), IMREAD_ANYDEPTH);
226     int shape[] = {1, 21, 500, 500};
227     Mat ref(4, shape, CV_32FC1, refData.data);
228
229     normAssert(ref, out);
230 }
231
232 TEST(Reproducibility_SSD, Accuracy)
233 {
234     applyTestTag(CV_TEST_TAG_MEMORY_512MB, CV_TEST_TAG_DEBUG_LONG);
235     Net net;
236     {
237         const string proto = findDataFile("dnn/ssd_vgg16.prototxt");
238         const string model = findDataFile("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", false);
239         net = readNetFromCaffe(proto, model);
240         ASSERT_FALSE(net.empty());
241     }
242     net.setPreferableBackend(DNN_BACKEND_OPENCV);
243
244     Mat sample = imread(_tf("street.png"));
245     ASSERT_TRUE(!sample.empty());
246
247     if (sample.channels() == 4)
248         cvtColor(sample, sample, COLOR_BGRA2BGR);
249
250     Mat in_blob = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
251     net.setInput(in_blob, "data");
252     Mat out = net.forward("detection_out");
253
254     Mat ref = blobFromNPY(_tf("ssd_out.npy"));
255     normAssertDetections(ref, out, "", FLT_MIN);
256 }
257
258 typedef testing::TestWithParam<tuple<Backend, Target> > Reproducibility_MobileNet_SSD;
259 TEST_P(Reproducibility_MobileNet_SSD, Accuracy)
260 {
261     const string proto = findDataFile("dnn/MobileNetSSD_deploy.prototxt", false);
262     const string model = findDataFile("dnn/MobileNetSSD_deploy.caffemodel", false);
263     Net net = readNetFromCaffe(proto, model);
264     int backendId = get<0>(GetParam());
265     int targetId = get<1>(GetParam());
266
267     net.setPreferableBackend(backendId);
268     net.setPreferableTarget(targetId);
269
270     Mat sample = imread(_tf("street.png"));
271
272     Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
273     net.setInput(inp);
274     Mat out = net.forward().clone();
275
276     ASSERT_EQ(out.size[2], 100);
277
278     const float scores_diff = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.5e-2 : 1e-5;
279     const float boxes_iou_diff = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 6.3e-2 : 1e-4;
280     Mat ref = blobFromNPY(_tf("mobilenet_ssd_caffe_out.npy"));
281     normAssertDetections(ref, out, "", FLT_MIN, scores_diff, boxes_iou_diff);
282
283     // Check that detections aren't preserved.
284     inp.setTo(0.0f);
285     net.setInput(inp);
286     Mat zerosOut = net.forward();
287     zerosOut = zerosOut.reshape(1, zerosOut.total() / 7);
288
289     const int numDetections = zerosOut.rows;
290     ASSERT_NE(numDetections, 0);
291     for (int i = 0; i < numDetections; ++i)
292     {
293         float confidence = zerosOut.ptr<float>(i)[2];
294         ASSERT_EQ(confidence, 0);
295     }
296
297     // There is something wrong with Reshape layer in Myriad plugin and
298     // regression with DLIE/OCL_FP16 target.
299     if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
300     {
301         if ((targetId == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2) ||
302             targetId == DNN_TARGET_OPENCL_FP16)
303             return;
304     }
305
306     // Check batching mode.
307     inp = blobFromImages(std::vector<Mat>(2, sample), 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
308     net.setInput(inp);
309     Mat outBatch = net.forward();
310
311     // Output blob has a shape 1x1x2Nx7 where N is a number of detection for
312     // a single sample in batch. The first numbers of detection vectors are batch id.
313     // For Inference Engine backend there is -1 delimiter which points the end of detections.
314     const int numRealDetections = ref.size[2];
315     EXPECT_EQ(outBatch.size[2], 2 * numDetections);
316     out = out.reshape(1, numDetections).rowRange(0, numRealDetections);
317     outBatch = outBatch.reshape(1, 2 * numDetections);
318     for (int i = 0; i < 2; ++i)
319     {
320         Mat pred = outBatch.rowRange(i * numRealDetections, (i + 1) * numRealDetections);
321         EXPECT_EQ(countNonZero(pred.col(0) != i), 0);
322         normAssert(pred.colRange(1, 7), out.colRange(1, 7));
323     }
324 }
325 INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_MobileNet_SSD, dnnBackendsAndTargets());
326
327 typedef testing::TestWithParam<Target> Reproducibility_ResNet50;
328 TEST_P(Reproducibility_ResNet50, Accuracy)
329 {
330     Target targetId = GetParam();
331     applyTestTag(targetId == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
332     if (!ocl::useOpenCL() && targetId != DNN_TARGET_CPU)
333         throw SkipTestException("OpenCL is disabled");
334
335     Net net = readNetFromCaffe(findDataFile("dnn/ResNet-50-deploy.prototxt"),
336                                findDataFile("dnn/ResNet-50-model.caffemodel", false));
337
338     net.setPreferableBackend(DNN_BACKEND_OPENCV);
339     net.setPreferableTarget(targetId);
340
341     float l1 = (targetId == DNN_TARGET_OPENCL_FP16) ? 3e-5 : 1e-5;
342     float lInf = (targetId == DNN_TARGET_OPENCL_FP16) ? 6e-3 : 1e-4;
343
344     Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(224,224), Scalar(), false);
345     ASSERT_TRUE(!input.empty());
346
347     net.setInput(input);
348     Mat out = net.forward();
349
350     Mat ref = blobFromNPY(_tf("resnet50_prob.npy"));
351     normAssert(ref, out, "", l1, lInf);
352
353     if (targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16)
354     {
355         UMat out_umat;
356         net.forward(out_umat);
357         normAssert(ref, out_umat, "out_umat", l1, lInf);
358
359         std::vector<UMat> out_umats;
360         net.forward(out_umats);
361         normAssert(ref, out_umats[0], "out_umat_vector", l1, lInf);
362     }
363 }
364 INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_ResNet50,
365                         Values(DNN_TARGET_CPU, DNN_TARGET_OPENCL, DNN_TARGET_OPENCL_FP16));
366
367 typedef testing::TestWithParam<Target> Reproducibility_SqueezeNet_v1_1;
368 TEST_P(Reproducibility_SqueezeNet_v1_1, Accuracy)
369 {
370     int targetId = GetParam();
371     if(targetId == DNN_TARGET_OPENCL_FP16)
372         throw SkipTestException("This test does not support FP16");
373     Net net = readNetFromCaffe(findDataFile("dnn/squeezenet_v1.1.prototxt"),
374                                findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
375     net.setPreferableBackend(DNN_BACKEND_OPENCV);
376     net.setPreferableTarget(targetId);
377
378     Mat input = blobFromImage(imread(_tf("googlenet_0.png")), 1.0f, Size(227,227), Scalar(), false, true);
379     ASSERT_TRUE(!input.empty());
380
381     Mat out;
382     if (targetId == DNN_TARGET_OPENCL)
383     {
384         // Firstly set a wrong input blob and run the model to receive a wrong output.
385         // Then set a correct input blob to check CPU->GPU synchronization is working well.
386         net.setInput(input * 2.0f);
387         out = net.forward();
388     }
389     net.setInput(input);
390     out = net.forward();
391
392     Mat ref = blobFromNPY(_tf("squeezenet_v1.1_prob.npy"));
393     normAssert(ref, out);
394 }
395 INSTANTIATE_TEST_CASE_P(/**/, Reproducibility_SqueezeNet_v1_1,
396     testing::ValuesIn(getAvailableTargets(DNN_BACKEND_OPENCV)));
397
398 TEST(Reproducibility_AlexNet_fp16, Accuracy)
399 {
400     applyTestTag(CV_TEST_TAG_MEMORY_512MB);
401     const float l1 = 1e-5;
402     const float lInf = 3e-3;
403
404     const string proto = findDataFile("dnn/bvlc_alexnet.prototxt");
405     const string model = findDataFile("dnn/bvlc_alexnet.caffemodel", false);
406
407     shrinkCaffeModel(model, "bvlc_alexnet.caffemodel_fp16");
408     Net net = readNetFromCaffe(proto, "bvlc_alexnet.caffemodel_fp16");
409     net.setPreferableBackend(DNN_BACKEND_OPENCV);
410
411     Mat sample = imread(findDataFile("dnn/grace_hopper_227.png"));
412
413     net.setInput(blobFromImage(sample, 1.0f, Size(227, 227), Scalar()));
414     Mat out = net.forward();
415     Mat ref = blobFromNPY(findDataFile("dnn/caffe_alexnet_prob.npy"));
416     normAssert(ref, out, "", l1, lInf);
417 }
418
419 TEST(Reproducibility_GoogLeNet_fp16, Accuracy)
420 {
421     const float l1 = 1e-5;
422     const float lInf = 3e-3;
423
424     const string proto = findDataFile("dnn/bvlc_googlenet.prototxt");
425     const string model = findDataFile("dnn/bvlc_googlenet.caffemodel", false);
426
427     shrinkCaffeModel(model, "bvlc_googlenet.caffemodel_fp16");
428     Net net = readNetFromCaffe(proto, "bvlc_googlenet.caffemodel_fp16");
429     net.setPreferableBackend(DNN_BACKEND_OPENCV);
430
431     std::vector<Mat> inpMats;
432     inpMats.push_back( imread(_tf("googlenet_0.png")) );
433     inpMats.push_back( imread(_tf("googlenet_1.png")) );
434     ASSERT_TRUE(!inpMats[0].empty() && !inpMats[1].empty());
435
436     net.setInput(blobFromImages(inpMats, 1.0f, Size(), Scalar(), false), "data");
437     Mat out = net.forward("prob");
438
439     Mat ref = blobFromNPY(_tf("googlenet_prob.npy"));
440     normAssert(out, ref, "", l1, lInf);
441 }
442
443 // https://github.com/richzhang/colorization
444 TEST_P(Test_Caffe_nets, Colorization)
445 {
446     applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
447     checkBackend();
448
449     Mat inp = blobFromNPY(_tf("colorization_inp.npy"));
450     Mat ref = blobFromNPY(_tf("colorization_out.npy"));
451     Mat kernel = blobFromNPY(_tf("colorization_pts_in_hull.npy"));
452
453     const string proto = findDataFile("dnn/colorization_deploy_v2.prototxt", false);
454     const string model = findDataFile("dnn/colorization_release_v2.caffemodel", false);
455     Net net = readNetFromCaffe(proto, model);
456     net.setPreferableBackend(backend);
457     net.setPreferableTarget(target);
458
459     net.getLayer(net.getLayerId("class8_ab"))->blobs.push_back(kernel);
460     net.getLayer(net.getLayerId("conv8_313_rh"))->blobs.push_back(Mat(1, 313, CV_32F, 2.606));
461
462     net.setInput(inp);
463     Mat out = net.forward();
464
465     // Reference output values are in range [-29.1, 69.5]
466     double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.25 : 4e-4;
467     double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5.3 : 3e-3;
468     if (target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
469     {
470         l1 = 0.6; lInf = 15;
471     }
472     normAssert(out, ref, "", l1, lInf);
473     expectNoFallbacksFromIE(net);
474 }
475
476 TEST_P(Test_Caffe_nets, DenseNet_121)
477 {
478     applyTestTag(CV_TEST_TAG_MEMORY_512MB);
479     checkBackend();
480     const string proto = findDataFile("dnn/DenseNet_121.prototxt", false);
481     const string model = findDataFile("dnn/DenseNet_121.caffemodel", false);
482
483     Mat inp = imread(_tf("dog416.png"));
484     inp = blobFromImage(inp, 1.0 / 255, Size(224, 224), Scalar(), true, true);
485     Mat ref = blobFromNPY(_tf("densenet_121_output.npy"));
486
487     Net net = readNetFromCaffe(proto, model);
488     net.setPreferableBackend(backend);
489     net.setPreferableTarget(target);
490
491     net.setInput(inp);
492     Mat out = net.forward();
493
494     // Reference is an array of 1000 values from a range [-6.16, 7.9]
495     float l1 = default_l1, lInf = default_lInf;
496     if (target == DNN_TARGET_OPENCL_FP16)
497     {
498         l1 = 0.017; lInf = 0.0795;
499     }
500     else if (target == DNN_TARGET_MYRIAD)
501     {
502         l1 = 0.11; lInf = 0.5;
503     }
504     normAssert(out, ref, "", l1, lInf);
505     expectNoFallbacksFromIE(net);
506 }
507
508 TEST(Test_Caffe, multiple_inputs)
509 {
510     const string proto = findDataFile("dnn/layers/net_input.prototxt");
511     Net net = readNetFromCaffe(proto);
512     net.setPreferableBackend(DNN_BACKEND_OPENCV);
513
514     Mat first_image(10, 11, CV_32FC3);
515     Mat second_image(10, 11, CV_32FC3);
516     randu(first_image, -1, 1);
517     randu(second_image, -1, 1);
518
519     first_image = blobFromImage(first_image);
520     second_image = blobFromImage(second_image);
521
522     Mat first_image_blue_green = slice(first_image, Range::all(), Range(0, 2), Range::all(), Range::all());
523     Mat first_image_red = slice(first_image, Range::all(), Range(2, 3), Range::all(), Range::all());
524     Mat second_image_blue_green = slice(second_image, Range::all(), Range(0, 2), Range::all(), Range::all());
525     Mat second_image_red = slice(second_image, Range::all(), Range(2, 3), Range::all(), Range::all());
526
527     net.setInput(first_image_blue_green, "old_style_input_blue_green");
528     net.setInput(first_image_red, "different_name_for_red");
529     net.setInput(second_image_blue_green, "input_layer_blue_green");
530     net.setInput(second_image_red, "old_style_input_red");
531     Mat out = net.forward();
532
533     normAssert(out, first_image + second_image);
534 }
535
536 TEST(Test_Caffe, shared_weights)
537 {
538   const string proto = findDataFile("dnn/layers/shared_weights.prototxt");
539   const string model = findDataFile("dnn/layers/shared_weights.caffemodel");
540
541   Net net = readNetFromCaffe(proto, model);
542
543   Mat input_1 = (Mat_<float>(2, 2) << 0., 2., 4., 6.);
544   Mat input_2 = (Mat_<float>(2, 2) << 1., 3., 5., 7.);
545
546   Mat blob_1 = blobFromImage(input_1);
547   Mat blob_2 = blobFromImage(input_2);
548
549   net.setInput(blob_1, "input_1");
550   net.setInput(blob_2, "input_2");
551   net.setPreferableBackend(DNN_BACKEND_OPENCV);
552
553   Mat sum = net.forward();
554
555   EXPECT_EQ(sum.at<float>(0,0), 12.);
556   EXPECT_EQ(sum.at<float>(0,1), 16.);
557 }
558
559 typedef testing::TestWithParam<tuple<std::string, Target> > opencv_face_detector;
560 TEST_P(opencv_face_detector, Accuracy)
561 {
562     std::string proto = findDataFile("dnn/opencv_face_detector.prototxt", false);
563     std::string model = findDataFile(get<0>(GetParam()), false);
564     dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam());
565
566     Net net = readNetFromCaffe(proto, model);
567     Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
568     Mat blob = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
569
570     net.setPreferableBackend(DNN_BACKEND_OPENCV);
571     net.setPreferableTarget(targetId);
572
573     net.setInput(blob);
574     // Output has shape 1x1xNx7 where N - number of detections.
575     // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
576     Mat out = net.forward();
577     Mat ref = (Mat_<float>(6, 7) << 0, 1, 0.99520785, 0.80997437, 0.16379407, 0.87996572, 0.26685631,
578                                     0, 1, 0.9934696, 0.2831718, 0.50738752, 0.345781, 0.5985168,
579                                     0, 1, 0.99096733, 0.13629119, 0.24892329, 0.19756334, 0.3310290,
580                                     0, 1, 0.98977017, 0.23901358, 0.09084064, 0.29902688, 0.1769477,
581                                     0, 1, 0.97203469, 0.67965847, 0.06876482, 0.73999709, 0.1513494,
582                                     0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
583     normAssertDetections(ref, out, "", 0.5, 1e-5, 2e-4);
584 }
585 INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
586     Combine(
587         Values("dnn/opencv_face_detector.caffemodel",
588                "dnn/opencv_face_detector_fp16.caffemodel"),
589         Values(DNN_TARGET_CPU, DNN_TARGET_OPENCL)
590     )
591 );
592
593 TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
594 {
595     applyTestTag(
596         (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
597         CV_TEST_TAG_LONG,
598         CV_TEST_TAG_DEBUG_VERYLONG
599     );
600
601 #if defined(INF_ENGINE_RELEASE)
602     if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
603         throw SkipTestException("Test is disabled for DLIE OpenCL targets");  // very slow
604
605     if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
606         throw SkipTestException("Test is disabled for Myriad targets");
607 #endif
608
609     static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
610                                            0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
611                                            0, 12, 0.993028, 133.221, 189.377, 350.994, 563.166);
612     testFaster("faster_rcnn_vgg16.prototxt", "VGG16_faster_rcnn_final.caffemodel", ref);
613 }
614
615 TEST_P(Test_Caffe_nets, FasterRCNN_zf)
616 {
617     applyTestTag(
618         (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB),
619         CV_TEST_TAG_DEBUG_LONG
620     );
621     if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16) ||
622         (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
623         throw SkipTestException("");
624     static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.90121, 120.407, 115.83, 570.586, 528.395,
625                                            0, 7, 0.988779, 469.849, 75.1756, 718.64, 186.762,
626                                            0, 12, 0.967198, 138.588, 206.843, 329.766, 553.176);
627     testFaster("faster_rcnn_zf.prototxt", "ZF_faster_rcnn_final.caffemodel", ref);
628 }
629
630 TEST_P(Test_Caffe_nets, RFCN)
631 {
632     applyTestTag(
633         (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_2GB),
634         CV_TEST_TAG_LONG,
635         CV_TEST_TAG_DEBUG_VERYLONG
636     );
637     if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16) ||
638         (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
639         throw SkipTestException("");
640     double scoreDiff = (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) ? 4e-3 : default_l1;
641     double iouDiff = (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) ? 8e-2 : default_lInf;
642     static Mat ref = (Mat_<float>(2, 7) << 0, 7, 0.991359, 491.822, 81.1668, 702.573, 178.234,
643                                            0, 12, 0.94786, 132.093, 223.903, 338.077, 566.16);
644     testFaster("rfcn_pascal_voc_resnet50.prototxt", "resnet50_rfcn_final.caffemodel", ref, scoreDiff, iouDiff);
645 }
646
647 INSTANTIATE_TEST_CASE_P(/**/, Test_Caffe_nets, dnnBackendsAndTargets());
648
649 }} // namespace