Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / test / gapi_fluid_test_kernels.cpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7 #include "test_precomp.hpp"
8
9 #include <iomanip>
10 #include "gapi_fluid_test_kernels.hpp"
11 #include <opencv2/gapi/core.hpp>
12
13 namespace cv
14 {
15 namespace gapi_test_kernels
16 {
17
18 GAPI_FLUID_KERNEL(FAddSimple, TAddSimple, false)
19 {
20     static const int Window = 1;
21
22     static void run(const cv::gapi::fluid::View   &a,
23                     const cv::gapi::fluid::View   &b,
24                           cv::gapi::fluid::Buffer &o)
25     {
26         // std::cout << "AddSimple {{{\n";
27         // std::cout << "  a - "; a.debug(std::cout);
28         // std::cout << "  b - "; b.debug(std::cout);
29         // std::cout << "  o - "; o.debug(std::cout);
30
31         const uint8_t* in1 = a.InLine<uint8_t>(0);
32         const uint8_t* in2 = b.InLine<uint8_t>(0);
33               uint8_t* out = o.OutLine<uint8_t>();
34
35         // std::cout << "a: ";
36         // for (int i = 0, w = a.length(); i < w; i++)
37         // {
38         //     std::cout << std::setw(4) << int(in1[i]);
39         // }
40         // std::cout << "\n";
41
42         // std::cout << "b: ";
43         // for (int i = 0, w = a.length(); i < w; i++)
44         // {
45         //     std::cout << std::setw(4) << int(in2[i]);
46         // }
47         // std::cout << "\n";
48
49         for (int i = 0, w = a.length(); i < w; i++)
50         {
51             out[i] = in1[i] + in2[i];
52         }
53
54         // std::cout << "}}} " << std::endl;;
55     }
56 };
57
58 GAPI_FLUID_KERNEL(FAddCSimple, TAddCSimple, false)
59 {
60     static const int Window = 1;
61     static const int LPI    = 2;
62
63     static void run(const cv::gapi::fluid::View   &in,
64                     const int                      cval,
65                           cv::gapi::fluid::Buffer &out)
66     {
67         for (int l = 0, lpi = out.lpi(); l < lpi; l++)
68         {
69             const uint8_t* in_row  = in .InLine <uint8_t>(l);
70                   uint8_t* out_row = out.OutLine<uint8_t>(l);
71             //std::cout << "l=" << l << ": ";
72             for (int i = 0, w = in.length(); i < w; i++)
73             {
74                 //std::cout << std::setw(4) << int(in_row[i]);
75                 out_row[i] = static_cast<uint8_t>(in_row[i] + cval);
76             }
77             //std::cout << std::endl;
78         }
79     }
80 };
81
82 GAPI_FLUID_KERNEL(FAddScalar, TAddScalar, false)
83 {
84     static const int Window = 1;
85     static const int LPI    = 2;
86
87     static void run(const cv::gapi::fluid::View   &in,
88                     const cv::Scalar              &cval,
89                           cv::gapi::fluid::Buffer &out)
90     {
91         for (int l = 0, lpi = out.lpi(); l < lpi; l++)
92         {
93             const uint8_t* in_row  = in .InLine <uint8_t>(l);
94                   uint8_t* out_row = out.OutLine<uint8_t>(l);
95             std::cout << "l=" << l << ": ";
96             for (int i = 0, w = in.length(); i < w; i++)
97             {
98                 std::cout << std::setw(4) << int(in_row[i]);
99                 out_row[i] = static_cast<uint8_t>(in_row[i] + cval[0]);
100             }
101             std::cout << std::endl;
102         }
103     }
104 };
105
106 GAPI_FLUID_KERNEL(FAddScalarToMat, TAddScalarToMat, false)
107 {
108     static const int Window = 1;
109     static const int LPI    = 2;
110
111     static void run(const cv::Scalar              &cval,
112                     const cv::gapi::fluid::View   &in,
113                           cv::gapi::fluid::Buffer &out)
114     {
115         for (int l = 0, lpi = out.lpi(); l < lpi; l++)
116         {
117             const uint8_t* in_row  = in .InLine <uint8_t>(l);
118                   uint8_t* out_row = out.OutLine<uint8_t>(l);
119             std::cout << "l=" << l << ": ";
120             for (int i = 0, w = in.length(); i < w; i++)
121             {
122                 std::cout << std::setw(4) << int(in_row[i]);
123                 out_row[i] = static_cast<uint8_t>(in_row[i] + cval[0]);
124             }
125             std::cout << std::endl;
126         }
127     }
128 };
129
130 template<int kernelSize, int lpi = 1>
131 static void runBlur(const cv::gapi::fluid::View& src, cv::gapi::fluid::Buffer& dst)
132 {
133     const auto borderSize = (kernelSize - 1) / 2;
134     const unsigned char* ins[kernelSize];
135
136     for (int l = 0; l < lpi; l++)
137     {
138         for (int i = 0; i < kernelSize; i++)
139         {
140             ins[i] = src.InLine<unsigned char>(i - borderSize + l);
141         }
142
143         auto out = dst.OutLine<unsigned char>(l);
144         const auto width = dst.length();
145
146         for (int w = 0; w < width; w++)
147         {
148             float res = 0.0f;
149             for (int i = 0; i < kernelSize; i++)
150             {
151                 for (int j = -borderSize; j < borderSize + 1; j++)
152                 {
153                     res += ins[i][w+j];
154                 }
155             }
156             out[w] = static_cast<unsigned char>(std::rint(res / (kernelSize * kernelSize)));
157         }
158     }
159 }
160
161 GAPI_FLUID_KERNEL(FBlur1x1, TBlur1x1, false)
162 {
163     static const int Window = 1;
164
165     static void run(const cv::gapi::fluid::View &src, int /*borderType*/,
166                     cv::Scalar /*borderValue*/, cv::gapi::fluid::Buffer &dst)
167     {
168         runBlur<Window>(src, dst);
169     }
170 };
171
172 GAPI_FLUID_KERNEL(FBlur3x3, TBlur3x3, false)
173 {
174     static const int Window = 3;
175
176     static void run(const cv::gapi::fluid::View &src, int /*borderType*/,
177                     cv::Scalar /*borderValue*/, cv::gapi::fluid::Buffer &dst)
178     {
179         runBlur<Window>(src, dst);
180     }
181
182     static cv::gapi::fluid::Border getBorder(const cv::GMatDesc &/*src*/, int borderType, cv::Scalar borderValue)
183     {
184         return { borderType, to_own(borderValue)};
185     }
186 };
187
188 GAPI_FLUID_KERNEL(FBlur5x5, TBlur5x5, false)
189 {
190     static const int Window = 5;
191
192     static void run(const cv::gapi::fluid::View &src, int /*borderType*/,
193                     cv::Scalar /*borderValue*/, cv::gapi::fluid::Buffer &dst)
194     {
195         runBlur<Window>(src, dst);
196     }
197
198     static cv::gapi::fluid::Border getBorder(const cv::GMatDesc &/*src*/, int borderType, cv::Scalar borderValue)
199     {
200         return { borderType, to_own(borderValue)};
201     }
202 };
203
204 GAPI_FLUID_KERNEL(FBlur3x3_2lpi, TBlur3x3_2lpi, false)
205 {
206     static const int Window = 3;
207     static const int LPI    = 2;
208
209     static void run(const cv::gapi::fluid::View &src, int /*borderType*/,
210                     cv::Scalar /*borderValue*/, cv::gapi::fluid::Buffer &dst)
211     {
212         runBlur<Window, LPI>(src, dst);
213     }
214
215     static cv::gapi::fluid::Border getBorder(const cv::GMatDesc &/*src*/, int borderType, cv::Scalar borderValue)
216     {
217         return { borderType, to_own(borderValue)};
218     }
219 };
220
221 GAPI_FLUID_KERNEL(FBlur5x5_2lpi, TBlur5x5_2lpi, false)
222 {
223     static const int Window = 5;
224     static const int LPI    = 2;
225
226     static void run(const cv::gapi::fluid::View &src, int /*borderType*/,
227                     cv::Scalar /*borderValue*/, cv::gapi::fluid::Buffer &dst)
228     {
229         runBlur<Window, LPI>(src, dst);
230     }
231
232     static cv::gapi::fluid::Border getBorder(const cv::GMatDesc &/*src*/, int borderType, cv::Scalar borderValue)
233     {
234         return { borderType, to_own(borderValue )};
235     }
236 };
237
238 GAPI_FLUID_KERNEL(FIdentity, TId, false)
239 {
240     static const int Window = 3;
241
242     static void run(const cv::gapi::fluid::View   &a,
243                           cv::gapi::fluid::Buffer &o)
244     {
245         const uint8_t* in[3] = {
246             a.InLine<uint8_t>(-1),
247             a.InLine<uint8_t>( 0),
248             a.InLine<uint8_t>(+1)
249         };
250         uint8_t* out = o.OutLine<uint8_t>();
251
252         // ReadFunction3x3(in, a.length());
253         for (int i = 0, w = a.length(); i < w; i++)
254         {
255             out[i] = in[1][i];
256         }
257     }
258
259     static gapi::fluid::Border getBorder(const cv::GMatDesc &)
260     {
261         return { cv::BORDER_REPLICATE, cv::gapi::own::Scalar{} };
262     }
263 };
264
265 GAPI_FLUID_KERNEL(FId7x7, TId7x7, false)
266 {
267     static const int Window = 7;
268     static const int LPI    = 2;
269
270     static void run(const cv::gapi::fluid::View   &a,
271                           cv::gapi::fluid::Buffer &o)
272     {
273         for (int l = 0, lpi = o.lpi(); l < lpi; l++)
274         {
275             const uint8_t* in[Window] = {
276                 a.InLine<uint8_t>(-3 + l),
277                 a.InLine<uint8_t>(-2 + l),
278                 a.InLine<uint8_t>(-1 + l),
279                 a.InLine<uint8_t>( 0 + l),
280                 a.InLine<uint8_t>(+1 + l),
281                 a.InLine<uint8_t>(+2 + l),
282                 a.InLine<uint8_t>(+3 + l),
283             };
284             uint8_t* out = o.OutLine<uint8_t>(l);
285
286             // std::cout << "Id7x7 " << l << " of " << lpi << " {{{\n";
287             // std::cout << "  a - "; a.debug(std::cout);
288             // std::cout << "  o - "; o.debug(std::cout);
289             // std::cout << "}}} " << std::endl;;
290
291             // // std::cout << "Id7x7 at " << a.y() << "/L" << l <<  " {{{" << std::endl;
292             // for (int j = 0; j < Window; j++)
293             // {
294             //     // std::cout << std::setw(2) << j-(Window-1)/2 << ": ";
295             //     for (int i = 0, w = a.length(); i < w; i++)
296             //         std::cout << std::setw(4) << int(in[j][i]);
297             //     std::cout << std::endl;
298             // }
299             // std::cout << "}}}" << std::endl;
300
301             for (int i = 0, w = a.length(); i < w; i++)
302                 out[i] = in[(Window-1)/2][i];
303         }
304     }
305
306     static cv::gapi::fluid::Border getBorder(const cv::GMatDesc&/* src*/)
307     {
308         return { cv::BORDER_REPLICATE, cv::gapi::own::Scalar{} };
309     }
310 };
311
312 GAPI_FLUID_KERNEL(FPlusRow0, TPlusRow0, true)
313 {
314     static const int Window = 1;
315
316     static void initScratch(const cv::GMatDesc            &in,
317                                   cv::gapi::fluid::Buffer &scratch)
318     {
319         cv::Size scratch_size{in.size.width, 1};
320         cv::gapi::fluid::Buffer buffer(in.withSize(scratch_size));
321         scratch = std::move(buffer);
322     }
323
324     static void resetScratch(cv::gapi::fluid::Buffer &scratch)
325     {
326         // FIXME: only 1 line can be used!
327         uint8_t* out_row = scratch.OutLine<uint8_t>();
328         for (int i = 0, w = scratch.length(); i < w; i++)
329         {
330             out_row[i] = 0;
331         }
332     }
333
334     static void run(const cv::gapi::fluid::View   &in,
335                           cv::gapi::fluid::Buffer &out,
336                           cv::gapi::fluid::Buffer &scratch)
337     {
338         const uint8_t* in_row  = in     .InLine <uint8_t>(0);
339               uint8_t* out_row = out    .OutLine<uint8_t>();
340               uint8_t* tmp_row = scratch.OutLine<uint8_t>();
341
342         if (in.y() == 0)
343         {
344             // Copy 1st row to scratch buffer
345             for (int i = 0, w = in.length(); i < w; i++)
346             {
347                 out_row[i] = in_row[i];
348                 tmp_row[i] = in_row[i];
349             }
350         }
351         else
352         {
353             // Output is 1st row + in
354             for (int i = 0, w = in.length(); i < w; i++)
355             {
356                 out_row[i] = in_row[i] + tmp_row[i];
357             }
358         }
359     }
360 };
361
362 GAPI_FLUID_KERNEL(FTestSplit3, cv::gapi::core::GSplit3, false)
363 {
364     static const int Window = 1;
365
366     static void run(const cv::gapi::fluid::View   &in,
367                           cv::gapi::fluid::Buffer &o1,
368                           cv::gapi::fluid::Buffer &o2,
369                           cv::gapi::fluid::Buffer &o3)
370     {
371         // std::cout << "Split3  {{{\n";
372         // std::cout << "  a - "; in.debug(std::cout);
373         // std::cout << "  1 - "; o1.debug(std::cout);
374         // std::cout << "  2 - "; o2.debug(std::cout);
375         // std::cout << "  3 - "; o3.debug(std::cout);
376         // std::cout << "}}} " << std::endl;;
377
378         const uint8_t* in_rgb = in.InLine<uint8_t>(0);
379               uint8_t* out_r  = o1.OutLine<uint8_t>();
380               uint8_t* out_g  = o2.OutLine<uint8_t>();
381               uint8_t* out_b  = o3.OutLine<uint8_t>();
382
383         for (int i = 0, w = in.length(); i < w; i++)
384         {
385             out_r[i] = in_rgb[3*i];
386             out_g[i] = in_rgb[3*i+1];
387             out_b[i] = in_rgb[3*i+2];
388         }
389     }
390 };
391
392 GAPI_FLUID_KERNEL(FSum2MatsAndScalar, TSum2MatsAndScalar, false)
393 {
394     static const int Window = 1;
395     static const int LPI    = 2;
396
397     static void run(const cv::gapi::fluid::View   &a,
398                     const cv::Scalar              &cval,
399                     const cv::gapi::fluid::View   &b,
400                           cv::gapi::fluid::Buffer &out)
401     {
402         for (int l = 0, lpi = out.lpi(); l < lpi; l++)
403         {
404             const uint8_t* in_row1  = a .InLine <uint8_t>(l);
405             const uint8_t* in_row2  = b .InLine <uint8_t>(l);
406                   uint8_t* out_row = out.OutLine<uint8_t>(l);
407             std::cout << "l=" << l << ": ";
408             for (int i = 0, w = a.length(); i < w; i++)
409             {
410                 std::cout << std::setw(4) << int(in_row1[i]);
411                 std::cout << std::setw(4) << int(in_row2[i]);
412                 out_row[i] = static_cast<uint8_t>(in_row1[i] + in_row2[i] + cval[0]);
413             }
414             std::cout << std::endl;
415         }
416     }
417 };
418
419 cv::gapi::GKernelPackage fluidTestPackage = cv::gapi::kernels
420         <FAddSimple
421         ,FAddCSimple
422         ,FAddScalar
423         ,FAddScalarToMat
424         ,FBlur1x1
425         ,FBlur3x3
426         ,FBlur5x5
427         ,FBlur3x3_2lpi
428         ,FBlur5x5_2lpi
429         ,FIdentity
430         ,FId7x7
431         ,FPlusRow0
432         ,FSum2MatsAndScalar
433         ,FTestSplit3
434         >();
435 } // namespace gapi_test_kernels
436 } // namespace cv