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