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 #include "precomp.hpp"
6 #include "opencl_kernels_imgproc.hpp"
7 #include "color.hpp"
8 
9 namespace cv
10 {
11 
12 #ifdef HAVE_OPENCL
13 
ocl_cvtColor(InputArray _src,OutputArray _dst,int code,int dcn)14 static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
15 {
16     int bidx = swapBlue(code) ? 2 : 0;
17 
18     switch (code)
19     {
20     case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2BGR:
21     case COLOR_RGBA2BGR: case COLOR_RGB2BGR: case COLOR_BGRA2RGBA:
22     {
23         bool reverse = !(code == COLOR_BGR2BGRA || code == COLOR_BGRA2BGR);
24         return oclCvtColorBGR2BGR(_src, _dst, dcn, reverse);
25     }
26     case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652RGB: case COLOR_BGR5552RGB:
27     case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
28         return oclCvtColor5x52BGR(_src, _dst, dcn, bidx, greenBits(code));
29 
30     case COLOR_BGR2BGR565: case COLOR_BGR2BGR555: case COLOR_RGB2BGR565: case COLOR_RGB2BGR555:
31     case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555: case COLOR_RGBA2BGR565: case COLOR_RGBA2BGR555:
32         return oclCvtColorBGR25x5(_src, _dst, bidx, greenBits(code) );
33 
34     case COLOR_BGR5652GRAY: case COLOR_BGR5552GRAY:
35         return oclCvtColor5x52Gray(_src, _dst, greenBits(code));
36 
37     case COLOR_GRAY2BGR565: case COLOR_GRAY2BGR555:
38         return oclCvtColorGray25x5(_src, _dst, greenBits(code));
39 
40     case COLOR_BGR2GRAY: case COLOR_BGRA2GRAY:
41     case COLOR_RGB2GRAY: case COLOR_RGBA2GRAY:
42         return oclCvtColorBGR2Gray(_src, _dst, bidx);
43 
44     case COLOR_GRAY2BGR:
45     case COLOR_GRAY2BGRA:
46         return oclCvtColorGray2BGR(_src, _dst, dcn);
47 
48     case COLOR_BGR2YUV:
49     case COLOR_RGB2YUV:
50         return oclCvtColorBGR2YUV(_src, _dst, bidx);
51 
52     case COLOR_YUV2BGR:
53     case COLOR_YUV2RGB:
54         return oclCvtColorYUV2BGR(_src, _dst, dcn, bidx);
55 
56     case COLOR_YUV2RGB_NV12: case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGR_NV21:
57     case COLOR_YUV2RGBA_NV12: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV21:
58     {
59         int uidx = code == COLOR_YUV2RGBA_NV21 || code == COLOR_YUV2RGB_NV21 ||
60                    code == COLOR_YUV2BGRA_NV21 || code == COLOR_YUV2BGR_NV21 ? 1 : 0;
61         return oclCvtColorTwoPlaneYUV2BGR(_src, _dst, dcn, bidx, uidx);
62     }
63     case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12:
64     case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
65     {
66         int uidx = code == COLOR_YUV2BGRA_YV12 || code == COLOR_YUV2BGR_YV12 ||
67                    code == COLOR_YUV2RGBA_YV12 || code == COLOR_YUV2RGB_YV12 ? 1 : 0;
68         return oclCvtColorThreePlaneYUV2BGR(_src, _dst, dcn, bidx, uidx);
69     }
70     case COLOR_YUV2GRAY_420:
71     {
72         return oclCvtColorYUV2Gray_420(_src, _dst);
73     }
74     case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
75     case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
76     {
77         int uidx = code == COLOR_RGBA2YUV_YV12 || code == COLOR_RGB2YUV_YV12 ||
78                    code == COLOR_BGRA2YUV_YV12 || code == COLOR_BGR2YUV_YV12 ? 1 : 0;
79         return oclCvtColorBGR2ThreePlaneYUV(_src, _dst, bidx, uidx );
80     }
81     case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY:
82     case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2: case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU:
83     case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
84     {
85         int yidx = (code==COLOR_YUV2RGB_UYVY || code==COLOR_YUV2RGBA_UYVY ||
86                     code==COLOR_YUV2BGR_UYVY || code==COLOR_YUV2BGRA_UYVY) ? 1 : 0;
87         int uidx = (code==COLOR_YUV2RGB_YVYU || code==COLOR_YUV2RGBA_YVYU ||
88                     code==COLOR_YUV2BGR_YVYU || code==COLOR_YUV2BGRA_YVYU) ? 2 : 0;
89         uidx = 1 - yidx + uidx;
90 
91         return oclCvtColorOnePlaneYUV2BGR(_src, _dst, dcn, bidx, uidx, yidx);
92     }
93     case COLOR_BGR2YCrCb:
94     case COLOR_RGB2YCrCb:
95         return oclCvtColorBGR2YCrCb(_src, _dst, bidx);
96 
97     case COLOR_YCrCb2BGR:
98     case COLOR_YCrCb2RGB:
99         return oclCvtcolorYCrCb2BGR(_src, _dst, dcn, bidx);
100 
101     case COLOR_BGR2XYZ:
102     case COLOR_RGB2XYZ:
103         return oclCvtColorBGR2XYZ(_src, _dst, bidx);
104 
105     case COLOR_XYZ2BGR:
106     case COLOR_XYZ2RGB:
107         return oclCvtColorXYZ2BGR(_src, _dst, dcn, bidx);
108 
109     case COLOR_BGR2HSV: case COLOR_BGR2HSV_FULL:
110     case COLOR_RGB2HSV: case COLOR_RGB2HSV_FULL:
111         return oclCvtColorBGR2HSV(_src, _dst, bidx, isFullRangeHSV(code));
112 
113     case COLOR_BGR2HLS: case COLOR_BGR2HLS_FULL:
114     case COLOR_RGB2HLS: case COLOR_RGB2HLS_FULL:
115         return oclCvtColorBGR2HLS(_src, _dst, bidx, isFullRangeHSV(code));
116 
117     case COLOR_HSV2BGR: case COLOR_HSV2BGR_FULL:
118     case COLOR_HSV2RGB: case COLOR_HSV2RGB_FULL:
119         return oclCvtColorHSV2BGR(_src, _dst, dcn, bidx, isFullRangeHSV(code));
120 
121     case COLOR_HLS2BGR: case COLOR_HLS2BGR_FULL:
122     case COLOR_HLS2RGB: case COLOR_HLS2RGB_FULL:
123         return oclCvtColorHLS2BGR(_src, _dst, dcn, bidx, isFullRangeHSV(code));
124 
125     case COLOR_RGBA2mRGBA:
126         return oclCvtColorRGBA2mRGBA(_src, _dst);
127 
128     case COLOR_mRGBA2RGBA:
129         return oclCvtColormRGBA2RGBA(_src, _dst);
130 
131     case COLOR_BGR2Lab: case COLOR_LBGR2Lab:
132     case COLOR_RGB2Lab: case COLOR_LRGB2Lab:
133         return oclCvtColorBGR2Lab(_src, _dst, bidx, is_sRGB(code));
134 
135     case COLOR_BGR2Luv: case COLOR_LBGR2Luv:
136     case COLOR_RGB2Luv: case COLOR_LRGB2Luv:
137         return oclCvtColorBGR2Luv(_src, _dst, bidx, is_sRGB(code));
138 
139     case COLOR_Lab2BGR: case COLOR_Lab2LBGR:
140     case COLOR_Lab2RGB: case COLOR_Lab2LRGB:
141         return oclCvtColorLab2BGR(_src, _dst, dcn, bidx, is_sRGB(code));
142 
143     case COLOR_Luv2BGR: case COLOR_Luv2LBGR:
144     case COLOR_Luv2RGB: case COLOR_Luv2LRGB:
145         return oclCvtColorLuv2BGR(_src, _dst, dcn, bidx, is_sRGB(code));
146 
147     default:
148         return false;
149     }
150 }
151 
152 #endif
153 
154 
155 // helper function for dual-plane modes
156 
cvtColorTwoPlane(InputArray _ysrc,InputArray _uvsrc,OutputArray _dst,int code)157 void cvtColorTwoPlane( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, int code )
158 {
159     // only YUV420 is currently supported
160     switch (code)
161     {
162         case COLOR_YUV2BGR_NV21:  case COLOR_YUV2RGB_NV21:  case COLOR_YUV2BGR_NV12:  case COLOR_YUV2RGB_NV12:
163         case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
164             break;
165         default:
166             CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
167             return;
168     }
169 
170     cvtColorTwoPlaneYUV2BGRpair(_ysrc, _uvsrc, _dst, dstChannels(code), swapBlue(code), uIndex(code));
171 }
172 
173 
174 //////////////////////////////////////////////////////////////////////////////////////////
175 //                                   The main function                                  //
176 //////////////////////////////////////////////////////////////////////////////////////////
177 
cvtColor(InputArray _src,OutputArray _dst,int code,int dcn)178 void cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
179 {
180     CV_INSTRUMENT_REGION();
181 
182     CV_Assert(!_src.empty());
183 
184     if(dcn <= 0)
185             dcn = dstChannels(code);
186 
187     CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() &&
188                 !(CV_MAT_DEPTH(_src.type()) == CV_8U && (code == COLOR_Luv2BGR || code == COLOR_Luv2RGB)),
189                 ocl_cvtColor(_src, _dst, code, dcn) )
190 
191     switch( code )
192     {
193         case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2BGR:
194         case COLOR_RGBA2BGR: case COLOR_RGB2BGR:  case COLOR_BGRA2RGBA:
195             if(_src.channels() == 1)
196                 cvtColorGray2BGR(_src, _dst, dcn);
197             else
198                 cvtColorBGR2BGR(_src, _dst, dcn, swapBlue(code));
199             break;
200 
201         case COLOR_BGR2BGR565:  case COLOR_BGR2BGR555: case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555:
202         case COLOR_RGB2BGR565:  case COLOR_RGB2BGR555: case COLOR_RGBA2BGR565: case COLOR_RGBA2BGR555:
203             cvtColorBGR25x5(_src, _dst, swapBlue(code), greenBits(code));
204             break;
205 
206         case COLOR_BGR5652BGR:  case COLOR_BGR5552BGR: case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA:
207         case COLOR_BGR5652RGB:  case COLOR_BGR5552RGB: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
208             cvtColor5x52BGR(_src, _dst, dcn, swapBlue(code), greenBits(code));
209             break;
210 
211         case COLOR_BGR2GRAY: case COLOR_BGRA2GRAY:
212         case COLOR_RGB2GRAY: case COLOR_RGBA2GRAY:
213             cvtColorBGR2Gray(_src, _dst, swapBlue(code));
214             break;
215 
216         case COLOR_BGR5652GRAY:
217         case COLOR_BGR5552GRAY:
218             cvtColor5x52Gray(_src, _dst, greenBits(code));
219             break;
220 
221         case COLOR_GRAY2BGR:
222         case COLOR_GRAY2BGRA:
223             cvtColorGray2BGR(_src, _dst, dcn);
224             break;
225 
226         case COLOR_GRAY2BGR565:
227         case COLOR_GRAY2BGR555:
228             cvtColorGray25x5(_src, _dst, greenBits(code));
229             break;
230 
231         case COLOR_BGR2YCrCb: case COLOR_RGB2YCrCb:
232         case COLOR_BGR2YUV:   case COLOR_RGB2YUV:
233             cvtColorBGR2YUV(_src, _dst, swapBlue(code), code == COLOR_BGR2YCrCb || code == COLOR_RGB2YCrCb);
234             break;
235 
236         case COLOR_YCrCb2BGR: case COLOR_YCrCb2RGB:
237         case COLOR_YUV2BGR:   case COLOR_YUV2RGB:
238             cvtColorYUV2BGR(_src, _dst, dcn, swapBlue(code), code == COLOR_YCrCb2BGR || code == COLOR_YCrCb2RGB);
239             break;
240 
241         case COLOR_BGR2XYZ:
242         case COLOR_RGB2XYZ:
243             cvtColorBGR2XYZ(_src, _dst, swapBlue(code));
244             break;
245 
246         case COLOR_XYZ2BGR:
247         case COLOR_XYZ2RGB:
248             cvtColorXYZ2BGR(_src, _dst, dcn, swapBlue(code));
249             break;
250 
251         case COLOR_BGR2HSV: case COLOR_BGR2HSV_FULL:
252         case COLOR_RGB2HSV: case COLOR_RGB2HSV_FULL:
253             cvtColorBGR2HSV(_src, _dst, swapBlue(code), isFullRangeHSV(code));
254             break;
255 
256         case COLOR_BGR2HLS: case COLOR_BGR2HLS_FULL:
257         case COLOR_RGB2HLS: case COLOR_RGB2HLS_FULL:
258             cvtColorBGR2HLS(_src, _dst, swapBlue(code), isFullRangeHSV(code));
259             break;
260 
261         case COLOR_HSV2BGR: case COLOR_HSV2BGR_FULL:
262         case COLOR_HSV2RGB: case COLOR_HSV2RGB_FULL:
263             cvtColorHSV2BGR(_src, _dst, dcn, swapBlue(code), isFullRangeHSV(code));
264             break;
265 
266         case COLOR_HLS2BGR: case COLOR_HLS2BGR_FULL:
267         case COLOR_HLS2RGB: case COLOR_HLS2RGB_FULL:
268             cvtColorHLS2BGR(_src, _dst, dcn, swapBlue(code), isFullRangeHSV(code));
269             break;
270 
271         case COLOR_BGR2Lab: case COLOR_LBGR2Lab:
272         case COLOR_RGB2Lab: case COLOR_LRGB2Lab:
273             cvtColorBGR2Lab(_src, _dst, swapBlue(code), is_sRGB(code));
274             break;
275 
276         case COLOR_BGR2Luv: case COLOR_LBGR2Luv:
277         case COLOR_RGB2Luv: case COLOR_LRGB2Luv:
278             cvtColorBGR2Luv(_src, _dst, swapBlue(code), is_sRGB(code));
279             break;
280 
281         case COLOR_Lab2BGR: case COLOR_Lab2LBGR:
282         case COLOR_Lab2RGB: case COLOR_Lab2LRGB:
283             cvtColorLab2BGR(_src, _dst, dcn, swapBlue(code), is_sRGB(code));
284             break;
285 
286         case COLOR_Luv2BGR: case COLOR_Luv2LBGR:
287         case COLOR_Luv2RGB: case COLOR_Luv2LRGB:
288             cvtColorLuv2BGR(_src, _dst, dcn, swapBlue(code), is_sRGB(code));
289             break;
290 
291         case COLOR_BayerBG2GRAY: case COLOR_BayerGB2GRAY: case COLOR_BayerRG2GRAY: case COLOR_BayerGR2GRAY:
292         case COLOR_BayerBG2BGR: case COLOR_BayerGB2BGR: case COLOR_BayerRG2BGR: case COLOR_BayerGR2BGR:
293         case COLOR_BayerBG2BGR_VNG: case COLOR_BayerGB2BGR_VNG: case COLOR_BayerRG2BGR_VNG: case COLOR_BayerGR2BGR_VNG:
294         case COLOR_BayerBG2BGR_EA: case COLOR_BayerGB2BGR_EA: case COLOR_BayerRG2BGR_EA: case COLOR_BayerGR2BGR_EA:
295         case COLOR_BayerBG2BGRA: case COLOR_BayerGB2BGRA: case COLOR_BayerRG2BGRA: case COLOR_BayerGR2BGRA:
296             {
297                 Mat src;
298                 if (_src.getObj() == _dst.getObj()) // inplace processing (#6653)
299                     _src.copyTo(src);
300                 else
301                     src = _src.getMat();
302                 demosaicing(src, _dst, code, dcn);
303                 break;
304             }
305 
306         case COLOR_YUV2BGR_NV21:  case COLOR_YUV2RGB_NV21:  case COLOR_YUV2BGR_NV12:  case COLOR_YUV2RGB_NV12:
307         case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
308             // http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples
309             // http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples
310             cvtColorTwoPlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code));
311             break;
312 
313         case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12:
314         case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
315             //http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.
316             //http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes
317             cvtColorThreePlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code));
318             break;
319 
320         case COLOR_YUV2GRAY_420:
321             cvtColorYUV2Gray_420(_src, _dst);
322             break;
323 
324         case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
325         case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
326             cvtColorBGR2ThreePlaneYUV(_src, _dst, swapBlue(code), uIndex(code));
327             break;
328 
329         case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY:
330         case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2: case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU:
331         case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
332             //http://www.fourcc.org/yuv.php#UYVY
333             //http://www.fourcc.org/yuv.php#YUY2
334             //http://www.fourcc.org/yuv.php#YVYU
335             {
336                 int ycn  = (code==COLOR_YUV2RGB_UYVY || code==COLOR_YUV2BGR_UYVY ||
337                             code==COLOR_YUV2RGBA_UYVY || code==COLOR_YUV2BGRA_UYVY) ? 1 : 0;
338                 cvtColorOnePlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code), ycn);
339                 break;
340             }
341 
342         case COLOR_YUV2GRAY_UYVY:
343         case COLOR_YUV2GRAY_YUY2:
344             cvtColorYUV2Gray_ch(_src, _dst, code == COLOR_YUV2GRAY_UYVY ? 1 : 0);
345             break;
346 
347         case COLOR_RGBA2mRGBA:
348             cvtColorRGBA2mRGBA(_src, _dst);
349             break;
350 
351         case COLOR_mRGBA2RGBA:
352             cvtColormRGBA2RGBA(_src, _dst);
353             break;
354         default:
355             CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
356     }
357 }
358 } //namespace cv
359 
360 
361 CV_IMPL void
cvCvtColor(const CvArr * srcarr,CvArr * dstarr,int code)362 cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code )
363 {
364     cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;
365     CV_Assert( src.depth() == dst.depth() );
366 
367     cv::cvtColor(src, dst, code, dst.channels());
368     CV_Assert( dst.data == dst0.data );
369 }
370