mirror of
https://github.com/opencv/opencv.git
synced 2026-07-26 22:03:04 +04:00
8b541e450b
Lab/XYZ modes have been postponed (color_lab.cpp): - need to split code for tables initialization and for pixels processing first - no significant performance improvements for switching between SSE42 / AVX2 code generation
367 lines
15 KiB
C++
367 lines
15 KiB
C++
// This file is part of OpenCV project.
|
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
// of this distribution and at http://opencv.org/license.html
|
|
|
|
#include "precomp.hpp"
|
|
#include "opencl_kernels_imgproc.hpp"
|
|
#include "color.hpp"
|
|
|
|
namespace cv
|
|
{
|
|
|
|
#ifdef HAVE_OPENCL
|
|
|
|
static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
|
|
{
|
|
int bidx = swapBlue(code) ? 2 : 0;
|
|
|
|
switch (code)
|
|
{
|
|
case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2BGR:
|
|
case COLOR_RGBA2BGR: case COLOR_RGB2BGR: case COLOR_BGRA2RGBA:
|
|
{
|
|
bool reverse = !(code == COLOR_BGR2BGRA || code == COLOR_BGRA2BGR);
|
|
return oclCvtColorBGR2BGR(_src, _dst, dcn, reverse);
|
|
}
|
|
case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652RGB: case COLOR_BGR5552RGB:
|
|
case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
|
|
return oclCvtColor5x52BGR(_src, _dst, dcn, bidx, greenBits(code));
|
|
|
|
case COLOR_BGR2BGR565: case COLOR_BGR2BGR555: case COLOR_RGB2BGR565: case COLOR_RGB2BGR555:
|
|
case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555: case COLOR_RGBA2BGR565: case COLOR_RGBA2BGR555:
|
|
return oclCvtColorBGR25x5(_src, _dst, bidx, greenBits(code) );
|
|
|
|
case COLOR_BGR5652GRAY: case COLOR_BGR5552GRAY:
|
|
return oclCvtColor5x52Gray(_src, _dst, greenBits(code));
|
|
|
|
case COLOR_GRAY2BGR565: case COLOR_GRAY2BGR555:
|
|
return oclCvtColorGray25x5(_src, _dst, greenBits(code));
|
|
|
|
case COLOR_BGR2GRAY: case COLOR_BGRA2GRAY:
|
|
case COLOR_RGB2GRAY: case COLOR_RGBA2GRAY:
|
|
return oclCvtColorBGR2Gray(_src, _dst, bidx);
|
|
|
|
case COLOR_GRAY2BGR:
|
|
case COLOR_GRAY2BGRA:
|
|
return oclCvtColorGray2BGR(_src, _dst, dcn);
|
|
|
|
case COLOR_BGR2YUV:
|
|
case COLOR_RGB2YUV:
|
|
return oclCvtColorBGR2YUV(_src, _dst, bidx);
|
|
|
|
case COLOR_YUV2BGR:
|
|
case COLOR_YUV2RGB:
|
|
return oclCvtColorYUV2BGR(_src, _dst, dcn, bidx);
|
|
|
|
case COLOR_YUV2RGB_NV12: case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGR_NV21:
|
|
case COLOR_YUV2RGBA_NV12: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV21:
|
|
{
|
|
int uidx = code == COLOR_YUV2RGBA_NV21 || code == COLOR_YUV2RGB_NV21 ||
|
|
code == COLOR_YUV2BGRA_NV21 || code == COLOR_YUV2BGR_NV21 ? 1 : 0;
|
|
return oclCvtColorTwoPlaneYUV2BGR(_src, _dst, dcn, bidx, uidx);
|
|
}
|
|
case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12:
|
|
case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
|
|
{
|
|
int uidx = code == COLOR_YUV2BGRA_YV12 || code == COLOR_YUV2BGR_YV12 ||
|
|
code == COLOR_YUV2RGBA_YV12 || code == COLOR_YUV2RGB_YV12 ? 1 : 0;
|
|
return oclCvtColorThreePlaneYUV2BGR(_src, _dst, dcn, bidx, uidx);
|
|
}
|
|
case COLOR_YUV2GRAY_420:
|
|
{
|
|
return oclCvtColorYUV2Gray_420(_src, _dst);
|
|
}
|
|
case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
|
|
case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
|
|
{
|
|
int uidx = code == COLOR_RGBA2YUV_YV12 || code == COLOR_RGB2YUV_YV12 ||
|
|
code == COLOR_BGRA2YUV_YV12 || code == COLOR_BGR2YUV_YV12 ? 1 : 0;
|
|
return oclCvtColorBGR2ThreePlaneYUV(_src, _dst, bidx, uidx );
|
|
}
|
|
case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY:
|
|
case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2: case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU:
|
|
case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
|
|
{
|
|
int yidx = (code==COLOR_YUV2RGB_UYVY || code==COLOR_YUV2RGBA_UYVY ||
|
|
code==COLOR_YUV2BGR_UYVY || code==COLOR_YUV2BGRA_UYVY) ? 1 : 0;
|
|
int uidx = (code==COLOR_YUV2RGB_YVYU || code==COLOR_YUV2RGBA_YVYU ||
|
|
code==COLOR_YUV2BGR_YVYU || code==COLOR_YUV2BGRA_YVYU) ? 2 : 0;
|
|
uidx = 1 - yidx + uidx;
|
|
|
|
return oclCvtColorOnePlaneYUV2BGR(_src, _dst, dcn, bidx, uidx, yidx);
|
|
}
|
|
case COLOR_BGR2YCrCb:
|
|
case COLOR_RGB2YCrCb:
|
|
return oclCvtColorBGR2YCrCb(_src, _dst, bidx);
|
|
|
|
case COLOR_YCrCb2BGR:
|
|
case COLOR_YCrCb2RGB:
|
|
return oclCvtcolorYCrCb2BGR(_src, _dst, dcn, bidx);
|
|
|
|
case COLOR_BGR2XYZ:
|
|
case COLOR_RGB2XYZ:
|
|
return oclCvtColorBGR2XYZ(_src, _dst, bidx);
|
|
|
|
case COLOR_XYZ2BGR:
|
|
case COLOR_XYZ2RGB:
|
|
return oclCvtColorXYZ2BGR(_src, _dst, dcn, bidx);
|
|
|
|
case COLOR_BGR2HSV: case COLOR_BGR2HSV_FULL:
|
|
case COLOR_RGB2HSV: case COLOR_RGB2HSV_FULL:
|
|
return oclCvtColorBGR2HSV(_src, _dst, bidx, isFullRangeHSV(code));
|
|
|
|
case COLOR_BGR2HLS: case COLOR_BGR2HLS_FULL:
|
|
case COLOR_RGB2HLS: case COLOR_RGB2HLS_FULL:
|
|
return oclCvtColorBGR2HLS(_src, _dst, bidx, isFullRangeHSV(code));
|
|
|
|
case COLOR_HSV2BGR: case COLOR_HSV2BGR_FULL:
|
|
case COLOR_HSV2RGB: case COLOR_HSV2RGB_FULL:
|
|
return oclCvtColorHSV2BGR(_src, _dst, dcn, bidx, isFullRangeHSV(code));
|
|
|
|
case COLOR_HLS2BGR: case COLOR_HLS2BGR_FULL:
|
|
case COLOR_HLS2RGB: case COLOR_HLS2RGB_FULL:
|
|
return oclCvtColorHLS2BGR(_src, _dst, dcn, bidx, isFullRangeHSV(code));
|
|
|
|
case COLOR_RGBA2mRGBA:
|
|
return oclCvtColorRGBA2mRGBA(_src, _dst);
|
|
|
|
case COLOR_mRGBA2RGBA:
|
|
return oclCvtColormRGBA2RGBA(_src, _dst);
|
|
|
|
case COLOR_BGR2Lab: case COLOR_LBGR2Lab:
|
|
case COLOR_RGB2Lab: case COLOR_LRGB2Lab:
|
|
return oclCvtColorBGR2Lab(_src, _dst, bidx, is_sRGB(code));
|
|
|
|
case COLOR_BGR2Luv: case COLOR_LBGR2Luv:
|
|
case COLOR_RGB2Luv: case COLOR_LRGB2Luv:
|
|
return oclCvtColorBGR2Luv(_src, _dst, bidx, is_sRGB(code));
|
|
|
|
case COLOR_Lab2BGR: case COLOR_Lab2LBGR:
|
|
case COLOR_Lab2RGB: case COLOR_Lab2LRGB:
|
|
return oclCvtColorLab2BGR(_src, _dst, dcn, bidx, is_sRGB(code));
|
|
|
|
case COLOR_Luv2BGR: case COLOR_Luv2LBGR:
|
|
case COLOR_Luv2RGB: case COLOR_Luv2LRGB:
|
|
return oclCvtColorLuv2BGR(_src, _dst, dcn, bidx, is_sRGB(code));
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
// helper function for dual-plane modes
|
|
|
|
void cvtColorTwoPlane( InputArray _ysrc, InputArray _uvsrc, OutputArray _dst, int code )
|
|
{
|
|
// only YUV420 is currently supported
|
|
switch (code)
|
|
{
|
|
case COLOR_YUV2BGR_NV21: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV12:
|
|
case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
|
|
break;
|
|
default:
|
|
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
|
|
return;
|
|
}
|
|
|
|
cvtColorTwoPlaneYUV2BGRpair(_ysrc, _uvsrc, _dst, dstChannels(code), swapBlue(code), uIndex(code));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// The main function //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
|
|
{
|
|
CV_INSTRUMENT_REGION();
|
|
|
|
CV_Assert(!_src.empty());
|
|
|
|
if(dcn <= 0)
|
|
dcn = dstChannels(code);
|
|
|
|
CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() &&
|
|
!(CV_MAT_DEPTH(_src.type()) == CV_8U && (code == COLOR_Luv2BGR || code == COLOR_Luv2RGB)),
|
|
ocl_cvtColor(_src, _dst, code, dcn) )
|
|
|
|
switch( code )
|
|
{
|
|
case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2BGR:
|
|
case COLOR_RGBA2BGR: case COLOR_RGB2BGR: case COLOR_BGRA2RGBA:
|
|
cvtColorBGR2BGR(_src, _dst, dcn, swapBlue(code));
|
|
break;
|
|
|
|
case COLOR_BGR2BGR565: case COLOR_BGR2BGR555: case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555:
|
|
case COLOR_RGB2BGR565: case COLOR_RGB2BGR555: case COLOR_RGBA2BGR565: case COLOR_RGBA2BGR555:
|
|
cvtColorBGR25x5(_src, _dst, swapBlue(code), greenBits(code));
|
|
break;
|
|
|
|
case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA:
|
|
case COLOR_BGR5652RGB: case COLOR_BGR5552RGB: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
|
|
cvtColor5x52BGR(_src, _dst, dcn, swapBlue(code), greenBits(code));
|
|
break;
|
|
|
|
case COLOR_BGR2GRAY: case COLOR_BGRA2GRAY:
|
|
case COLOR_RGB2GRAY: case COLOR_RGBA2GRAY:
|
|
cvtColorBGR2Gray(_src, _dst, swapBlue(code));
|
|
break;
|
|
|
|
case COLOR_BGR5652GRAY:
|
|
case COLOR_BGR5552GRAY:
|
|
cvtColor5x52Gray(_src, _dst, greenBits(code));
|
|
break;
|
|
|
|
case COLOR_GRAY2BGR:
|
|
case COLOR_GRAY2BGRA:
|
|
cvtColorGray2BGR(_src, _dst, dcn);
|
|
break;
|
|
|
|
case COLOR_GRAY2BGR565:
|
|
case COLOR_GRAY2BGR555:
|
|
cvtColorGray25x5(_src, _dst, greenBits(code));
|
|
break;
|
|
|
|
case COLOR_BGR2YCrCb: case COLOR_RGB2YCrCb:
|
|
case COLOR_BGR2YUV: case COLOR_RGB2YUV:
|
|
cvtColorBGR2YUV(_src, _dst, swapBlue(code), code == COLOR_BGR2YCrCb || code == COLOR_RGB2YCrCb);
|
|
break;
|
|
|
|
case COLOR_YCrCb2BGR: case COLOR_YCrCb2RGB:
|
|
case COLOR_YUV2BGR: case COLOR_YUV2RGB:
|
|
cvtColorYUV2BGR(_src, _dst, dcn, swapBlue(code), code == COLOR_YCrCb2BGR || code == COLOR_YCrCb2RGB);
|
|
break;
|
|
|
|
case COLOR_BGR2XYZ:
|
|
case COLOR_RGB2XYZ:
|
|
cvtColorBGR2XYZ(_src, _dst, swapBlue(code));
|
|
break;
|
|
|
|
case COLOR_XYZ2BGR:
|
|
case COLOR_XYZ2RGB:
|
|
cvtColorXYZ2BGR(_src, _dst, dcn, swapBlue(code));
|
|
break;
|
|
|
|
case COLOR_BGR2HSV: case COLOR_BGR2HSV_FULL:
|
|
case COLOR_RGB2HSV: case COLOR_RGB2HSV_FULL:
|
|
cvtColorBGR2HSV(_src, _dst, swapBlue(code), isFullRangeHSV(code));
|
|
break;
|
|
|
|
case COLOR_BGR2HLS: case COLOR_BGR2HLS_FULL:
|
|
case COLOR_RGB2HLS: case COLOR_RGB2HLS_FULL:
|
|
cvtColorBGR2HLS(_src, _dst, swapBlue(code), isFullRangeHSV(code));
|
|
break;
|
|
|
|
case COLOR_HSV2BGR: case COLOR_HSV2BGR_FULL:
|
|
case COLOR_HSV2RGB: case COLOR_HSV2RGB_FULL:
|
|
cvtColorHSV2BGR(_src, _dst, dcn, swapBlue(code), isFullRangeHSV(code));
|
|
break;
|
|
|
|
case COLOR_HLS2BGR: case COLOR_HLS2BGR_FULL:
|
|
case COLOR_HLS2RGB: case COLOR_HLS2RGB_FULL:
|
|
cvtColorHLS2BGR(_src, _dst, dcn, swapBlue(code), isFullRangeHSV(code));
|
|
break;
|
|
|
|
case COLOR_BGR2Lab: case COLOR_LBGR2Lab:
|
|
case COLOR_RGB2Lab: case COLOR_LRGB2Lab:
|
|
cvtColorBGR2Lab(_src, _dst, swapBlue(code), is_sRGB(code));
|
|
break;
|
|
|
|
case COLOR_BGR2Luv: case COLOR_LBGR2Luv:
|
|
case COLOR_RGB2Luv: case COLOR_LRGB2Luv:
|
|
cvtColorBGR2Luv(_src, _dst, swapBlue(code), is_sRGB(code));
|
|
break;
|
|
|
|
case COLOR_Lab2BGR: case COLOR_Lab2LBGR:
|
|
case COLOR_Lab2RGB: case COLOR_Lab2LRGB:
|
|
cvtColorLab2BGR(_src, _dst, dcn, swapBlue(code), is_sRGB(code));
|
|
break;
|
|
|
|
case COLOR_Luv2BGR: case COLOR_Luv2LBGR:
|
|
case COLOR_Luv2RGB: case COLOR_Luv2LRGB:
|
|
cvtColorLuv2BGR(_src, _dst, dcn, swapBlue(code), is_sRGB(code));
|
|
break;
|
|
|
|
case COLOR_BayerBG2GRAY: case COLOR_BayerGB2GRAY: case COLOR_BayerRG2GRAY: case COLOR_BayerGR2GRAY:
|
|
case COLOR_BayerBG2BGR: case COLOR_BayerGB2BGR: case COLOR_BayerRG2BGR: case COLOR_BayerGR2BGR:
|
|
case COLOR_BayerBG2BGR_VNG: case COLOR_BayerGB2BGR_VNG: case COLOR_BayerRG2BGR_VNG: case COLOR_BayerGR2BGR_VNG:
|
|
case COLOR_BayerBG2BGR_EA: case COLOR_BayerGB2BGR_EA: case COLOR_BayerRG2BGR_EA: case COLOR_BayerGR2BGR_EA:
|
|
case COLOR_BayerBG2BGRA: case COLOR_BayerGB2BGRA: case COLOR_BayerRG2BGRA: case COLOR_BayerGR2BGRA:
|
|
{
|
|
Mat src;
|
|
if (_src.getObj() == _dst.getObj()) // inplace processing (#6653)
|
|
_src.copyTo(src);
|
|
else
|
|
src = _src.getMat();
|
|
demosaicing(src, _dst, code, dcn);
|
|
break;
|
|
}
|
|
|
|
case COLOR_YUV2BGR_NV21: case COLOR_YUV2RGB_NV21: case COLOR_YUV2BGR_NV12: case COLOR_YUV2RGB_NV12:
|
|
case COLOR_YUV2BGRA_NV21: case COLOR_YUV2RGBA_NV21: case COLOR_YUV2BGRA_NV12: case COLOR_YUV2RGBA_NV12:
|
|
// 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
|
|
// 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
|
|
cvtColorTwoPlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code));
|
|
break;
|
|
|
|
case COLOR_YUV2BGR_YV12: case COLOR_YUV2RGB_YV12: case COLOR_YUV2BGRA_YV12: case COLOR_YUV2RGBA_YV12:
|
|
case COLOR_YUV2BGR_IYUV: case COLOR_YUV2RGB_IYUV: case COLOR_YUV2BGRA_IYUV: case COLOR_YUV2RGBA_IYUV:
|
|
//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.
|
|
//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
|
|
cvtColorThreePlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code));
|
|
break;
|
|
|
|
case COLOR_YUV2GRAY_420:
|
|
cvtColorYUV2Gray_420(_src, _dst);
|
|
break;
|
|
|
|
case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
|
|
case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
|
|
cvtColorBGR2ThreePlaneYUV(_src, _dst, swapBlue(code), uIndex(code));
|
|
break;
|
|
|
|
case COLOR_YUV2RGB_UYVY: case COLOR_YUV2BGR_UYVY: case COLOR_YUV2RGBA_UYVY: case COLOR_YUV2BGRA_UYVY:
|
|
case COLOR_YUV2RGB_YUY2: case COLOR_YUV2BGR_YUY2: case COLOR_YUV2RGB_YVYU: case COLOR_YUV2BGR_YVYU:
|
|
case COLOR_YUV2RGBA_YUY2: case COLOR_YUV2BGRA_YUY2: case COLOR_YUV2RGBA_YVYU: case COLOR_YUV2BGRA_YVYU:
|
|
//http://www.fourcc.org/yuv.php#UYVY
|
|
//http://www.fourcc.org/yuv.php#YUY2
|
|
//http://www.fourcc.org/yuv.php#YVYU
|
|
{
|
|
int ycn = (code==COLOR_YUV2RGB_UYVY || code==COLOR_YUV2BGR_UYVY ||
|
|
code==COLOR_YUV2RGBA_UYVY || code==COLOR_YUV2BGRA_UYVY) ? 1 : 0;
|
|
cvtColorOnePlaneYUV2BGR(_src, _dst, dcn, swapBlue(code), uIndex(code), ycn);
|
|
break;
|
|
}
|
|
|
|
case COLOR_YUV2GRAY_UYVY:
|
|
case COLOR_YUV2GRAY_YUY2:
|
|
cvtColorYUV2Gray_ch(_src, _dst, code == COLOR_YUV2GRAY_UYVY ? 1 : 0);
|
|
break;
|
|
|
|
case COLOR_RGBA2mRGBA:
|
|
cvtColorRGBA2mRGBA(_src, _dst);
|
|
break;
|
|
|
|
case COLOR_mRGBA2RGBA:
|
|
cvtColormRGBA2RGBA(_src, _dst);
|
|
break;
|
|
default:
|
|
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
|
|
}
|
|
}
|
|
} //namespace cv
|
|
|
|
|
|
CV_IMPL void
|
|
cvCvtColor( const CvArr* srcarr, CvArr* dstarr, int code )
|
|
{
|
|
cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;
|
|
CV_Assert( src.depth() == dst.depth() );
|
|
|
|
cv::cvtColor(src, dst, code, dst.channels());
|
|
CV_Assert( dst.data == dst0.data );
|
|
}
|