Publishing 2019 R3 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / src / backends / cpu / gcpuimgproc.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 Intel Corporation
6
7
8 #include "precomp.hpp"
9
10 #include <opencv2/gapi/imgproc.hpp>
11 #include <opencv2/gapi/cpu/imgproc.hpp>
12 #include <opencv2/gapi/cpu/gcpukernel.hpp>
13
14 #include "backends/fluid/gfluidimgproc_func.hpp"
15
16 namespace {
17     cv::Mat add_border(const cv::Mat& in, const int ksize, const int borderType, const cv::Scalar& bordVal){
18         if( borderType == cv::BORDER_CONSTANT )
19         {
20             cv::Mat temp_in;
21             int add = (ksize - 1) / 2;
22             cv::copyMakeBorder(in, temp_in, add, add, add, add, borderType, bordVal);
23             return temp_in(cv::Rect(add, add, in.cols, in.rows));
24         }
25         return in;
26     }
27 }
28
29 GAPI_OCV_KERNEL(GCPUSepFilter, cv::gapi::imgproc::GSepFilter)
30 {
31     static void run(const cv::Mat& in, int ddepth, const cv::Mat& kernX, const cv::Mat& kernY, const cv::Point& anchor, const cv::Scalar& delta,
32                     int border, const cv::Scalar& bordVal, cv::Mat &out)
33     {
34         if( border == cv::BORDER_CONSTANT )
35         {
36             cv::Mat temp_in;
37             int width_add = (kernY.cols - 1) / 2;
38             int height_add =  (kernX.rows - 1) / 2;
39             cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, border, bordVal);
40             cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
41             cv::sepFilter2D(temp_in(rect), out, ddepth, kernX, kernY, anchor, delta.val[0], border);
42         }
43         else
44             cv::sepFilter2D(in, out, ddepth, kernX, kernY, anchor, delta.val[0], border);
45     }
46 };
47
48 GAPI_OCV_KERNEL(GCPUBoxFilter, cv::gapi::imgproc::GBoxFilter)
49 {
50     static void run(const cv::Mat& in, int ddepth, const cv::Size& ksize, const cv::Point& anchor, bool normalize, int borderType, const cv::Scalar& bordVal, cv::Mat &out)
51     {
52         if( borderType == cv::BORDER_CONSTANT )
53         {
54             cv::Mat temp_in;
55             int width_add = (ksize.width - 1) / 2;
56             int height_add =  (ksize.height - 1) / 2;
57             cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal);
58             cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
59             cv::boxFilter(temp_in(rect), out, ddepth, ksize, anchor, normalize, borderType);
60         }
61         else
62             cv::boxFilter(in, out, ddepth, ksize, anchor, normalize, borderType);
63     }
64 };
65
66 GAPI_OCV_KERNEL(GCPUBlur, cv::gapi::imgproc::GBlur)
67 {
68     static void run(const cv::Mat& in, const cv::Size& ksize, const cv::Point& anchor, int borderType, const cv::Scalar& bordVal, cv::Mat &out)
69     {
70         if( borderType == cv::BORDER_CONSTANT )
71         {
72             cv::Mat temp_in;
73             int width_add = (ksize.width - 1) / 2;
74             int height_add =  (ksize.height - 1) / 2;
75             cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal);
76             cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
77             cv::blur(temp_in(rect), out, ksize, anchor, borderType);
78         }
79         else
80             cv::blur(in, out, ksize, anchor, borderType);
81     }
82 };
83
84
85 GAPI_OCV_KERNEL(GCPUFilter2D, cv::gapi::imgproc::GFilter2D)
86 {
87     static void run(const cv::Mat& in, int ddepth, const cv::Mat& k, const cv::Point& anchor, const cv::Scalar& delta, int border,
88                     const cv::Scalar& bordVal, cv::Mat &out)
89     {
90         if( border == cv::BORDER_CONSTANT )
91         {
92             cv::Mat temp_in;
93             int width_add = (k.cols - 1) / 2;
94             int height_add =  (k.rows - 1) / 2;
95             cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, border, bordVal );
96             cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
97             cv::filter2D(temp_in(rect), out, ddepth, k, anchor, delta.val[0], border);
98         }
99         else
100             cv::filter2D(in, out, ddepth, k, anchor, delta.val[0], border);
101     }
102 };
103
104 GAPI_OCV_KERNEL(GCPUGaussBlur, cv::gapi::imgproc::GGaussBlur)
105 {
106     static void run(const cv::Mat& in, const cv::Size& ksize, double sigmaX, double sigmaY, int borderType, const cv::Scalar& bordVal, cv::Mat &out)
107     {
108         if( borderType == cv::BORDER_CONSTANT )
109         {
110             cv::Mat temp_in;
111             int width_add = (ksize.width - 1) / 2;
112             int height_add =  (ksize.height - 1) / 2;
113             cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal );
114             cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
115             cv::GaussianBlur(temp_in(rect), out, ksize, sigmaX, sigmaY, borderType);
116         }
117         else
118             cv::GaussianBlur(in, out, ksize, sigmaX, sigmaY, borderType);
119     }
120 };
121
122 GAPI_OCV_KERNEL(GCPUMedianBlur, cv::gapi::imgproc::GMedianBlur)
123 {
124     static void run(const cv::Mat& in, int ksize, cv::Mat &out)
125     {
126         cv::medianBlur(in, out, ksize);
127     }
128 };
129
130 GAPI_OCV_KERNEL(GCPUErode, cv::gapi::imgproc::GErode)
131 {
132     static void run(const cv::Mat& in, const cv::Mat& kernel, const cv::Point& anchor, int iterations, int borderType, const cv::Scalar& borderValue, cv::Mat &out)
133     {
134         cv::erode(in, out, kernel, anchor, iterations, borderType, borderValue);
135     }
136 };
137
138 GAPI_OCV_KERNEL(GCPUDilate, cv::gapi::imgproc::GDilate)
139 {
140     static void run(const cv::Mat& in, const cv::Mat& kernel, const cv::Point& anchor, int iterations, int borderType, const cv::Scalar& borderValue, cv::Mat &out)
141     {
142         cv::dilate(in, out, kernel, anchor, iterations, borderType, borderValue);
143     }
144 };
145
146 GAPI_OCV_KERNEL(GCPUSobel, cv::gapi::imgproc::GSobel)
147 {
148     static void run(const cv::Mat& in, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType,
149                     const cv::Scalar& bordVal, cv::Mat &out)
150     {
151         cv::Mat temp_in = add_border(in, ksize, borderType, bordVal);
152         cv::Sobel(temp_in, out, ddepth, dx, dy, ksize, scale, delta, borderType);
153     }
154 };
155
156 GAPI_OCV_KERNEL(GCPUSobelXY, cv::gapi::imgproc::GSobelXY)
157 {
158     static void run(const cv::Mat& in, int ddepth, int order, int ksize, double scale, double delta, int borderType,
159                     const cv::Scalar& bordVal, cv::Mat &out_dx, cv::Mat &out_dy)
160     {
161         cv::Mat temp_in = add_border(in, ksize, borderType, bordVal);
162         cv::Sobel(temp_in, out_dx, ddepth, order, 0, ksize, scale, delta, borderType);
163         cv::Sobel(temp_in, out_dy, ddepth, 0, order, ksize, scale, delta, borderType);
164     }
165 };
166
167 GAPI_OCV_KERNEL(GCPUEqualizeHist, cv::gapi::imgproc::GEqHist)
168 {
169     static void run(const cv::Mat& in, cv::Mat &out)
170     {
171         cv::equalizeHist(in, out);
172     }
173 };
174
175 GAPI_OCV_KERNEL(GCPUCanny, cv::gapi::imgproc::GCanny)
176 {
177     static void run(const cv::Mat& in, double thr1, double thr2, int apSize, bool l2gradient, cv::Mat &out)
178     {
179         cv::Canny(in, out, thr1, thr2, apSize, l2gradient);
180     }
181 };
182
183 GAPI_OCV_KERNEL(GCPURGB2YUV, cv::gapi::imgproc::GRGB2YUV)
184 {
185     static void run(const cv::Mat& in, cv::Mat &out)
186     {
187         cv::cvtColor(in, out, cv::COLOR_RGB2YUV);
188     }
189 };
190
191 GAPI_OCV_KERNEL(GCPUYUV2RGB, cv::gapi::imgproc::GYUV2RGB)
192 {
193     static void run(const cv::Mat& in, cv::Mat &out)
194     {
195         cv::cvtColor(in, out, cv::COLOR_YUV2RGB);
196     }
197 };
198
199 GAPI_OCV_KERNEL(GCPUNV12toRGB, cv::gapi::imgproc::GNV12toRGB)
200 {
201     static void run(const cv::Mat& in_y, const cv::Mat& in_uv, cv::Mat &out)
202     {
203         cv::cvtColorTwoPlane(in_y, in_uv, out, cv::COLOR_YUV2RGB_NV12);
204     }
205 };
206
207 GAPI_OCV_KERNEL(GCPUNV12toBGR, cv::gapi::imgproc::GNV12toBGR)
208 {
209     static void run(const cv::Mat& in_y, const cv::Mat& in_uv, cv::Mat &out)
210     {
211         cv::cvtColorTwoPlane(in_y, in_uv, out, cv::COLOR_YUV2BGR_NV12);
212     }
213 };
214
215 GAPI_OCV_KERNEL(GCPURGB2Lab, cv::gapi::imgproc::GRGB2Lab)
216 {
217     static void run(const cv::Mat& in, cv::Mat &out)
218     {
219         cv::cvtColor(in, out, cv::COLOR_RGB2Lab);
220     }
221 };
222
223 GAPI_OCV_KERNEL(GCPUBGR2LUV, cv::gapi::imgproc::GBGR2LUV)
224 {
225     static void run(const cv::Mat& in, cv::Mat &out)
226     {
227         cv::cvtColor(in, out, cv::COLOR_BGR2Luv);
228     }
229 };
230
231 GAPI_OCV_KERNEL(GCPUBGR2YUV, cv::gapi::imgproc::GBGR2YUV)
232 {
233     static void run(const cv::Mat& in, cv::Mat &out)
234     {
235         cv::cvtColor(in, out, cv::COLOR_BGR2YUV);
236     }
237 };
238
239 GAPI_OCV_KERNEL(GCPULUV2BGR, cv::gapi::imgproc::GLUV2BGR)
240 {
241     static void run(const cv::Mat& in, cv::Mat &out)
242     {
243         cv::cvtColor(in, out, cv::COLOR_Luv2BGR);
244     }
245 };
246
247 GAPI_OCV_KERNEL(GCPUYUV2BGR, cv::gapi::imgproc::GYUV2BGR)
248 {
249     static void run(const cv::Mat& in, cv::Mat &out)
250     {
251         cv::cvtColor(in, out, cv::COLOR_YUV2BGR);
252     }
253 };
254
255 GAPI_OCV_KERNEL(GCPURGB2Gray, cv::gapi::imgproc::GRGB2Gray)
256 {
257     static void run(const cv::Mat& in, cv::Mat &out)
258     {
259         cv::cvtColor(in, out, cv::COLOR_RGB2GRAY);
260     }
261 };
262
263 GAPI_OCV_KERNEL(GCPUBGR2Gray, cv::gapi::imgproc::GBGR2Gray)
264 {
265     static void run(const cv::Mat& in, cv::Mat &out)
266     {
267         cv::cvtColor(in, out, cv::COLOR_BGR2GRAY);
268     }
269 };
270
271 GAPI_OCV_KERNEL(GCPURGB2GrayCustom, cv::gapi::imgproc::GRGB2GrayCustom)
272 {
273     static void run(const cv::Mat& in, float rY, float bY, float gY, cv::Mat &out)
274     {
275         cv::Mat planes[3];
276         cv::split(in, planes);
277         out = planes[0]*rY + planes[1]*bY + planes[2]*gY;
278     }
279 };
280
281 GAPI_OCV_KERNEL(GCPUBayerGR2RGB, cv::gapi::imgproc::GBayerGR2RGB)
282 {
283     static void run(const cv::Mat& in, cv::Mat &out)
284     {
285         cv::cvtColor(in, out, cv::COLOR_BayerGR2RGB);
286     }
287 };
288
289 GAPI_OCV_KERNEL(GCPURGB2HSV, cv::gapi::imgproc::GRGB2HSV)
290 {
291     static void run(const cv::Mat& in, cv::Mat &out)
292     {
293         cv::cvtColor(in, out, cv::COLOR_RGB2HSV);
294     }
295 };
296
297 GAPI_OCV_KERNEL(GCPURGB2YUV422, cv::gapi::imgproc::GRGB2YUV422)
298 {
299     static void run(const cv::Mat& in, cv::Mat &out)
300     {
301         out.create(in.size(), CV_8UC2);
302
303         for (int i = 0; i < in.rows; ++i)
304         {
305             const uchar* in_line_p  = in.ptr<uchar>(i);
306             uchar* out_line_p = out.ptr<uchar>(i);
307             cv::gapi::fluid::run_rgb2yuv422_impl(out_line_p, in_line_p, in.cols);
308         }
309     }
310 };
311
312 static void toPlanar(const cv::Mat& in, cv::Mat& out)
313 {
314     GAPI_Assert(out.depth() == in.depth());
315     GAPI_Assert(out.channels() == 1);
316     GAPI_Assert(in.channels() == 3);
317     GAPI_Assert(out.cols == in.cols);
318     GAPI_Assert(out.rows == 3*in.rows);
319
320     std::vector<cv::Mat> outs(3);
321     for (int i = 0; i < 3; i++) {
322         outs[i] = out(cv::Rect(0, i*in.rows, in.cols, in.rows));
323     }
324     cv::split(in, outs);
325 }
326
327
328 GAPI_OCV_KERNEL(GCPUNV12toRGBp, cv::gapi::imgproc::GNV12toRGBp)
329 {
330     static void run(const cv::Mat& inY, const cv::Mat& inUV, cv::Mat& out)
331     {
332         cv::Mat rgb;
333         cv::cvtColorTwoPlane(inY, inUV, rgb, cv::COLOR_YUV2RGB_NV12);
334         toPlanar(rgb, out);
335     }
336 };
337
338 GAPI_OCV_KERNEL(GCPUNV12toBGRp, cv::gapi::imgproc::GNV12toBGRp)
339 {
340     static void run(const cv::Mat& inY, const cv::Mat& inUV, cv::Mat& out)
341     {
342         cv::Mat rgb;
343         cv::cvtColorTwoPlane(inY, inUV, rgb, cv::COLOR_YUV2BGR_NV12);
344         toPlanar(rgb, out);
345     }
346 };
347
348
349 cv::gapi::GKernelPackage cv::gapi::imgproc::cpu::kernels()
350 {
351     static auto pkg = cv::gapi::kernels
352         < GCPUFilter2D
353         , GCPUSepFilter
354         , GCPUBoxFilter
355         , GCPUBlur
356         , GCPUGaussBlur
357         , GCPUMedianBlur
358         , GCPUErode
359         , GCPUDilate
360         , GCPUSobel
361         , GCPUSobelXY
362         , GCPUCanny
363         , GCPUEqualizeHist
364         , GCPURGB2YUV
365         , GCPUYUV2RGB
366         , GCPUNV12toRGB
367         , GCPUNV12toBGR
368         , GCPURGB2Lab
369         , GCPUBGR2LUV
370         , GCPUBGR2YUV
371         , GCPUYUV2BGR
372         , GCPULUV2BGR
373         , GCPUBGR2Gray
374         , GCPURGB2Gray
375         , GCPURGB2GrayCustom
376         , GCPUBayerGR2RGB
377         , GCPURGB2HSV
378         , GCPURGB2YUV422
379         , GCPUNV12toRGBp
380         , GCPUNV12toBGRp
381         >();
382     return pkg;
383 }