Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / test / common / gapi_tests_common.hpp
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-2019 Intel Corporation
6
7
8 #include <iostream>
9
10 #include "opencv2/ts.hpp"
11 #include "opencv2/gapi.hpp"
12
13 namespace
14 {
15     inline std::ostream& operator<<(std::ostream& o, const cv::GCompileArg& arg)
16     {
17         return o << (arg.tag.empty() ? "empty" : arg.tag);
18     }
19 }
20
21 namespace opencv_test
22 {
23
24 class TestFunctional
25 {
26 public:
27     cv::Mat in_mat1;
28     cv::Mat in_mat2;
29     cv::Mat out_mat_gapi;
30     cv::Mat out_mat_ocv;
31
32     cv::Scalar sc;
33
34     cv::Scalar initScalarRandU(unsigned upper)
35     {
36         auto& rng = cv::theRNG();
37         double s1 = rng(upper);
38         double s2 = rng(upper);
39         double s3 = rng(upper);
40         double s4 = rng(upper);
41         return cv::Scalar(s1, s2, s3, s4);
42     }
43
44     void initMatsRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
45     {
46         in_mat1 = cv::Mat(sz_in, type);
47         in_mat2 = cv::Mat(sz_in, type);
48
49         sc = initScalarRandU(100);
50         cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
51         cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
52
53         if (createOutputMatrices && dtype != -1)
54         {
55             out_mat_gapi = cv::Mat (sz_in, dtype);
56             out_mat_ocv = cv::Mat (sz_in, dtype);
57         }
58     }
59
60     void initMatrixRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
61     {
62         in_mat1 = cv::Mat(sz_in, type);
63
64         sc = initScalarRandU(100);
65
66         cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
67
68         if (createOutputMatrices && dtype != -1)
69         {
70             out_mat_gapi = cv::Mat (sz_in, dtype);
71             out_mat_ocv = cv::Mat (sz_in, dtype);
72         }
73     }
74
75     void initMatsRandN(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
76     {
77         in_mat1  = cv::Mat(sz_in, type);
78         cv::randn(in_mat1, cv::Scalar::all(127), cv::Scalar::all(40.f));
79
80         if (createOutputMatrices  && dtype != -1)
81         {
82             out_mat_gapi = cv::Mat(sz_in, dtype);
83             out_mat_ocv = cv::Mat(sz_in, dtype);
84         }
85     }
86
87     static cv::Mat nonZeroPixels(const cv::Mat& mat)
88     {
89         int channels = mat.channels();
90         std::vector<cv::Mat> split(channels);
91         cv::split(mat, split);
92         cv::Mat result;
93         for (int c=0; c < channels; c++)
94         {
95             if (c == 0)
96                 result = split[c] != 0;
97             else
98                 result = result | (split[c] != 0);
99         }
100         return result;
101     }
102
103     static int countNonZeroPixels(const cv::Mat& mat)
104     {
105         return cv::countNonZero( nonZeroPixels(mat) );
106     }
107
108 };
109
110 template<class T>
111 class TestParams: public TestFunctional, public TestWithParam<T>{};
112
113 template<class T>
114 class TestPerfParams: public TestFunctional, public perf::TestBaseWithParam<T>{};
115
116 using compare_f = std::function<bool(const cv::Mat &a, const cv::Mat &b)>;
117
118 using compare_scalar_f = std::function<bool(const cv::Scalar &a, const cv::Scalar &b)>;
119
120
121 template<typename T>
122 struct Wrappable
123 {
124     compare_f to_compare_f()
125     {
126         T t = *static_cast<T*const>(this);
127         return [t](const cv::Mat &a, const cv::Mat &b)
128         {
129             return t(a, b);
130         };
131     }
132 };
133
134 template<typename T>
135 struct WrappableScalar
136 {
137     compare_scalar_f to_compare_f()
138     {
139         T t = *static_cast<T*const>(this);
140         return [t](const cv::Scalar &a, const cv::Scalar &b)
141         {
142             return t(a, b);
143         };
144     }
145 };
146
147
148 class AbsExact : public Wrappable<AbsExact>
149 {
150 public:
151     AbsExact() {}
152     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
153     {
154         if (cv::norm(in1, in2, NORM_INF) != 0)
155         {
156             std::cout << "AbsExact error: G-API output and reference output matrixes are not bitexact equal."  << std::endl;
157             return false;
158         }
159         else
160         {
161             return true;
162         }
163     }
164 private:
165 };
166
167 class AbsTolerance : public Wrappable<AbsTolerance>
168 {
169 public:
170     AbsTolerance(double tol) : _tol(tol) {}
171     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
172     {
173         if (cv::norm(in1, in2, NORM_INF) > _tol)
174         {
175             std::cout << "AbsTolerance error: Number of different pixels in " << std::endl;
176             std::cout << "G-API output and reference output matrixes exceeds " << _tol << " pixels threshold." << std::endl;
177             return false;
178         }
179         else
180         {
181             return true;
182         }
183     }
184 private:
185     double _tol;
186 };
187
188 class Tolerance_FloatRel_IntAbs : public Wrappable<Tolerance_FloatRel_IntAbs>
189 {
190 public:
191     Tolerance_FloatRel_IntAbs(double tol, double tol8u) : _tol(tol), _tol8u(tol8u) {}
192     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
193     {
194         int depth = CV_MAT_DEPTH(in1.type());
195         {
196             double err = depth >= CV_32F ? cv::norm(in1, in2, NORM_L1 | NORM_RELATIVE)
197                                                      : cv::norm(in1, in2, NORM_INF);
198             double tolerance = depth >= CV_32F ? _tol : _tol8u;
199             if (err > tolerance)
200             {
201                 std::cout << "Tolerance_FloatRel_IntAbs error: err=" << err
202                           << "  tolerance=" << tolerance
203                           << "  depth=" << cv::typeToString(depth) << std::endl;
204                 return false;
205             }
206             else
207             {
208                 return true;
209             }
210         }
211     }
212 private:
213     double _tol;
214     double _tol8u;
215 };
216
217
218 class AbsSimilarPoints : public Wrappable<AbsSimilarPoints>
219 {
220 public:
221     AbsSimilarPoints(double tol, double percent) : _tol(tol), _percent(percent) {}
222     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
223     {
224         Mat diff;
225         cv::absdiff(in1, in2, diff);
226         Mat err_mask = diff > _tol;
227         int err_points = cv::countNonZero(err_mask.reshape(1));
228         double max_err_points = _percent * std::max((size_t)1000, in1.total());
229         if (err_points > max_err_points)
230         {
231             std::cout << "AbsSimilarPoints error: err_points=" << err_points
232                       << "  max_err_points=" << max_err_points << " (total=" << in1.total() << ")"
233                       << "  diff_tolerance=" << _tol << std::endl;
234             return false;
235         }
236         else
237         {
238             return true;
239         }
240     }
241 private:
242     double _tol;
243     double _percent;
244 };
245
246
247 class ToleranceFilter : public Wrappable<ToleranceFilter>
248 {
249 public:
250     ToleranceFilter(double tol, double tol8u, double inf_tol = 2.0) : _tol(tol), _tol8u(tol8u), _inf_tol(inf_tol) {}
251     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
252     {
253         int depth = CV_MAT_DEPTH(in1.type());
254         {
255             double err_Inf = cv::norm(in1, in2, NORM_INF);
256             if (err_Inf > _inf_tol)
257             {
258                 std::cout << "ToleranceFilter error: err_Inf=" << err_Inf << "  tolerance=" << _inf_tol << std::endl;
259                 return false;
260             }
261             double err = cv::norm(in1, in2, NORM_L2 | NORM_RELATIVE);
262             double tolerance = depth >= CV_32F ? _tol : _tol8u;
263             if (err > tolerance)
264             {
265                 std::cout << "ToleranceFilter error: err=" << err << "  tolerance=" << tolerance
266                           << "  depth=" << cv::depthToString(depth)
267                           << std::endl;
268                 return false;
269             }
270         }
271         return true;
272     }
273 private:
274     double _tol;
275     double _tol8u;
276     double _inf_tol;
277 };
278
279 class ToleranceColor : public Wrappable<ToleranceColor>
280 {
281 public:
282     ToleranceColor(double tol, double inf_tol = 2.0) : _tol(tol), _inf_tol(inf_tol) {}
283     bool operator() (const cv::Mat& in1, const cv::Mat& in2) const
284     {
285         {
286             double err_Inf = cv::norm(in1, in2, NORM_INF);
287             if (err_Inf > _inf_tol)
288             {
289                 std::cout << "ToleranceColor error: err_Inf=" << err_Inf << "  tolerance=" << _inf_tol << std::endl;;
290                 return false;
291             }
292             double err = cv::norm(in1, in2, NORM_L1 | NORM_RELATIVE);
293             if (err > _tol)
294             {
295                 std::cout << "ToleranceColor error: err=" << err << "  tolerance=" << _tol << std::endl;;
296                 return false;
297             }
298         }
299         return true;
300     }
301 private:
302     double _tol;
303     double _inf_tol;
304 };
305
306 class AbsToleranceScalar : public WrappableScalar<AbsToleranceScalar>
307 {
308 public:
309     AbsToleranceScalar(double tol) : _tol(tol) {}
310     bool operator() (const cv::Scalar& in1, const cv::Scalar& in2) const
311     {
312         double abs_err = std::abs(in1[0] - in2[0]) / std::max(1.0, std::abs(in2[0]));
313         if (abs_err > _tol)
314         {
315             std::cout << "AbsToleranceScalar error: abs_err=" << abs_err << "  tolerance=" << _tol << " in1[0]" << in1[0] << " in2[0]" << in2[0] << std::endl;;
316             return false;
317         }
318         else
319         {
320             return true;
321         }
322     }
323 private:
324     double _tol;
325 };
326
327 } // namespace opencv_test
328
329 namespace
330 {
331     inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_f&)
332     {
333         return os << "compare_f";
334     }
335 }
336
337 namespace
338 {
339     inline std::ostream& operator<<(std::ostream& os, const opencv_test::compare_scalar_f&)
340     {
341         return os << "compare_scalar_f";
342     }
343 }