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) 2018-2021 Intel Corporation
6 
7 
8 #ifndef OPENCV_GAPI_CORE_TESTS_INL_HPP
9 #define OPENCV_GAPI_CORE_TESTS_INL_HPP
10 
11 #include <opencv2/gapi/core.hpp>
12 #include <opencv2/gapi/infer/parsers.hpp>
13 #include "gapi_core_tests.hpp"
14 
15 #include "gapi_core_tests_common.hpp"
16 
17 namespace opencv_test
18 {
TEST_P(MathOpTest,MatricesAccuracyTest)19 TEST_P(MathOpTest, MatricesAccuracyTest)
20 {
21     // G-API code & corresponding OpenCV code ////////////////////////////////
22     cv::GMat in1, in2, out;
23     if( testWithScalar )
24     {
25         cv::GScalar sc1;
26         switch(opType)
27         {
28         case (ADD):
29         {
30             out = cv::gapi::addC(in1, sc1, dtype);
31             cv::add(in_mat1, sc, out_mat_ocv, cv::noArray(), dtype);
32             break;
33         }
34         case (SUB):
35         {
36             if( doReverseOp )
37             {
38                 out = cv::gapi::subRC(sc1, in1, dtype);
39                 cv::subtract(sc, in_mat1, out_mat_ocv, cv::noArray(), dtype);
40             }
41             else
42             {
43                 out = cv::gapi::subC(in1, sc1, dtype);
44                 cv::subtract(in_mat1, sc, out_mat_ocv, cv::noArray(), dtype);
45             }
46             break;
47         }
48         case (DIV):
49         {
50             if( doReverseOp )
51             {
52                 in_mat1.setTo(1, in_mat1 == 0);  // avoiding zeros in divide input data
53                 out = cv::gapi::divRC(sc1, in1, scale, dtype);
54                 cv::divide(sc, in_mat1, out_mat_ocv, scale, dtype);
55                 break;
56             }
57             else
58             {
59                 sc += Scalar(sc[0] == 0, sc[1] == 0, sc[2] == 0, sc[3] == 0);  // avoiding zeros in divide input data
60                 out = cv::gapi::divC(in1, sc1, scale, dtype);
61                 cv::divide(in_mat1, sc, out_mat_ocv, scale, dtype);
62                 break;
63             }
64         }
65         case (MUL):
66         {
67             // FIXME: add `scale` parameter to mulC
68             out = cv::gapi::mulC(in1, sc1, /* scale, */ dtype);
69             cv::multiply(in_mat1, sc, out_mat_ocv, 1., dtype);
70             break;
71         }
72         default:
73         {
74             FAIL() << "no such math operation type for scalar and matrix!";
75         }
76         }
77         cv::GComputation c(GIn(in1, sc1), GOut(out));
78         c.apply(gin(in_mat1, sc), gout(out_mat_gapi), getCompileArgs());
79     }
80     else
81     {
82         switch(opType)
83         {
84         case (ADD):
85         {
86             out = cv::gapi::add(in1, in2, dtype);
87             cv::add(in_mat1, in_mat2, out_mat_ocv, cv::noArray(), dtype);
88             break;
89         }
90         case (SUB):
91         {
92             out = cv::gapi::sub(in1, in2, dtype);
93             cv::subtract(in_mat1, in_mat2, out_mat_ocv, cv::noArray(), dtype);
94             break;
95         }
96         case (DIV):
97         {
98             in_mat2.setTo(1, in_mat2 == 0);  // avoiding zeros in divide input data
99             out = cv::gapi::div(in1, in2, scale, dtype);
100             cv::divide(in_mat1, in_mat2, out_mat_ocv, scale, dtype);
101             break;
102         }
103         case (MUL):
104         {
105             out = cv::gapi::mul(in1, in2, scale, dtype);
106             cv::multiply(in_mat1, in_mat2, out_mat_ocv, scale, dtype);
107             break;
108         }
109         default:
110         {
111             FAIL() << "no such math operation type for matrix and matrix!";
112         }}
113         cv::GComputation c(GIn(in1, in2), GOut(out));
114         c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
115     }
116 
117     // Comparison //////////////////////////////////////////////////////////////
118     {
119     // TODO: make threshold vs bit-exact criteria be driven by testing parameter
120     #if 1
121         if (CV_MAT_DEPTH(out_mat_ocv.type()) != CV_32F &&
122             CV_MAT_DEPTH(out_mat_ocv.type()) != CV_64F)
123         {
124             // integral: allow 1% of differences, and no diffs by >1 unit
125             EXPECT_LE(cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF), 1);  // check: abs(a[i] - b[i]) <= 1
126             float tolerance = 0.01f;
127 #if defined(__arm__) || defined(__aarch64__)
128             if (opType == DIV)
129                 tolerance = 0.05f;
130 #endif
131             EXPECT_LE(cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_L1), tolerance*out_mat_ocv.total());
132         }
133         else
134         {
135             // floating-point: expect 6 decimal digits - best we expect of F32
136             EXPECT_LE(cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF | NORM_RELATIVE), 1e-6);
137         }
138     #else
139         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
140     #endif
141         EXPECT_EQ(out_mat_gapi.size(), sz);
142     }
143 }
144 
TEST_P(MulDoubleTest,AccuracyTest)145 TEST_P(MulDoubleTest, AccuracyTest)
146 {
147     auto& rng = cv::theRNG();
148     double d = rng.uniform(0.0, 10.0);
149 
150     // G-API code ////////////////////////////////////////////////////////////
151     cv::GMat in1, out;
152     out = cv::gapi::mulC(in1, d, dtype);
153     cv::GComputation c(in1, out);
154     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
155 
156     // OpenCV code ///////////////////////////////////////////////////////////
157     cv::multiply(in_mat1, d, out_mat_ocv, 1, dtype);
158 
159     // Comparison ////////////////////////////////////////////////////////////
160 #if 1
161     if (CV_MAT_DEPTH(out_mat_ocv.type()) != CV_32F &&
162         CV_MAT_DEPTH(out_mat_ocv.type()) != CV_64F)
163     {
164         // integral: allow 1% of differences, and no diffs by >1 unit
165         EXPECT_LE(cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF), 1);
166         EXPECT_LE(cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_L1 | NORM_RELATIVE), 0.01);
167     }
168     else
169     {
170         // floating-point: expect 6 decimal digits - best we expect of F32
171         EXPECT_LE(cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF | NORM_RELATIVE), 1e-6);
172     }
173 #else
174     EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
175 #endif
176     EXPECT_EQ(out_mat_gapi.size(), sz);
177 }
178 
TEST_P(DivTest,DISABLED_DivByZeroTest)179 TEST_P(DivTest, DISABLED_DivByZeroTest)  // https://github.com/opencv/opencv/pull/12826
180 {
181     in_mat2 = cv::Mat(sz, type);
182     in_mat2.setTo(cv::Scalar::all(0));
183 
184     // G-API code //////////////////////////////////////////////////////////////
185     cv::GMat in1, in2;
186     auto out = cv::gapi::div(in1, in2, 1.0, dtype);
187     cv::GComputation c(GIn(in1, in2), GOut(out));
188     c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
189 
190     // OpenCV code /////////////////////////////////////////////////////////////
191     {
192         cv::divide(in_mat1, in_mat2, out_mat_ocv, 1.0, dtype);
193     }
194 
195     // Comparison //////////////////////////////////////////////////////////////
196     {
197         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
198         EXPECT_EQ(out_mat_gapi.size(), sz);
199     }
200 }
201 
TEST_P(DivCTest,DISABLED_DivByZeroTest)202 TEST_P(DivCTest, DISABLED_DivByZeroTest)  // https://github.com/opencv/opencv/pull/12826
203 {
204     sc = cv::Scalar::all(0);
205 
206     // G-API code //////////////////////////////////////////////////////////////
207     cv::GMat in1;
208     cv::GScalar sc1;
209     auto out = cv::gapi::divC(in1, sc1, dtype);
210     cv::GComputation c(GIn(in1, sc1), GOut(out));
211 
212     c.apply(gin(in_mat1, sc), gout(out_mat_gapi), getCompileArgs());
213 
214     // OpenCV code /////////////////////////////////////////////////////////////
215     {
216         cv::divide(in_mat1, sc, out_mat_ocv, dtype);
217     }
218 
219     // Comparison //////////////////////////////////////////////////////////////
220     {
221         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
222         cv::Mat zeros = cv::Mat::zeros(sz, type);
223         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, zeros, NORM_INF));
224     }
225 }
226 
TEST_P(MeanTest,AccuracyTest)227 TEST_P(MeanTest, AccuracyTest)
228 {
229     cv::Scalar out_norm;
230     cv::Scalar out_norm_ocv;
231 
232     // G-API code //////////////////////////////////////////////////////////////
233     cv::GMat in;
234     auto out = cv::gapi::mean(in);
235 
236     cv::GComputation c(cv::GIn(in), cv::GOut(out));
237     c.apply(cv::gin(in_mat1), cv::gout(out_norm), getCompileArgs());
238     // OpenCV code /////////////////////////////////////////////////////////////
239     {
240         out_norm_ocv = cv::mean(in_mat1);
241     }
242     // Comparison //////////////////////////////////////////////////////////////
243     {
244         EXPECT_EQ(out_norm[0], out_norm_ocv[0]);
245     }
246 }
247 
TEST_P(MaskTest,AccuracyTest)248 TEST_P(MaskTest, AccuracyTest)
249 {
250     in_mat2 = cv::Mat(sz, CV_8UC1);
251     cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
252     in_mat2 = in_mat2 > 128;
253 
254     // G-API code //////////////////////////////////////////////////////////////
255     cv::GMat in, m;
256     auto out = cv::gapi::mask(in, m);
257 
258     cv::GComputation c(cv::GIn(in, m), cv::GOut(out));
259     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
260     // OpenCV code /////////////////////////////////////////////////////////////
261     {
262         out_mat_ocv = cv::Mat::zeros(in_mat1.size(), in_mat1.type());
263         in_mat1.copyTo(out_mat_ocv, in_mat2);
264     }
265     // Comparison //////////////////////////////////////////////////////////////
266     {
267         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
268     }
269 }
270 
TEST_P(Polar2CartTest,AccuracyTest)271 TEST_P(Polar2CartTest, AccuracyTest)
272 {
273     cv::Mat out_mat2;
274     cv::Mat out_mat_ocv2;
275     if (dtype != -1)
276     {
277         out_mat2 = cv::Mat(sz, dtype);
278         out_mat_ocv2 = cv::Mat(sz, dtype);
279     }
280 
281     // G-API code //////////////////////////////////////////////////////////////
282     cv::GMat in1, in2, out1, out2;
283     std::tie(out1, out2) = cv::gapi::polarToCart(in1, in2);
284 
285     cv::GComputation c(GIn(in1, in2), GOut(out1, out2));
286     c.apply(gin(in_mat1,in_mat2), gout(out_mat_gapi, out_mat2), getCompileArgs());
287     // OpenCV code /////////////////////////////////////////////////////////////
288     {
289         cv::polarToCart(in_mat1, in_mat2, out_mat_ocv, out_mat_ocv2);
290     }
291     // Comparison //////////////////////////////////////////////////////////////
292     {
293         // Note that we cannot rely on bit-exact sin/cos functions used for this
294         // transform, so we need a threshold for verifying results vs reference.
295         //
296         // Relative threshold like 1e-6 is very restrictive, nearly best we can
297         // expect of single-precision elementary functions implementation.
298         //
299         // However, good idea is making such threshold configurable: parameter
300         // of this test - which a specific test instantiation could setup.
301         //
302         // Note that test instantiation for the OpenCV back-end could even let
303         // the threshold equal to zero, as CV back-end calls the same kernel.
304         //
305         // TODO: Make threshold a configurable parameter of this test (ADE-221)
306 
307         ASSERT_EQ(out_mat_gapi.size(), sz);
308 
309         cv::Mat &outx = out_mat_gapi,
310                 &outy = out_mat2;
311         cv::Mat &refx = out_mat_ocv,
312                 &refy = out_mat_ocv2;
313 
314         EXPECT_LE(cvtest::norm(refx, outx, NORM_L1 | NORM_RELATIVE), 1e-6);
315         EXPECT_LE(cvtest::norm(refy, outy, NORM_L1 | NORM_RELATIVE), 1e-6);
316     }
317 }
318 
TEST_P(Cart2PolarTest,AccuracyTest)319 TEST_P(Cart2PolarTest, AccuracyTest)
320 {
321     cv::Mat out_mat2(sz, dtype);
322     cv::Mat out_mat_ocv2(sz, dtype);
323 
324     // G-API code //////////////////////////////////////////////////////////////
325     cv::GMat in1, in2, out1, out2;
326     std::tie(out1, out2) = cv::gapi::cartToPolar(in1, in2);
327 
328     cv::GComputation c(GIn(in1, in2), GOut(out1, out2));
329     c.apply(gin(in_mat1,in_mat2), gout(out_mat_gapi, out_mat2));
330     // OpenCV code /////////////////////////////////////////////////////////////
331     {
332         cv::cartToPolar(in_mat1, in_mat2, out_mat_ocv, out_mat_ocv2);
333     }
334     // Comparison //////////////////////////////////////////////////////////////
335     {
336         // Note that we cannot rely on bit-exact sin/cos functions used for this
337         // transform, so we need a threshold for verifying results vs reference.
338         //
339         // Relative threshold like 1e-6 is very restrictive, nearly best we can
340         // expect of single-precision elementary functions implementation.
341         //
342         // However, good idea is making such threshold configurable: parameter
343         // of this test - which a specific test instantiation could setup.
344         //
345         // Note that test instantiation for the OpenCV back-end could even let
346         // the threshold equal to zero, as CV back-end calls the same kernel.
347         //
348         // TODO: Make threshold a configurable parameter of this test (ADE-221)
349 
350         ASSERT_EQ(out_mat_gapi.size(), sz);
351 
352         cv::Mat &outm = out_mat_gapi,
353                 &outa = out_mat2;
354         cv::Mat &refm = out_mat_ocv,
355                 &refa = out_mat_ocv2;
356 
357         // FIXME: Angle result looks inaccurate at OpenCV
358         //        (expected relative accuracy like 1e-6)
359         EXPECT_LE(cvtest::norm(refm, outm, NORM_INF), 1e-6);
360         EXPECT_LE(cvtest::norm(refa, outa, NORM_INF), 1e-3);
361     }
362 }
363 
TEST_P(CmpTest,AccuracyTest)364 TEST_P(CmpTest, AccuracyTest)
365 {
366     // G-API code & corresponding OpenCV code ////////////////////////////////
367     cv::GMat in1, out;
368     if( testWithScalar )
369     {
370         cv::GScalar in2;
371         switch(opType)
372         {
373         case CMP_EQ: out = cv::gapi::cmpEQ(in1, in2); break;
374         case CMP_GT: out = cv::gapi::cmpGT(in1, in2); break;
375         case CMP_GE: out = cv::gapi::cmpGE(in1, in2); break;
376         case CMP_LT: out = cv::gapi::cmpLT(in1, in2); break;
377         case CMP_LE: out = cv::gapi::cmpLE(in1, in2); break;
378         case CMP_NE: out = cv::gapi::cmpNE(in1, in2); break;
379         default: FAIL() << "no such compare operation type for matrix and scalar!";
380         }
381 
382         cv::compare(in_mat1, sc, out_mat_ocv, opType);
383 
384         cv::GComputation c(GIn(in1, in2), GOut(out));
385         c.apply(gin(in_mat1, sc), gout(out_mat_gapi), getCompileArgs());
386     }
387     else
388     {
389         cv::GMat in2;
390         switch(opType)
391         {
392         case CMP_EQ: out = cv::gapi::cmpEQ(in1, in2); break;
393         case CMP_GT: out = cv::gapi::cmpGT(in1, in2); break;
394         case CMP_GE: out = cv::gapi::cmpGE(in1, in2); break;
395         case CMP_LT: out = cv::gapi::cmpLT(in1, in2); break;
396         case CMP_LE: out = cv::gapi::cmpLE(in1, in2); break;
397         case CMP_NE: out = cv::gapi::cmpNE(in1, in2); break;
398         default: FAIL() << "no such compare operation type for two matrices!";
399         }
400 
401         cv::compare(in_mat1, in_mat2, out_mat_ocv, opType);
402 
403         cv::GComputation c(GIn(in1, in2), GOut(out));
404         c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
405     }
406 
407     // Comparison //////////////////////////////////////////////////////////////
408     {
409         ASSERT_EQ(out_mat_gapi.size(), sz);
410         EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
411     }
412 }
413 
TEST_P(BitwiseTest,AccuracyTest)414 TEST_P(BitwiseTest, AccuracyTest)
415 {
416     // G-API code & corresponding OpenCV code ////////////////////////////////
417     cv::GMat in1, in2, out;
418     if( testWithScalar )
419     {
420         cv::GScalar sc1;
421         switch(opType)
422         {
423             case AND:
424                 out = cv::gapi::bitwise_and(in1, sc1);
425                 cv::bitwise_and(in_mat1, sc, out_mat_ocv);
426                 break;
427             case OR:
428                 out = cv::gapi::bitwise_or(in1, sc1);
429                 cv::bitwise_or(in_mat1, sc, out_mat_ocv);
430                 break;
431             case XOR:
432                 out = cv::gapi::bitwise_xor(in1, sc1);
433                 cv::bitwise_xor(in_mat1, sc, out_mat_ocv);
434                 break;
435             default:
436                 FAIL() << "no such bitwise operation type!";
437         }
438         cv::GComputation c(GIn(in1, sc1), GOut(out));
439         c.apply(gin(in_mat1, sc), gout(out_mat_gapi), getCompileArgs());
440     }
441     else
442     {
443         switch(opType)
444         {
445             case AND:
446                 out = cv::gapi::bitwise_and(in1, in2);
447                 cv::bitwise_and(in_mat1, in_mat2, out_mat_ocv);
448                 break;
449             case OR:
450                 out = cv::gapi::bitwise_or(in1, in2);
451                 cv::bitwise_or(in_mat1, in_mat2, out_mat_ocv);
452                 break;
453             case XOR:
454                 out = cv::gapi::bitwise_xor(in1, in2);
455                 cv::bitwise_xor(in_mat1, in_mat2, out_mat_ocv);
456                 break;
457             default:
458                 FAIL() << "no such bitwise operation type!";
459         }
460         cv::GComputation c(GIn(in1, in2), GOut(out));
461         c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
462     }
463 
464 
465     // Comparison //////////////////////////////////////////////////////////////
466     {
467         ASSERT_EQ(out_mat_gapi.size(), sz);
468         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
469     }
470 }
471 
TEST_P(NotTest,AccuracyTest)472 TEST_P(NotTest, AccuracyTest)
473 {
474     // G-API code //////////////////////////////////////////////////////////////
475     cv::GMat in;
476     auto out = cv::gapi::bitwise_not(in);
477     cv::GComputation c(in, out);
478 
479     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
480 
481     // OpenCV code /////////////////////////////////////////////////////////////
482     {
483         cv::bitwise_not(in_mat1, out_mat_ocv);
484     }
485     // Comparison //////////////////////////////////////////////////////////////
486     {
487         ASSERT_EQ(out_mat_gapi.size(), sz);
488         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
489     }
490 }
491 
TEST_P(SelectTest,AccuracyTest)492 TEST_P(SelectTest, AccuracyTest)
493 {
494     cv::Mat in_mask(sz, CV_8UC1);
495     cv::randu(in_mask, cv::Scalar::all(0), cv::Scalar::all(255));
496 
497     // G-API code //////////////////////////////////////////////////////////////
498     cv::GMat in1, in2, in3;
499     auto out = cv::gapi::select(in1, in2, in3);
500     cv::GComputation c(GIn(in1, in2, in3), GOut(out));
501 
502     c.apply(gin(in_mat1, in_mat2, in_mask), gout(out_mat_gapi), getCompileArgs());
503 
504     // OpenCV code /////////////////////////////////////////////////////////////
505     {
506         in_mat2.copyTo(out_mat_ocv);
507         in_mat1.copyTo(out_mat_ocv, in_mask);
508     }
509     // Comparison //////////////////////////////////////////////////////////////
510     {
511         ASSERT_EQ(out_mat_gapi.size(), sz);
512         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
513     }
514 }
515 
TEST_P(MinTest,AccuracyTest)516 TEST_P(MinTest, AccuracyTest)
517 {
518     // G-API code //////////////////////////////////////////////////////////////
519     cv::GMat in1, in2;
520     auto out = cv::gapi::min(in1, in2);
521     cv::GComputation c(GIn(in1, in2), GOut(out));
522 
523     c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
524 
525     // OpenCV code /////////////////////////////////////////////////////////////
526     {
527         cv::min(in_mat1, in_mat2, out_mat_ocv);
528     }
529     // Comparison //////////////////////////////////////////////////////////////
530     {
531         ASSERT_EQ(out_mat_gapi.size(), sz);
532         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
533     }
534 }
535 
TEST_P(MaxTest,AccuracyTest)536 TEST_P(MaxTest, AccuracyTest)
537 {
538     // G-API code //////////////////////////////////////////////////////////////
539     cv::GMat in1, in2;
540     auto out = cv::gapi::max(in1, in2);
541     cv::GComputation c(GIn(in1, in2), GOut(out));
542 
543     c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
544 
545     // OpenCV code /////////////////////////////////////////////////////////////
546     {
547         cv::max(in_mat1, in_mat2, out_mat_ocv);
548     }
549     // Comparison //////////////////////////////////////////////////////////////
550     {
551         ASSERT_EQ(out_mat_gapi.size(), sz);
552         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
553     }
554 }
555 
TEST_P(AbsDiffTest,AccuracyTest)556 TEST_P(AbsDiffTest, AccuracyTest)
557 {
558     // G-API code //////////////////////////////////////////////////////////////
559     cv::GMat in1, in2;
560     auto out = cv::gapi::absDiff(in1, in2);
561     cv::GComputation c(GIn(in1, in2), GOut(out));
562 
563     c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
564 
565     // OpenCV code /////////////////////////////////////////////////////////////
566     {
567         cv::absdiff(in_mat1, in_mat2, out_mat_ocv);
568     }
569     // Comparison //////////////////////////////////////////////////////////////
570     {
571         ASSERT_EQ(out_mat_gapi.size(), sz);
572         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
573     }
574 }
575 
TEST_P(AbsDiffCTest,AccuracyTest)576 TEST_P(AbsDiffCTest, AccuracyTest)
577 {
578     // G-API code //////////////////////////////////////////////////////////////
579     cv::GMat in1;
580     cv::GScalar sc1;
581     auto out = cv::gapi::absDiffC(in1, sc1);
582     cv::GComputation c(cv::GIn(in1, sc1), cv::GOut(out));
583 
584     c.apply(gin(in_mat1, sc), gout(out_mat_gapi), getCompileArgs());
585 
586     // OpenCV code /////////////////////////////////////////////////////////////
587     {
588         cv::absdiff(in_mat1, sc, out_mat_ocv);
589     }
590     // Comparison //////////////////////////////////////////////////////////////
591     {
592         ASSERT_EQ(out_mat_gapi.size(), sz);
593         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
594     }
595 }
596 
TEST_P(SumTest,AccuracyTest)597 TEST_P(SumTest, AccuracyTest)
598 {
599     cv::Scalar out_sum;
600     cv::Scalar out_sum_ocv;
601 
602     // G-API code //////////////////////////////////////////////////////////////
603     cv::GMat in;
604     auto out = cv::gapi::sum(in);
605 
606     cv::GComputation c(cv::GIn(in), cv::GOut(out));
607     c.apply(cv::gin(in_mat1), cv::gout(out_sum), getCompileArgs());
608     // OpenCV code /////////////////////////////////////////////////////////////
609     {
610         out_sum_ocv = cv::sum(in_mat1);
611     }
612     // Comparison //////////////////////////////////////////////////////////////
613     {
614         EXPECT_TRUE(cmpF(out_sum, out_sum_ocv));
615     }
616 }
617 
618 #pragma push_macro("countNonZero")
619 #undef countNonZero
TEST_P(CountNonZeroTest,AccuracyTest)620 TEST_P(CountNonZeroTest, AccuracyTest)
621 {
622     int out_cnz_gapi = -1;
623     int out_cnz_ocv = -2;
624 
625     // G-API code //////////////////////////////////////////////////////////////
626     cv::GMat in;
627     auto out = cv::gapi::countNonZero(in);
628 
629     cv::GComputation c(cv::GIn(in), cv::GOut(out));
630     c.apply(cv::gin(in_mat1), cv::gout(out_cnz_gapi), getCompileArgs());
631     // OpenCV code /////////////////////////////////////////////////////////////
632     {
633         out_cnz_ocv = cv::countNonZero(in_mat1);
634     }
635     // Comparison //////////////////////////////////////////////////////////////
636     {
637         EXPECT_TRUE(cmpF(out_cnz_gapi, out_cnz_ocv));
638     }
639 }
640 #pragma pop_macro("countNonZero")
641 
TEST_P(AddWeightedTest,AccuracyTest)642 TEST_P(AddWeightedTest, AccuracyTest)
643 {
644     auto& rng = cv::theRNG();
645     double alpha = rng.uniform(0.0, 1.0);
646     double beta = rng.uniform(0.0, 1.0);
647     double gamma = rng.uniform(0.0, 1.0);
648 
649     // G-API code //////////////////////////////////////////////////////////////
650     cv::GMat in1, in2;
651     auto out = cv::gapi::addWeighted(in1, alpha, in2, beta, gamma, dtype);
652     cv::GComputation c(GIn(in1, in2), GOut(out));
653 
654     c.apply(gin(in_mat1, in_mat2), gout(out_mat_gapi), getCompileArgs());
655 
656     // OpenCV code /////////////////////////////////////////////////////////////
657     {
658         cv::addWeighted(in_mat1, alpha, in_mat2, beta, gamma, out_mat_ocv, dtype);
659     }
660     // Comparison //////////////////////////////////////////////////////////////
661     EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
662     EXPECT_EQ(out_mat_gapi.size(), sz);
663 }
664 
TEST_P(NormTest,AccuracyTest)665 TEST_P(NormTest, AccuracyTest)
666 {
667     cv::Scalar out_norm;
668     cv::Scalar out_norm_ocv;
669 
670     // G-API code & corresponding OpenCV code ////////////////////////////////
671     cv::GMat in1;
672     cv::GScalar out;
673     switch(opType)
674     {
675         case NORM_L1: out = cv::gapi::normL1(in1); break;
676         case NORM_L2: out = cv::gapi::normL2(in1); break;
677         case NORM_INF: out = cv::gapi::normInf(in1); break;
678         default: FAIL() << "no such norm operation type!";
679     }
680     out_norm_ocv = cv::norm(in_mat1, opType);
681     cv::GComputation c(GIn(in1), GOut(out));
682     c.apply(gin(in_mat1), gout(out_norm), getCompileArgs());
683 
684     // Comparison //////////////////////////////////////////////////////////////
685     {
686         EXPECT_TRUE(cmpF(out_norm, out_norm_ocv));
687     }
688 }
689 
TEST_P(IntegralTest,AccuracyTest)690 TEST_P(IntegralTest, AccuracyTest)
691 {
692     int type_out = (type == CV_8U) ? CV_32SC1 : CV_64FC1;
693     in_mat1 = cv::Mat(sz, type);
694 
695     cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
696 
697     cv::Size sz_out = cv::Size(sz.width + 1, sz.height + 1);
698     cv::Mat out_mat1(sz_out, type_out);
699     cv::Mat out_mat_ocv1(sz_out, type_out);
700 
701     cv::Mat out_mat2(sz_out, CV_64FC1);
702     cv::Mat out_mat_ocv2(sz_out, CV_64FC1);
703 
704     // G-API code //////////////////////////////////////////////////////////////
705     cv::GMat in1, out1, out2;
706     std::tie(out1, out2)  = cv::gapi::integral(in1, type_out, CV_64FC1);
707     cv::GComputation c(cv::GIn(in1), cv::GOut(out1, out2));
708 
709     c.apply(cv::gin(in_mat1), cv::gout(out_mat1, out_mat2), getCompileArgs());
710 
711     // OpenCV code /////////////////////////////////////////////////////////////
712     {
713         cv::integral(in_mat1, out_mat_ocv1, out_mat_ocv2);
714     }
715     // Comparison //////////////////////////////////////////////////////////////
716     {
717         EXPECT_EQ(0, cvtest::norm(out_mat_ocv1, out_mat1, NORM_INF));
718         EXPECT_EQ(0, cvtest::norm(out_mat_ocv2, out_mat2, NORM_INF));
719     }
720 }
721 
TEST_P(ThresholdTest,AccuracyTestBinary)722 TEST_P(ThresholdTest, AccuracyTestBinary)
723 {
724     cv::Scalar thr = initScalarRandU(50);
725     cv::Scalar out_scalar;
726 
727     // G-API code //////////////////////////////////////////////////////////////
728     cv::GMat in1, out;
729     cv::GScalar th1, mv1;
730     out = cv::gapi::threshold(in1, th1, mv1, tt);
731     cv::GComputation c(GIn(in1, th1, mv1), GOut(out));
732 
733     c.apply(gin(in_mat1, thr, maxval), gout(out_mat_gapi), getCompileArgs());
734 
735     // OpenCV code /////////////////////////////////////////////////////////////
736     {
737         cv::threshold(in_mat1, out_mat_ocv, thr.val[0], maxval.val[0], tt);
738     }
739     // Comparison //////////////////////////////////////////////////////////////
740     {
741         ASSERT_EQ(out_mat_gapi.size(), sz);
742         EXPECT_EQ(0, cv::norm(out_mat_ocv, out_mat_gapi, NORM_L1));
743     }
744 }
745 
TEST_P(ThresholdOTTest,AccuracyTestOtsu)746 TEST_P(ThresholdOTTest, AccuracyTestOtsu)
747 {
748     cv::Scalar maxval = initScalarRandU(50) + cv::Scalar(50, 50, 50, 50);
749     cv::Scalar out_gapi_scalar;
750     double ocv_res;
751 
752     // G-API code //////////////////////////////////////////////////////////////
753     cv::GMat in1, out;
754     cv::GScalar mv1, scout;
755     std::tie<cv::GMat, cv::GScalar>(out, scout) = cv::gapi::threshold(in1, mv1, tt);
756     cv::GComputation c(cv::GIn(in1, mv1), cv::GOut(out, scout));
757 
758     c.apply(gin(in_mat1, maxval), gout(out_mat_gapi, out_gapi_scalar), getCompileArgs());
759 
760     // OpenCV code /////////////////////////////////////////////////////////////
761     {
762         ocv_res = cv::threshold(in_mat1, out_mat_ocv, maxval.val[0], maxval.val[0], tt);
763     }
764     // Comparison //////////////////////////////////////////////////////////////
765     {
766         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
767         EXPECT_EQ(out_mat_gapi.size(), sz);
768         EXPECT_EQ(ocv_res, out_gapi_scalar.val[0]);
769     }
770 }
771 
TEST_P(InRangeTest,AccuracyTest)772 TEST_P(InRangeTest, AccuracyTest)
773 {
774     cv::Scalar thrLow = initScalarRandU(100);
775     cv::Scalar thrUp = initScalarRandU(100) + cv::Scalar(100, 100, 100, 100);
776 
777     // G-API code //////////////////////////////////////////////////////////////
778     cv::GMat in1;
779     cv::GScalar th1, mv1;
780     auto out = cv::gapi::inRange(in1, th1, mv1);
781     cv::GComputation c(GIn(in1, th1, mv1), GOut(out));
782 
783     c.apply(gin(in_mat1, thrLow, thrUp), gout(out_mat_gapi), getCompileArgs());
784 
785     // OpenCV code /////////////////////////////////////////////////////////////
786     {
787         cv::inRange(in_mat1, thrLow, thrUp, out_mat_ocv);
788     }
789     // Comparison //////////////////////////////////////////////////////////////
790     {
791         ASSERT_EQ(out_mat_gapi.size(), sz);
792         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
793     }
794 }
795 
TEST_P(Split3Test,AccuracyTest)796 TEST_P(Split3Test, AccuracyTest)
797 {
798     cv::Mat out_mat2 = cv::Mat(sz, dtype);
799     cv::Mat out_mat3 = cv::Mat(sz, dtype);
800     cv::Mat out_mat_ocv2 = cv::Mat(sz, dtype);
801     cv::Mat out_mat_ocv3 = cv::Mat(sz, dtype);
802     // G-API code //////////////////////////////////////////////////////////////
803     cv::GMat in1, out1, out2, out3;
804     std::tie(out1, out2, out3)  = cv::gapi::split3(in1);
805     cv::GComputation c(cv::GIn(in1), cv::GOut(out1, out2, out3));
806 
807     c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi, out_mat2, out_mat3), getCompileArgs());
808     // OpenCV code /////////////////////////////////////////////////////////////
809     {
810         std::vector<cv::Mat> out_mats_ocv = {out_mat_ocv, out_mat_ocv2, out_mat_ocv3};
811         cv::split(in_mat1, out_mats_ocv);
812     }
813     // Comparison //////////////////////////////////////////////////////////////
814     {
815         EXPECT_EQ(0, cvtest::norm(out_mat_ocv,  out_mat_gapi, NORM_INF));
816         EXPECT_EQ(0, cvtest::norm(out_mat_ocv2, out_mat2, NORM_INF));
817         EXPECT_EQ(0, cvtest::norm(out_mat_ocv3, out_mat3, NORM_INF));
818     }
819 }
820 
TEST_P(Split4Test,AccuracyTest)821 TEST_P(Split4Test, AccuracyTest)
822 {
823     cv::Mat out_mat2 = cv::Mat(sz, dtype);
824     cv::Mat out_mat3 = cv::Mat(sz, dtype);
825     cv::Mat out_mat4 = cv::Mat(sz, dtype);
826     cv::Mat out_mat_ocv2 = cv::Mat(sz, dtype);
827     cv::Mat out_mat_ocv3 = cv::Mat(sz, dtype);
828     cv::Mat out_mat_ocv4 = cv::Mat(sz, dtype);
829 
830     // G-API code //////////////////////////////////////////////////////////////
831     cv::GMat in1, out1, out2, out3, out4;
832     std::tie(out1, out2, out3, out4)  = cv::gapi::split4(in1);
833     cv::GComputation c(cv::GIn(in1), cv::GOut(out1, out2, out3, out4));
834 
835     c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi, out_mat2, out_mat3, out_mat4), getCompileArgs());
836     // OpenCV code /////////////////////////////////////////////////////////////
837     {
838         std::vector<cv::Mat> out_mats_ocv = {out_mat_ocv, out_mat_ocv2, out_mat_ocv3, out_mat_ocv4};
839         cv::split(in_mat1, out_mats_ocv);
840     }
841     // Comparison //////////////////////////////////////////////////////////////
842     {
843         EXPECT_EQ(0, cvtest::norm(out_mat_ocv,  out_mat_gapi, NORM_INF));
844         EXPECT_EQ(0, cvtest::norm(out_mat_ocv2, out_mat2, NORM_INF));
845         EXPECT_EQ(0, cvtest::norm(out_mat_ocv3, out_mat3, NORM_INF));
846         EXPECT_EQ(0, cvtest::norm(out_mat_ocv4, out_mat4, NORM_INF));
847     }
848 }
849 
ResizeAccuracyTest(const CompareMats & cmpF,int type,int interp,cv::Size sz_in,cv::Size sz_out,double fx,double fy,cv::GCompileArgs && compile_args)850 static void ResizeAccuracyTest(const CompareMats& cmpF, int type, int interp, cv::Size sz_in,
851     cv::Size sz_out, double fx, double fy, cv::GCompileArgs&& compile_args)
852 {
853     cv::Mat in_mat1 (sz_in, type );
854     cv::Scalar mean = cv::Scalar::all(127);
855     cv::Scalar stddev = cv::Scalar::all(40.f);
856 
857     cv::randn(in_mat1, mean, stddev);
858 
859     auto out_mat_sz = sz_out.area() == 0 ? cv::Size(saturate_cast<int>(sz_in.width *fx),
860                                                     saturate_cast<int>(sz_in.height*fy))
861                                          : sz_out;
862     cv::Mat out_mat(out_mat_sz, type);
863     cv::Mat out_mat_ocv(out_mat_sz, type);
864 
865     // G-API code //////////////////////////////////////////////////////////////
866     cv::GMat in;
867     auto out = cv::gapi::resize(in, sz_out, fx, fy, interp);
868 
869     cv::GComputation c(in, out);
870     c.apply(in_mat1, out_mat, std::move(compile_args));
871     // OpenCV code /////////////////////////////////////////////////////////////
872     {
873         cv::resize(in_mat1, out_mat_ocv, sz_out, fx, fy, interp);
874     }
875     // Comparison //////////////////////////////////////////////////////////////
876     {
877         EXPECT_TRUE(cmpF(out_mat, out_mat_ocv));
878     }
879 }
880 
TEST_P(ResizeTest,AccuracyTest)881 TEST_P(ResizeTest, AccuracyTest)
882 {
883     ResizeAccuracyTest(cmpF, type, interp, sz, sz_out, 0.0, 0.0, getCompileArgs());
884 }
885 
TEST_P(ResizeTestFxFy,AccuracyTest)886 TEST_P(ResizeTestFxFy, AccuracyTest)
887 {
888     ResizeAccuracyTest(cmpF, type, interp, sz, cv::Size{0, 0}, fx, fy, getCompileArgs());
889 }
890 
TEST_P(ResizePTest,AccuracyTest)891 TEST_P(ResizePTest, AccuracyTest)
892 {
893     constexpr int planeNum = 3;
894     cv::Size sz_in_p {sz.width,  sz.height*planeNum};
895     cv::Size sz_out_p{sz_out.width, sz_out.height*planeNum};
896 
897     cv::Mat in_mat(sz_in_p, CV_8UC1);
898     cv::randn(in_mat, cv::Scalar::all(127.0f), cv::Scalar::all(40.f));
899 
900     cv::Mat out_mat    (sz_out_p, CV_8UC1);
901     cv::Mat out_mat_ocv_p(sz_out_p, CV_8UC1);
902 
903     cv::GMatP in;
904     auto out = cv::gapi::resizeP(in, sz_out, interp);
905     cv::GComputation c(cv::GIn(in), cv::GOut(out));
906 
907     c.compile(cv::descr_of(in_mat).asPlanar(planeNum), getCompileArgs())
908              (cv::gin(in_mat), cv::gout(out_mat));
909 
910     for (int i = 0; i < planeNum; i++) {
911         const cv::Mat in_mat_roi = in_mat(cv::Rect(0, i*sz.height,  sz.width,  sz.height));
912         cv::Mat out_mat_roi = out_mat_ocv_p(cv::Rect(0, i*sz_out.height, sz_out.width, sz_out.height));
913         cv::resize(in_mat_roi, out_mat_roi, sz_out, 0, 0, interp);
914     }
915 
916     // Comparison //////////////////////////////////////////////////////////////
917     {
918         EXPECT_TRUE(cmpF(out_mat, out_mat_ocv_p));
919     }
920 }
921 
TEST_P(Merge3Test,AccuracyTest)922 TEST_P(Merge3Test, AccuracyTest)
923 {
924     cv::Mat in_mat3(sz, type);
925     cv::Scalar mean = cv::Scalar::all(127);
926     cv::Scalar stddev = cv::Scalar::all(40.f);
927 
928     cv::randn(in_mat3, mean, stddev);
929 
930     // G-API code //////////////////////////////////////////////////////////////
931     cv::GMat in1, in2, in3;
932     auto out = cv::gapi::merge3(in1, in2, in3);
933 
934     cv::GComputation c(cv::GIn(in1, in2, in3), cv::GOut(out));
935     c.apply(cv::gin(in_mat1, in_mat2, in_mat3), cv::gout(out_mat_gapi), getCompileArgs());
936     // OpenCV code /////////////////////////////////////////////////////////////
937     {
938         std::vector<cv::Mat> in_mats_ocv = {in_mat1, in_mat2, in_mat3};
939         cv::merge(in_mats_ocv, out_mat_ocv);
940     }
941     // Comparison //////////////////////////////////////////////////////////////
942     {
943         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
944     }
945 }
946 
TEST_P(Merge4Test,AccuracyTest)947 TEST_P(Merge4Test, AccuracyTest)
948 {
949     cv::Mat in_mat3(sz, type);
950     cv::Mat in_mat4(sz, type);
951     cv::Scalar mean = cv::Scalar::all(127);
952     cv::Scalar stddev = cv::Scalar::all(40.f);
953 
954     cv::randn(in_mat3, mean, stddev);
955     cv::randn(in_mat4, mean, stddev);
956 
957     // G-API code //////////////////////////////////////////////////////////////
958     cv::GMat in1, in2, in3, in4;
959     auto out = cv::gapi::merge4(in1, in2, in3, in4);
960 
961     cv::GComputation c(cv::GIn(in1, in2, in3, in4), cv::GOut(out));
962     c.apply(cv::gin(in_mat1, in_mat2, in_mat3, in_mat4), cv::gout(out_mat_gapi), getCompileArgs());
963     // OpenCV code /////////////////////////////////////////////////////////////
964     {
965         std::vector<cv::Mat> in_mats_ocv = {in_mat1, in_mat2, in_mat3, in_mat4};
966         cv::merge(in_mats_ocv, out_mat_ocv);
967     }
968     // Comparison //////////////////////////////////////////////////////////////
969     {
970         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
971     }
972 }
973 
TEST_P(RemapTest,AccuracyTest)974 TEST_P(RemapTest, AccuracyTest)
975 {
976     cv::Mat in_map1(sz, CV_16SC2);
977     cv::Mat in_map2 = cv::Mat();
978     cv::randu(in_map1, cv::Scalar::all(0), cv::Scalar::all(255));
979     cv::Scalar bv = cv::Scalar();
980 
981     // G-API code //////////////////////////////////////////////////////////////
982     cv::GMat in1;
983     auto out = cv::gapi::remap(in1, in_map1, in_map2, cv::INTER_NEAREST,  cv::BORDER_REPLICATE, bv);
984     cv::GComputation c(in1, out);
985 
986     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
987 
988     // OpenCV code /////////////////////////////////////////////////////////////
989     {
990         cv::remap(in_mat1, out_mat_ocv, in_map1, in_map2, cv::INTER_NEAREST, cv::BORDER_REPLICATE, bv);
991     }
992     // Comparison //////////////////////////////////////////////////////////////
993     {
994         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
995         EXPECT_EQ(out_mat_gapi.size(), sz);
996     }
997 }
998 
TEST_P(FlipTest,AccuracyTest)999 TEST_P(FlipTest, AccuracyTest)
1000 {
1001     // G-API code //////////////////////////////////////////////////////////////
1002     cv::GMat in;
1003     auto out = cv::gapi::flip(in, flipCode);
1004 
1005     cv::GComputation c(in, out);
1006     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1007     // OpenCV code /////////////////////////////////////////////////////////////
1008     {
1009         cv::flip(in_mat1, out_mat_ocv, flipCode);
1010     }
1011     // Comparison //////////////////////////////////////////////////////////////
1012     {
1013         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1014         EXPECT_EQ(out_mat_gapi.size(), sz);
1015     }
1016 }
1017 
TEST_P(CropTest,AccuracyTest)1018 TEST_P(CropTest, AccuracyTest)
1019 {
1020     cv::Size sz_out = cv::Size(rect_to.width, rect_to.height);
1021     if (dtype != -1)
1022     {
1023         out_mat_gapi = cv::Mat(sz_out, dtype);
1024         out_mat_ocv = cv::Mat(sz_out, dtype);
1025     }
1026 
1027     // G-API code //////////////////////////////////////////////////////////////
1028     cv::GMat in;
1029     auto out = cv::gapi::crop(in, rect_to);
1030 
1031     cv::GComputation c(in, out);
1032     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1033     // OpenCV code /////////////////////////////////////////////////////////////
1034     {
1035         cv::Mat(in_mat1, rect_to).copyTo(out_mat_ocv);
1036     }
1037     // Comparison //////////////////////////////////////////////////////////////
1038     {
1039         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1040         EXPECT_EQ(out_mat_gapi.size(), sz_out);
1041     }
1042 }
1043 
TEST_P(CopyTest,AccuracyTest)1044 TEST_P(CopyTest, AccuracyTest)
1045 {
1046     cv::Size sz_out = sz;
1047     if (dtype != -1)
1048     {
1049         out_mat_gapi = cv::Mat(sz_out, dtype);
1050         out_mat_ocv = cv::Mat(sz_out, dtype);
1051     }
1052 
1053     // G-API code //////////////////////////////////////////////////////////////
1054     cv::GMat in;
1055     auto out = cv::gapi::copy(in);
1056 
1057     cv::GComputation c(in, out);
1058     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1059     // OpenCV code /////////////////////////////////////////////////////////////
1060     {
1061         cv::Mat(in_mat1).copyTo(out_mat_ocv);
1062     }
1063     // Comparison //////////////////////////////////////////////////////////////
1064     {
1065         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1066         EXPECT_EQ(out_mat_gapi.size(), sz_out);
1067     }
1068 }
1069 
TEST_P(ConcatHorTest,AccuracyTest)1070 TEST_P(ConcatHorTest, AccuracyTest)
1071 {
1072     cv::Size sz_out = sz;
1073 
1074     int wpart = sz_out.width / 4;
1075     cv::Size sz_in1 = cv::Size(wpart, sz_out.height);
1076     cv::Size sz_in2 = cv::Size(sz_out.width - wpart, sz_out.height);
1077 
1078     in_mat1 = cv::Mat(sz_in1, type );
1079     in_mat2 = cv::Mat(sz_in2, type);
1080     cv::Scalar mean = cv::Scalar::all(127);
1081     cv::Scalar stddev = cv::Scalar::all(40.f);
1082 
1083     cv::randn(in_mat1, mean, stddev);
1084     cv::randn(in_mat2, mean, stddev);
1085 
1086     cv::Mat out_mat(sz_out, type);
1087     out_mat_ocv = cv::Mat(sz_out, type);
1088 
1089     // G-API code //////////////////////////////////////////////////////////////
1090     cv::GMat in1, in2;
1091     auto out = cv::gapi::concatHor(in1, in2);
1092 
1093     cv::GComputation c(GIn(in1, in2), GOut(out));
1094     c.apply(gin(in_mat1, in_mat2), gout(out_mat), getCompileArgs());
1095     // OpenCV code /////////////////////////////////////////////////////////////
1096     {
1097         cv::hconcat(in_mat1, in_mat2, out_mat_ocv);
1098     }
1099     // Comparison //////////////////////////////////////////////////////////////
1100     {
1101         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat, NORM_INF));
1102     }
1103 }
1104 
TEST_P(ConcatVertTest,AccuracyTest)1105 TEST_P(ConcatVertTest, AccuracyTest)
1106 {
1107     cv::Size sz_out = sz;
1108 
1109     int hpart = sz_out.height * 2/3;
1110     cv::Size sz_in1 = cv::Size(sz_out.width, hpart);
1111     cv::Size sz_in2 = cv::Size(sz_out.width, sz_out.height - hpart);
1112 
1113     in_mat1 = cv::Mat(sz_in1, type);
1114     in_mat2 = cv::Mat(sz_in2, type);
1115     cv::Scalar mean = cv::Scalar::all(127);
1116     cv::Scalar stddev = cv::Scalar::all(40.f);
1117 
1118     cv::randn(in_mat1, mean, stddev);
1119     cv::randn(in_mat2, mean, stddev);
1120 
1121     cv::Mat out_mat(sz_out, type);
1122     out_mat_ocv = cv::Mat(sz_out, type);
1123 
1124     // G-API code //////////////////////////////////////////////////////////////
1125     cv::GMat in1, in2;
1126     auto out = cv::gapi::concatVert(in1, in2);
1127 
1128     cv::GComputation c(GIn(in1, in2), GOut(out));
1129     c.apply(gin(in_mat1, in_mat2), gout(out_mat), getCompileArgs());
1130     // OpenCV code /////////////////////////////////////////////////////////////
1131     {
1132         cv::vconcat(in_mat1, in_mat2, out_mat_ocv );
1133     }
1134     // Comparison //////////////////////////////////////////////////////////////
1135     {
1136         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat, NORM_INF));
1137     }
1138 }
1139 
TEST_P(ConcatVertVecTest,AccuracyTest)1140 TEST_P(ConcatVertVecTest, AccuracyTest)
1141 {
1142     cv::Size sz_out = sz;
1143 
1144     int hpart1 = sz_out.height * 2/5;
1145     int hpart2 = sz_out.height / 5;
1146     cv::Size sz_in1 = cv::Size(sz_out.width, hpart1);
1147     cv::Size sz_in2 = cv::Size(sz_out.width, hpart2);
1148     cv::Size sz_in3 = cv::Size(sz_out.width, sz_out.height - hpart1 - hpart2);
1149 
1150     in_mat1 = cv::Mat(sz_in1, type);
1151     in_mat2 = cv::Mat(sz_in2, type);
1152     cv::Mat in_mat3(sz_in3, type);
1153     cv::Scalar mean = cv::Scalar::all(127);
1154     cv::Scalar stddev = cv::Scalar::all(40.f);
1155 
1156     cv::randn(in_mat1, mean, stddev);
1157     cv::randn(in_mat2, mean, stddev);
1158     cv::randn(in_mat3, mean, stddev);
1159 
1160     cv::Mat out_mat(sz_out, type);
1161     out_mat_ocv = cv::Mat(sz_out, type);
1162 
1163     // G-API code //////////////////////////////////////////////////////////////
1164     std::vector <cv::GMat> mats(3);
1165     auto out = cv::gapi::concatVert(mats);
1166 
1167     std::vector <cv::Mat> cvmats = {in_mat1, in_mat2, in_mat3};
1168 
1169     cv::GComputation c({mats[0], mats[1], mats[2]}, {out});
1170     c.apply(gin(in_mat1, in_mat2, in_mat3), gout(out_mat), getCompileArgs());
1171 
1172     // OpenCV code /////////////////////////////////////////////////////////////
1173     {
1174         cv::vconcat(cvmats, out_mat_ocv );
1175     }
1176     // Comparison //////////////////////////////////////////////////////////////
1177     {
1178         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat, NORM_INF));
1179     }
1180 }
1181 
TEST_P(ConcatHorVecTest,AccuracyTest)1182 TEST_P(ConcatHorVecTest, AccuracyTest)
1183 {
1184     cv::Size sz_out = sz;
1185 
1186     int wpart1 = sz_out.width / 3;
1187     int wpart2 = sz_out.width / 4;
1188     cv::Size sz_in1 = cv::Size(wpart1, sz_out.height);
1189     cv::Size sz_in2 = cv::Size(wpart2, sz_out.height);
1190     cv::Size sz_in3 = cv::Size(sz_out.width - wpart1 - wpart2, sz_out.height);
1191 
1192     in_mat1 = cv::Mat(sz_in1, type);
1193     in_mat2 = cv::Mat(sz_in2, type);
1194     cv::Mat in_mat3 (sz_in3, type);
1195     cv::Scalar mean = cv::Scalar::all(127);
1196     cv::Scalar stddev = cv::Scalar::all(40.f);
1197 
1198     cv::randn(in_mat1, mean, stddev);
1199     cv::randn(in_mat2, mean, stddev);
1200     cv::randn(in_mat3, mean, stddev);
1201 
1202     cv::Mat out_mat(sz_out, type);
1203     out_mat_ocv = cv::Mat(sz_out, type);
1204 
1205     // G-API code //////////////////////////////////////////////////////////////
1206     std::vector <cv::GMat> mats(3);
1207     auto out = cv::gapi::concatHor(mats);
1208 
1209     std::vector <cv::Mat> cvmats = {in_mat1, in_mat2, in_mat3};
1210 
1211     cv::GComputation c({mats[0], mats[1], mats[2]}, {out});
1212     c.apply(gin(in_mat1, in_mat2, in_mat3), gout(out_mat), getCompileArgs());
1213 
1214     // OpenCV code /////////////////////////////////////////////////////////////
1215     {
1216         cv::hconcat(cvmats, out_mat_ocv );
1217     }
1218     // Comparison //////////////////////////////////////////////////////////////
1219     {
1220         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat, NORM_INF));
1221     }
1222 }
1223 
TEST_P(LUTTest,AccuracyTest)1224 TEST_P(LUTTest, AccuracyTest)
1225 {
1226     int type_mat = type;
1227     int type_lut = dtype;
1228     int type_out = CV_MAKETYPE(CV_MAT_DEPTH(type_lut), CV_MAT_CN(type_mat));
1229 
1230     initMatrixRandU(type_mat, sz, type_out);
1231     cv::Size sz_lut = cv::Size(1, 256);
1232     cv::Mat in_lut(sz_lut, type_lut);
1233     cv::randu(in_lut, cv::Scalar::all(0), cv::Scalar::all(255));
1234 
1235     // G-API code //////////////////////////////////////////////////////////////
1236     cv::GMat in;
1237     auto out = cv::gapi::LUT(in, in_lut);
1238 
1239     cv::GComputation c(in, out);
1240     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1241     // OpenCV code /////////////////////////////////////////////////////////////
1242     {
1243         cv::LUT(in_mat1, in_lut, out_mat_ocv);
1244     }
1245     // Comparison //////////////////////////////////////////////////////////////
1246     {
1247         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1248         EXPECT_EQ(out_mat_gapi.size(), sz);
1249     }
1250 }
1251 
TEST_P(ConvertToTest,AccuracyTest)1252 TEST_P(ConvertToTest, AccuracyTest)
1253 {
1254     int type_mat = type;
1255     int depth_to = dtype;
1256     int type_out = CV_MAKETYPE(depth_to, CV_MAT_CN(type_mat));
1257     initMatrixRandU(type_mat, sz, type_out);
1258 
1259     // G-API code //////////////////////////////////////////////////////////////
1260     cv::GMat in;
1261     auto out = cv::gapi::convertTo(in, depth_to, alpha, beta);
1262 
1263     cv::GComputation c(in, out);
1264     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1265     // OpenCV code /////////////////////////////////////////////////////////////
1266     {
1267         in_mat1.convertTo(out_mat_ocv, depth_to, alpha, beta);
1268     }
1269     // Comparison //////////////////////////////////////////////////////////////
1270     {
1271         EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
1272         EXPECT_EQ(out_mat_gapi.size(), sz);
1273     }
1274 }
1275 
TEST_P(PhaseTest,AccuracyTest)1276 TEST_P(PhaseTest, AccuracyTest)
1277 {
1278     // G-API code //////////////////////////////////////////////////////////////
1279     cv::GMat in_x, in_y;
1280     auto out = cv::gapi::phase(in_x, in_y, angle_in_degrees);
1281 
1282     cv::GComputation c(in_x, in_y, out);
1283     c.apply(in_mat1, in_mat2, out_mat_gapi, getCompileArgs());
1284 
1285     // OpenCV code /////////////////////////////////////////////////////////////
1286     cv::phase(in_mat1, in_mat2, out_mat_ocv, angle_in_degrees);
1287 
1288     // Comparison //////////////////////////////////////////////////////////////
1289     // FIXME: use a comparison functor instead (after enabling OpenCL)
1290     {
1291 #if defined(__aarch64__) || defined(__arm__)
1292         EXPECT_NEAR(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF), 4e-6);
1293 #else
1294         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1295 #endif
1296     }
1297 }
1298 
TEST_P(SqrtTest,AccuracyTest)1299 TEST_P(SqrtTest, AccuracyTest)
1300 {
1301     // G-API code //////////////////////////////////////////////////////////////
1302     cv::GMat in;
1303     auto out = cv::gapi::sqrt(in);
1304 
1305     cv::GComputation c(in, out);
1306     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1307 
1308     // OpenCV code /////////////////////////////////////////////////////////////
1309     cv::sqrt(in_mat1, out_mat_ocv);
1310 
1311     // Comparison //////////////////////////////////////////////////////////////
1312     // FIXME: use a comparison functor instead (after enabling OpenCL)
1313     {
1314         EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
1315     }
1316 }
1317 
TEST_P(WarpPerspectiveTest,AccuracyTest)1318 TEST_P(WarpPerspectiveTest, AccuracyTest)
1319 {
1320     cv::Point center{in_mat1.size() / 2};
1321     cv::Mat xy = cv::getRotationMatrix2D(center, angle, scale);
1322     cv::Matx13d z (0, 0, 1);
1323     cv::Mat transform_mat;
1324     cv::vconcat(xy, z, transform_mat);
1325 
1326     // G-API code //////////////////////////////////////////////////////////////
1327     cv::GMat in;
1328     auto out = cv::gapi::warpPerspective(in, transform_mat, in_mat1.size(), flags, border_mode, border_value);
1329 
1330     cv::GComputation c(in, out);
1331     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1332 
1333     // OpenCV code /////////////////////////////////////////////////////////////
1334     cv::warpPerspective(in_mat1, out_mat_ocv, cv::Mat(transform_mat), in_mat1.size(), flags, border_mode, border_value);
1335 
1336     // Comparison //////////////////////////////////////////////////////////////
1337     {
1338         EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
1339     }
1340 }
1341 
TEST_P(WarpAffineTest,AccuracyTest)1342 TEST_P(WarpAffineTest, AccuracyTest)
1343 {
1344     cv::Point center{in_mat1.size() / 2};
1345     cv::Mat warp_mat = cv::getRotationMatrix2D(center, angle, scale);
1346 
1347     // G-API code //////////////////////////////////////////////////////////////
1348     cv::GMat in;
1349     auto out = cv::gapi::warpAffine(in, warp_mat, in_mat1.size(), flags, border_mode, border_value);
1350 
1351     cv::GComputation c(in, out);
1352     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1353 
1354     // OpenCV code /////////////////////////////////////////////////////////////
1355     cv::warpAffine(in_mat1, out_mat_ocv, warp_mat, in_mat1.size(), flags, border_mode, border_value);
1356 
1357     // Comparison //////////////////////////////////////////////////////////////
1358     {
1359         EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
1360     }
1361 }
1362 
TEST_P(NormalizeTest,Test)1363 TEST_P(NormalizeTest, Test)
1364 {
1365     initMatrixRandN(type, sz, CV_MAKETYPE(ddepth, CV_MAT_CN(type)));
1366 
1367     // G-API code //////////////////////////////////////////////////////////////
1368     cv::GMat in;
1369     auto out = cv::gapi::normalize(in, a, b, norm_type, ddepth);
1370 
1371     cv::GComputation c(cv::GIn(in), cv::GOut(out));
1372     c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi), getCompileArgs());
1373 
1374     // OpenCV code /////////////////////////////////////////////////////////////
1375     {
1376         cv::normalize(in_mat1, out_mat_ocv, a, b, norm_type, ddepth);
1377     }
1378     // Comparison //////////////////////////////////////////////////////////////
1379     {
1380         EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
1381         EXPECT_EQ(out_mat_gapi.size(), sz);
1382     }
1383 }
1384 
TEST_P(KMeansNDTest,AccuracyTest)1385 TEST_P(KMeansNDTest, AccuracyTest)
1386 {
1387     kmeansTestBody(in_mat1, sz, type, K, flags, getCompileArgs(), cmpF);
1388 }
1389 
TEST_P(KMeans2DTest,AccuracyTest)1390 TEST_P(KMeans2DTest, AccuracyTest)
1391 {
1392     const int amount = sz.height;
1393     std::vector<cv::Point2f> in_vector{};
1394     initPointsVectorRandU(amount, in_vector);
1395     kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs());
1396 }
1397 
TEST_P(KMeans3DTest,AccuracyTest)1398 TEST_P(KMeans3DTest, AccuracyTest)
1399 {
1400     const int amount = sz.height;
1401     std::vector<cv::Point3f> in_vector{};
1402     initPointsVectorRandU(amount, in_vector);
1403     kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs());
1404 }
1405 
TEST_P(TransposeTest,Test)1406 TEST_P(TransposeTest, Test)
1407 {
1408     // G-API code //////////////////////////////////////////////////////////////
1409     cv::GMat in;
1410     auto out = cv::gapi::transpose(in);
1411 
1412     cv::GComputation c(in, out);
1413     c.apply(in_mat1, out_mat_gapi, getCompileArgs());
1414     // OpenCV code /////////////////////////////////////////////////////////////
1415     {
1416         cv::transpose(in_mat1, out_mat_ocv);
1417     }
1418     // Comparison //////////////////////////////////////////////////////////////
1419     {
1420         EXPECT_TRUE(cmpF(out_mat_ocv, out_mat_gapi));
1421     }
1422 }
1423 // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! //////////////////////
1424 
TEST_P(BackendOutputAllocationTest,EmptyOutput)1425 TEST_P(BackendOutputAllocationTest, EmptyOutput)
1426 {
1427     // G-API code //////////////////////////////////////////////////////////////
1428     cv::GMat in1, in2, out;
1429     out = cv::gapi::mul(in1, in2);
1430     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1431 
1432     EXPECT_TRUE(out_mat_gapi.empty());
1433     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1434     EXPECT_FALSE(out_mat_gapi.empty());
1435 
1436     // OpenCV code /////////////////////////////////////////////////////////////
1437     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1438 
1439     // Comparison //////////////////////////////////////////////////////////////
1440     // Expected: output is allocated to the needed size
1441     EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1442     EXPECT_EQ(sz, out_mat_gapi.size());
1443 }
1444 
TEST_P(BackendOutputAllocationTest,CorrectlyPreallocatedOutput)1445 TEST_P(BackendOutputAllocationTest, CorrectlyPreallocatedOutput)
1446 {
1447     out_mat_gapi = cv::Mat(sz, type);
1448     auto out_mat_gapi_ref = out_mat_gapi;  // shallow copy to ensure previous data is not deleted
1449 
1450     // G-API code //////////////////////////////////////////////////////////////
1451     cv::GMat in1, in2, out;
1452     out = cv::gapi::add(in1, in2);
1453     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1454     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1455 
1456     // OpenCV code /////////////////////////////////////////////////////////////
1457     cv::add(in_mat1, in_mat2, out_mat_ocv);
1458 
1459     // Comparison //////////////////////////////////////////////////////////////
1460     // Expected: output is not reallocated
1461     EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1462     EXPECT_EQ(sz, out_mat_gapi.size());
1463 
1464     EXPECT_EQ(out_mat_gapi_ref.data, out_mat_gapi.data);
1465 }
1466 
TEST_P(BackendOutputAllocationTest,IncorrectOutputMeta)1467 TEST_P(BackendOutputAllocationTest, IncorrectOutputMeta)
1468 {
1469     // G-API code //////////////////////////////////////////////////////////////
1470     cv::GMat in1, in2, out;
1471     out = cv::gapi::add(in1, in2);
1472     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1473 
1474     const auto run_and_compare = [&c, this] ()
1475     {
1476         auto out_mat_gapi_ref = out_mat_gapi; // shallow copy to ensure previous data is not deleted
1477 
1478         // G-API code //////////////////////////////////////////////////////////////
1479         c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1480 
1481         // OpenCV code /////////////////////////////////////////////////////////////
1482         cv::add(in_mat1, in_mat2, out_mat_ocv, cv::noArray());
1483 
1484         // Comparison //////////////////////////////////////////////////////////////
1485         // Expected: size is changed, type is changed, output is reallocated
1486         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1487         EXPECT_EQ(sz, out_mat_gapi.size());
1488         EXPECT_EQ(type, out_mat_gapi.type());
1489 
1490         EXPECT_NE(out_mat_gapi_ref.data, out_mat_gapi.data);
1491     };
1492 
1493     const auto chan = CV_MAT_CN(type);
1494 
1495     out_mat_gapi = cv::Mat(sz, CV_MAKE_TYPE(CV_64F, chan));
1496     run_and_compare();
1497 
1498     out_mat_gapi = cv::Mat(sz, CV_MAKE_TYPE(CV_MAT_DEPTH(type), chan + 1));
1499     run_and_compare();
1500 }
1501 
TEST_P(BackendOutputAllocationTest,SmallerPreallocatedSize)1502 TEST_P(BackendOutputAllocationTest, SmallerPreallocatedSize)
1503 {
1504     out_mat_gapi = cv::Mat(sz / 2, type);
1505     auto out_mat_gapi_ref = out_mat_gapi; // shallow copy to ensure previous data is not deleted
1506 
1507     // G-API code //////////////////////////////////////////////////////////////
1508     cv::GMat in1, in2, out;
1509     out = cv::gapi::mul(in1, in2);
1510     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1511     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1512 
1513     // OpenCV code /////////////////////////////////////////////////////////////
1514     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1515 
1516     // Comparison //////////////////////////////////////////////////////////////
1517     // Expected: size is changed, output is reallocated due to original size < curr size
1518     EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1519     EXPECT_EQ(sz, out_mat_gapi.size());
1520 
1521     EXPECT_NE(out_mat_gapi_ref.data, out_mat_gapi.data);
1522 }
1523 
TEST_P(BackendOutputAllocationTest,SmallerPreallocatedSizeWithSubmatrix)1524 TEST_P(BackendOutputAllocationTest, SmallerPreallocatedSizeWithSubmatrix)
1525 {
1526     out_mat_gapi = cv::Mat(sz / 2, type);
1527 
1528     cv::Mat out_mat_gapi_submat = out_mat_gapi(cv::Rect({10, 0}, sz / 5));
1529     EXPECT_EQ(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1530 
1531     auto out_mat_gapi_submat_ref = out_mat_gapi_submat; // shallow copy to ensure previous data is not deleted
1532 
1533     // G-API code //////////////////////////////////////////////////////////////
1534     cv::GMat in1, in2, out;
1535     out = cv::gapi::mul(in1, in2);
1536     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1537     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi_submat), getCompileArgs());
1538 
1539     // OpenCV code /////////////////////////////////////////////////////////////
1540     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1541 
1542     // Comparison //////////////////////////////////////////////////////////////
1543     // Expected: submatrix is reallocated and is "detached", original matrix is unchanged
1544     EXPECT_EQ(0, cvtest::norm(out_mat_gapi_submat, out_mat_ocv, NORM_INF));
1545     EXPECT_EQ(sz, out_mat_gapi_submat.size());
1546     EXPECT_EQ(sz / 2, out_mat_gapi.size());
1547 
1548     EXPECT_NE(out_mat_gapi_submat_ref.data, out_mat_gapi_submat.data);
1549     EXPECT_NE(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1550 }
1551 
TEST_P(BackendOutputAllocationTest,LargerPreallocatedSize)1552 TEST_P(BackendOutputAllocationTest, LargerPreallocatedSize)
1553 {
1554     out_mat_gapi = cv::Mat(sz * 2, type);
1555     auto out_mat_gapi_ref = out_mat_gapi; // shallow copy to ensure previous data is not deleted
1556 
1557     // G-API code //////////////////////////////////////////////////////////////
1558     cv::GMat in1, in2, out;
1559     out = cv::gapi::mul(in1, in2);
1560     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1561     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1562 
1563     // OpenCV code /////////////////////////////////////////////////////////////
1564     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1565 
1566     // Comparison //////////////////////////////////////////////////////////////
1567     // Expected: size is changed, output is reallocated
1568     EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1569     EXPECT_EQ(sz, out_mat_gapi.size());
1570 
1571     EXPECT_NE(out_mat_gapi_ref.data, out_mat_gapi.data);
1572 }
1573 
TEST_P(BackendOutputAllocationLargeSizeWithCorrectSubmatrixTest,LargerPreallocatedSizeWithCorrectSubmatrix)1574 TEST_P(BackendOutputAllocationLargeSizeWithCorrectSubmatrixTest,
1575     LargerPreallocatedSizeWithCorrectSubmatrix)
1576 {
1577     out_mat_gapi = cv::Mat(sz * 2, type);
1578     auto out_mat_gapi_ref = out_mat_gapi; // shallow copy to ensure previous data is not deleted
1579 
1580     cv::Mat out_mat_gapi_submat = out_mat_gapi(cv::Rect({5, 8}, sz));
1581     EXPECT_EQ(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1582 
1583     auto out_mat_gapi_submat_ref = out_mat_gapi_submat;
1584 
1585     // G-API code //////////////////////////////////////////////////////////////
1586     cv::GMat in1, in2, out;
1587     out = cv::gapi::mul(in1, in2);
1588     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1589     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi_submat), getCompileArgs());
1590 
1591     // OpenCV code /////////////////////////////////////////////////////////////
1592     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1593 
1594     // Comparison //////////////////////////////////////////////////////////////
1595     // Expected: submatrix is not reallocated, original matrix is not reallocated
1596     EXPECT_EQ(0, cvtest::norm(out_mat_gapi_submat, out_mat_ocv, NORM_INF));
1597     EXPECT_EQ(sz, out_mat_gapi_submat.size());
1598     EXPECT_EQ(sz * 2, out_mat_gapi.size());
1599 
1600     EXPECT_EQ(out_mat_gapi_ref.data, out_mat_gapi.data);
1601     EXPECT_EQ(out_mat_gapi_submat_ref.data, out_mat_gapi_submat.data);
1602     EXPECT_EQ(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1603 }
1604 
TEST_P(BackendOutputAllocationTest,LargerPreallocatedSizeWithSmallSubmatrix)1605 TEST_P(BackendOutputAllocationTest, LargerPreallocatedSizeWithSmallSubmatrix)
1606 {
1607     out_mat_gapi = cv::Mat(sz * 2, type);
1608     auto out_mat_gapi_ref = out_mat_gapi; // shallow copy to ensure previous data is not deleted
1609 
1610     cv::Mat out_mat_gapi_submat = out_mat_gapi(cv::Rect({5, 8}, sz / 2));
1611     EXPECT_EQ(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1612 
1613     auto out_mat_gapi_submat_ref = out_mat_gapi_submat;
1614 
1615     // G-API code //////////////////////////////////////////////////////////////
1616     cv::GMat in1, in2, out;
1617     out = cv::gapi::mul(in1, in2);
1618     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1619     c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi_submat), getCompileArgs());
1620 
1621     // OpenCV code /////////////////////////////////////////////////////////////
1622     cv::multiply(in_mat1, in_mat2, out_mat_ocv);
1623 
1624     // Comparison //////////////////////////////////////////////////////////////
1625     // Expected: submatrix is reallocated and is "detached", original matrix is unchanged
1626     EXPECT_EQ(0, cvtest::norm(out_mat_gapi_submat, out_mat_ocv, NORM_INF));
1627     EXPECT_EQ(sz, out_mat_gapi_submat.size());
1628     EXPECT_EQ(sz * 2, out_mat_gapi.size());
1629 
1630     EXPECT_EQ(out_mat_gapi_ref.data, out_mat_gapi.data);
1631     EXPECT_NE(out_mat_gapi_submat_ref.data, out_mat_gapi_submat.data);
1632     EXPECT_NE(out_mat_gapi.data, out_mat_gapi_submat.datastart);
1633 }
1634 
TEST_P(ReInitOutTest,TestWithAdd)1635 TEST_P(ReInitOutTest, TestWithAdd)
1636 {
1637     in_mat1 = cv::Mat(sz, type);
1638     in_mat2 = cv::Mat(sz, type);
1639     cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(100));
1640     cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(100));
1641 
1642     // G-API code //////////////////////////////////////////////////////////////
1643     cv::GMat in1, in2, out;
1644     out = cv::gapi::add(in1, in2, dtype);
1645     cv::GComputation c(cv::GIn(in1, in2), cv::GOut(out));
1646 
1647     const auto run_and_compare = [&c, this] ()
1648     {
1649         // G-API code //////////////////////////////////////////////////////////////
1650         c.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi), getCompileArgs());
1651 
1652         // OpenCV code /////////////////////////////////////////////////////////////
1653         cv::add(in_mat1, in_mat2, out_mat_ocv, cv::noArray());
1654 
1655         // Comparison //////////////////////////////////////////////////////////////
1656         EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
1657         EXPECT_EQ(out_mat_gapi.size(), sz);
1658     };
1659 
1660     // run for uninitialized output
1661     run_and_compare();
1662 
1663     // run for initialized output (can be initialized with a different size)
1664     initOutMats(out_sz, type);
1665     run_and_compare();
1666 }
1667 
TEST_P(ParseSSDBLTest,ParseTest)1668 TEST_P(ParseSSDBLTest, ParseTest)
1669 {
1670     cv::Mat in_mat = generateSSDoutput(sz);
1671     std::vector<cv::Rect> boxes_gapi, boxes_ref;
1672     std::vector<int> labels_gapi, labels_ref;
1673 
1674     // G-API code //////////////////////////////////////////////////////////////
1675     cv::GMat in;
1676     cv::GOpaque<cv::Size> op_sz;
1677     auto out = cv::gapi::parseSSD(in, op_sz, confidence_threshold, filter_label);
1678     cv::GComputation c(cv::GIn(in, op_sz), cv::GOut(std::get<0>(out), std::get<1>(out)));
1679     c.apply(cv::gin(in_mat, sz), cv::gout(boxes_gapi, labels_gapi), getCompileArgs());
1680 
1681     // Reference code //////////////////////////////////////////////////////////
1682     parseSSDBLref(in_mat, sz, confidence_threshold, filter_label, boxes_ref, labels_ref);
1683 
1684     // Comparison //////////////////////////////////////////////////////////////
1685     EXPECT_TRUE(boxes_gapi == boxes_ref);
1686     EXPECT_TRUE(labels_gapi == labels_ref);
1687 }
1688 
TEST_P(ParseSSDTest,ParseTest)1689 TEST_P(ParseSSDTest, ParseTest)
1690 {
1691     cv::Mat in_mat = generateSSDoutput(sz);
1692     std::vector<cv::Rect> boxes_gapi, boxes_ref;
1693 
1694     // G-API code //////////////////////////////////////////////////////////////
1695     cv::GMat in;
1696     cv::GOpaque<cv::Size> op_sz;
1697     auto out = cv::gapi::parseSSD(in, op_sz, confidence_threshold,
1698                                   alignment_to_square, filter_out_of_bounds);
1699     cv::GComputation c(cv::GIn(in, op_sz), cv::GOut(out));
1700     c.apply(cv::gin(in_mat, sz), cv::gout(boxes_gapi), getCompileArgs());
1701 
1702     // Reference code //////////////////////////////////////////////////////////
1703     parseSSDref(in_mat, sz, confidence_threshold, alignment_to_square,
1704                 filter_out_of_bounds, boxes_ref);
1705 
1706     // Comparison //////////////////////////////////////////////////////////////
1707     EXPECT_TRUE(boxes_gapi == boxes_ref);
1708 }
1709 
TEST_P(ParseYoloTest,ParseTest)1710 TEST_P(ParseYoloTest, ParseTest)
1711 {
1712     cv::Mat in_mat = generateYoloOutput(num_classes, dims_config);
1713     auto anchors = cv::gapi::nn::parsers::GParseYolo::defaultAnchors();
1714     std::vector<cv::Rect> boxes_gapi, boxes_ref;
1715     std::vector<int> labels_gapi, labels_ref;
1716 
1717     // G-API code //////////////////////////////////////////////////////////////
1718     cv::GMat in;
1719     cv::GOpaque<cv::Size> op_sz;
1720     auto out = cv::gapi::parseYolo(in, op_sz, confidence_threshold, nms_threshold, anchors);
1721     cv::GComputation c(cv::GIn(in, op_sz), cv::GOut(std::get<0>(out), std::get<1>(out)));
1722     c.apply(cv::gin(in_mat, sz), cv::gout(boxes_gapi, labels_gapi), getCompileArgs());
1723 
1724     // Reference code //////////////////////////////////////////////////////////
1725     parseYoloRef(in_mat, sz, confidence_threshold, nms_threshold, num_classes, anchors, boxes_ref, labels_ref);
1726 
1727     // Comparison //////////////////////////////////////////////////////////////
1728     EXPECT_TRUE(boxes_gapi == boxes_ref);
1729     EXPECT_TRUE(labels_gapi == labels_ref);
1730 }
1731 
TEST_P(SizeTest,ParseTest)1732 TEST_P(SizeTest, ParseTest)
1733 {
1734     cv::GMat in;
1735     cv::Size out_sz;
1736 
1737     auto out = cv::gapi::streaming::size(in);
1738     cv::GComputation c(cv::GIn(in), cv::GOut(out));
1739     c.apply(cv::gin(in_mat1), cv::gout(out_sz), getCompileArgs());
1740 
1741     EXPECT_EQ(out_sz, sz);
1742 }
1743 
TEST_P(SizeRTest,ParseTest)1744 TEST_P(SizeRTest, ParseTest)
1745 {
1746     cv::Rect rect(cv::Point(0,0), sz);
1747     cv::Size out_sz;
1748 
1749     cv::GOpaque<cv::Rect> op_rect;
1750     auto out = cv::gapi::streaming::size(op_rect);
1751     cv::GComputation c(cv::GIn(op_rect), cv::GOut(out));
1752     c.apply(cv::gin(rect), cv::gout(out_sz), getCompileArgs());
1753 
1754     EXPECT_EQ(out_sz, sz);
1755 }
1756 
1757 namespace {
1758     class TestMediaBGR final : public cv::MediaFrame::IAdapter {
1759         cv::Mat m_mat;
1760 
1761     public:
TestMediaBGR(cv::Mat m)1762         explicit TestMediaBGR(cv::Mat m)
1763             : m_mat(m) {
1764         }
meta() const1765         cv::GFrameDesc meta() const override {
1766             return cv::GFrameDesc{ cv::MediaFormat::BGR, cv::Size(m_mat.cols, m_mat.rows) };
1767         }
access(cv::MediaFrame::Access)1768         cv::MediaFrame::View access(cv::MediaFrame::Access) override {
1769             cv::MediaFrame::View::Ptrs pp = { m_mat.ptr(), nullptr, nullptr, nullptr };
1770             cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u };
1771             return cv::MediaFrame::View(std::move(pp), std::move(ss));
1772         }
1773     };
1774 };
1775 
TEST_P(SizeMFTest,ParseTest)1776 TEST_P(SizeMFTest, ParseTest)
1777 {
1778     cv::Size out_sz;
1779     cv::Mat bgr = cv::Mat::eye(sz.height, sz.width, CV_8UC3);
1780     cv::MediaFrame frame = cv::MediaFrame::Create<TestMediaBGR>(bgr);
1781 
1782     cv::GFrame in;
1783     auto out = cv::gapi::streaming::size(in);
1784     cv::GComputation c(cv::GIn(in), cv::GOut(out));
1785     c.apply(cv::gin(frame), cv::gout(out_sz), getCompileArgs());
1786 
1787     EXPECT_EQ(out_sz, sz);
1788 }
1789 
1790 } // opencv_test
1791 
1792 #endif //OPENCV_GAPI_CORE_TESTS_INL_HPP
1793