Commit 19e4c772 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #7546 from savuor:fix2.4/yuv_channel_order

parents f2a59b3d d23190dc
...@@ -102,6 +102,38 @@ static IppStatus sts = ippInit(); ...@@ -102,6 +102,38 @@ static IppStatus sts = ippInit();
namespace cv namespace cv
{ {
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
const float B2YF = 0.114f;
const float G2YF = 0.587f;
const float R2YF = 0.299f;
//to YCbCr
const float YCBF = 0.564f; // == 1/2/(1-B2YF)
const float YCRF = 0.713f; // == 1/2/(1-R2YF)
const int YCBI = 9241; // == YCBF*16384
const int YCRI = 11682; // == YCRF*16384
//to YUV
const float B2UF = 0.492f;
const float R2VF = 0.877f;
const int B2UI = 8061; // == B2UF*16384
const int R2VI = 14369; // == R2VF*16384
//from YUV
const float U2BF = 2.032f;
const float U2GF = -0.395f;
const float V2GF = -0.581f;
const float V2RF = 1.140f;
const int U2BI = 33292;
const int U2GI = -6472;
const int V2GI = -9519;
const int V2RI = 18678;
//from YCrCb
const float CR2RF = 1.403f;
const float CB2GF = -0.344f;
const float CR2GF = -0.714f;
const float CB2BF = 1.773f;
const int CR2RI = 22987;
const int CB2GI = -5636;
const int CR2GI = -11698;
const int CB2BI = 29049;
// computes cubic spline coefficients for a function: (xi=i, yi=f[i]), i=0..n // computes cubic spline coefficients for a function: (xi=i, yi=f[i]), i=0..n
template<typename _Tp> static void splineBuild(const _Tp* f, int n, _Tp* tab) template<typename _Tp> static void splineBuild(const _Tp* f, int n, _Tp* tab)
...@@ -402,9 +434,9 @@ struct IPPColor2GrayFunctor ...@@ -402,9 +434,9 @@ struct IPPColor2GrayFunctor
{ {
IPPColor2GrayFunctor(ippiColor2GrayFunc _func) : func(_func) IPPColor2GrayFunctor(ippiColor2GrayFunc _func) : func(_func)
{ {
coeffs[0] = 0.114f; coeffs[0] = B2YF;
coeffs[1] = 0.587f; coeffs[1] = G2YF;
coeffs[2] = 0.299f; coeffs[2] = R2YF;
} }
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
{ {
...@@ -668,9 +700,9 @@ enum ...@@ -668,9 +700,9 @@ enum
{ {
yuv_shift = 14, yuv_shift = 14,
xyz_shift = 12, xyz_shift = 12,
R2Y = 4899, R2Y = 4899, // B2YF*16384
G2Y = 9617, G2Y = 9617, // G2YF*16384
B2Y = 1868, B2Y = 1868, // B2YF*16384
BLOCK_SIZE = 256 BLOCK_SIZE = 256
}; };
...@@ -709,7 +741,7 @@ template<typename _Tp> struct RGB2Gray ...@@ -709,7 +741,7 @@ template<typename _Tp> struct RGB2Gray
RGB2Gray(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn) RGB2Gray(int _srccn, int blueIdx, const float* _coeffs) : srccn(_srccn)
{ {
static const float coeffs0[] = { 0.299f, 0.587f, 0.114f }; static const float coeffs0[] = { R2YF, G2YF, B2YF };
memcpy( coeffs, _coeffs ? _coeffs : coeffs0, 3*sizeof(coeffs[0]) ); memcpy( coeffs, _coeffs ? _coeffs : coeffs0, 3*sizeof(coeffs[0]) );
if(blueIdx == 0) if(blueIdx == 0)
std::swap(coeffs[0], coeffs[2]); std::swap(coeffs[0], coeffs[2]);
...@@ -787,16 +819,18 @@ template<typename _Tp> struct RGB2YCrCb_f ...@@ -787,16 +819,18 @@ template<typename _Tp> struct RGB2YCrCb_f
{ {
typedef _Tp channel_type; typedef _Tp channel_type;
RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx) RGB2YCrCb_f(int _srccn, int _blueIdx, bool _isCrCb) : srccn(_srccn), blueIdx(_blueIdx), isCrCb(_isCrCb)
{ {
static const float coeffs0[] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f}; static const float coeffs_crb[] = { R2YF, G2YF, B2YF, YCRF, YCBF };
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0])); static const float coeffs_yuv[] = { R2YF, G2YF, B2YF, R2VF, B2UF };
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 5*sizeof(coeffs[0]));
if(blueIdx==0) std::swap(coeffs[0], coeffs[2]); if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
} }
void operator()(const _Tp* src, _Tp* dst, int n) const void operator()(const _Tp* src, _Tp* dst, int n) const
{ {
int scn = srccn, bidx = blueIdx; int scn = srccn, bidx = blueIdx;
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
const _Tp delta = ColorChannel<_Tp>::half(); const _Tp delta = ColorChannel<_Tp>::half();
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4]; float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
n *= 3; n *= 3;
...@@ -805,10 +839,11 @@ template<typename _Tp> struct RGB2YCrCb_f ...@@ -805,10 +839,11 @@ template<typename _Tp> struct RGB2YCrCb_f
_Tp Y = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2); _Tp Y = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2);
_Tp Cr = saturate_cast<_Tp>((src[bidx^2] - Y)*C3 + delta); _Tp Cr = saturate_cast<_Tp>((src[bidx^2] - Y)*C3 + delta);
_Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta); _Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta);
dst[i] = Y; dst[i+1] = Cr; dst[i+2] = Cb; dst[i] = Y; dst[i+1+yuvOrder] = Cr; dst[i+2-yuvOrder] = Cb;
} }
} }
int srccn, blueIdx; int srccn, blueIdx;
bool isCrCb;
float coeffs[5]; float coeffs[5];
}; };
...@@ -817,16 +852,18 @@ template<typename _Tp> struct RGB2YCrCb_i ...@@ -817,16 +852,18 @@ template<typename _Tp> struct RGB2YCrCb_i
{ {
typedef _Tp channel_type; typedef _Tp channel_type;
RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs) RGB2YCrCb_i(int _srccn, int _blueIdx, bool _isCrCb)
: srccn(_srccn), blueIdx(_blueIdx) : srccn(_srccn), blueIdx(_blueIdx), isCrCb(_isCrCb)
{ {
static const int coeffs0[] = {R2Y, G2Y, B2Y, 11682, 9241}; static const int coeffs_crb[] = { R2Y, G2Y, B2Y, YCRI, YCBI };
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0])); static const int coeffs_yuv[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 5*sizeof(coeffs[0]));
if(blueIdx==0) std::swap(coeffs[0], coeffs[2]); if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
} }
void operator()(const _Tp* src, _Tp* dst, int n) const void operator()(const _Tp* src, _Tp* dst, int n) const
{ {
int scn = srccn, bidx = blueIdx; int scn = srccn, bidx = blueIdx;
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4]; int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift); int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
n *= 3; n *= 3;
...@@ -836,11 +873,12 @@ template<typename _Tp> struct RGB2YCrCb_i ...@@ -836,11 +873,12 @@ template<typename _Tp> struct RGB2YCrCb_i
int Cr = CV_DESCALE((src[bidx^2] - Y)*C3 + delta, yuv_shift); int Cr = CV_DESCALE((src[bidx^2] - Y)*C3 + delta, yuv_shift);
int Cb = CV_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift); int Cb = CV_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift);
dst[i] = saturate_cast<_Tp>(Y); dst[i] = saturate_cast<_Tp>(Y);
dst[i+1] = saturate_cast<_Tp>(Cr); dst[i+1+yuvOrder] = saturate_cast<_Tp>(Cr);
dst[i+2] = saturate_cast<_Tp>(Cb); dst[i+2-yuvOrder] = saturate_cast<_Tp>(Cb);
} }
} }
int srccn, blueIdx; int srccn, blueIdx;
bool isCrCb;
int coeffs[5]; int coeffs[5];
}; };
...@@ -849,23 +887,25 @@ template<typename _Tp> struct YCrCb2RGB_f ...@@ -849,23 +887,25 @@ template<typename _Tp> struct YCrCb2RGB_f
{ {
typedef _Tp channel_type; typedef _Tp channel_type;
YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs) YCrCb2RGB_f(int _dstcn, int _blueIdx, bool _isCrCb)
: dstcn(_dstcn), blueIdx(_blueIdx) : dstcn(_dstcn), blueIdx(_blueIdx), isCrCb(_isCrCb)
{ {
static const float coeffs0[] = {1.403f, -0.714f, -0.344f, 1.773f}; static const float coeffs_cbr[] = {CR2RF, CR2GF, CB2GF, CB2BF};
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0])); static const float coeffs_yuv[] = { V2RF, V2GF, U2GF, U2BF};
memcpy(coeffs, isCrCb ? coeffs_cbr : coeffs_yuv, 4*sizeof(coeffs[0]));
} }
void operator()(const _Tp* src, _Tp* dst, int n) const void operator()(const _Tp* src, _Tp* dst, int n) const
{ {
int dcn = dstcn, bidx = blueIdx; int dcn = dstcn, bidx = blueIdx;
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max(); const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3]; float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
n *= 3; n *= 3;
for(int i = 0; i < n; i += 3, dst += dcn) for(int i = 0; i < n; i += 3, dst += dcn)
{ {
_Tp Y = src[i]; _Tp Y = src[i];
_Tp Cr = src[i+1]; _Tp Cr = src[i+1+yuvOrder];
_Tp Cb = src[i+2]; _Tp Cb = src[i+2-yuvOrder];
_Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3); _Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
_Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1); _Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
...@@ -877,6 +917,7 @@ template<typename _Tp> struct YCrCb2RGB_f ...@@ -877,6 +917,7 @@ template<typename _Tp> struct YCrCb2RGB_f
} }
} }
int dstcn, blueIdx; int dstcn, blueIdx;
bool isCrCb;
float coeffs[4]; float coeffs[4];
}; };
...@@ -885,24 +926,26 @@ template<typename _Tp> struct YCrCb2RGB_i ...@@ -885,24 +926,26 @@ template<typename _Tp> struct YCrCb2RGB_i
{ {
typedef _Tp channel_type; typedef _Tp channel_type;
YCrCb2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs) YCrCb2RGB_i(int _dstcn, int _blueIdx, bool _isCrCb)
: dstcn(_dstcn), blueIdx(_blueIdx) : dstcn(_dstcn), blueIdx(_blueIdx), isCrCb(_isCrCb)
{ {
static const int coeffs0[] = {22987, -11698, -5636, 29049}; static const int coeffs_crb[] = { CR2RI, CR2GI, CB2GI, CB2BI};
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0])); static const int coeffs_yuv[] = { V2RI, V2GI, U2GI, U2BI };
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 4*sizeof(coeffs[0]));
} }
void operator()(const _Tp* src, _Tp* dst, int n) const void operator()(const _Tp* src, _Tp* dst, int n) const
{ {
int dcn = dstcn, bidx = blueIdx; int dcn = dstcn, bidx = blueIdx;
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max(); const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3]; int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
n *= 3; n *= 3;
for(int i = 0; i < n; i += 3, dst += dcn) for(int i = 0; i < n; i += 3, dst += dcn)
{ {
_Tp Y = src[i]; _Tp Y = src[i];
_Tp Cr = src[i+1]; _Tp Cr = src[i+1+yuvOrder];
_Tp Cb = src[i+2]; _Tp Cb = src[i+2-yuvOrder];
int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift); int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift);
int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift); int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
...@@ -916,6 +959,7 @@ template<typename _Tp> struct YCrCb2RGB_i ...@@ -916,6 +959,7 @@ template<typename _Tp> struct YCrCb2RGB_i
} }
} }
int dstcn, blueIdx; int dstcn, blueIdx;
bool isCrCb;
int coeffs[4]; int coeffs[4];
}; };
...@@ -3832,10 +3876,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) ...@@ -3832,10 +3876,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
{ {
CV_Assert( scn == 3 || scn == 4 ); CV_Assert( scn == 3 || scn == 4 );
bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2; bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2;
static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; const bool isCrCb = (code == CV_BGR2YCrCb || code == CV_RGB2YCrCb);
static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
_dst.create(sz, CV_MAKETYPE(depth, 3)); _dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat(); dst = _dst.getMat();
...@@ -3846,12 +3887,12 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) ...@@ -3846,12 +3887,12 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb(src, dst, bidx)) if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb(src, dst, bidx))
break; break;
#endif #endif
CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i)); CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, isCrCb));
} }
else if( depth == CV_16U ) else if( depth == CV_16U )
CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, coeffs_i)); CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, isCrCb));
else else
CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f)); CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, isCrCb));
} }
break; break;
...@@ -3861,20 +3902,17 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) ...@@ -3861,20 +3902,17 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
if( dcn <= 0 ) dcn = 3; if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2; bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2;
static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; const bool isCrCb = (code == CV_YCrCb2BGR || code == CV_YCrCb2RGB);
static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
_dst.create(sz, CV_MAKETYPE(depth, dcn)); _dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat(); dst = _dst.getMat();
if( depth == CV_8U ) if( depth == CV_8U )
CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i)); CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, isCrCb));
else if( depth == CV_16U ) else if( depth == CV_16U )
CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, coeffs_i)); CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, isCrCb));
else else
CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, coeffs_f)); CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, isCrCb));
} }
break; break;
......
...@@ -115,9 +115,42 @@ enum ...@@ -115,9 +115,42 @@ enum
BLOCK_SIZE = 256 BLOCK_SIZE = 256
}; };
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
#define B2YF 0.114f
#define G2YF 0.587f
#define R2YF 0.299f
//to YCbCr
#define YCBF 0.564f
#define YCRF 0.713f
#define YCBI 9241
#define YCRI 11682
//to YUV
#define B2UF 0.492f
#define R2VF 0.877f
#define B2UI 8061
#define R2VI 14369
//from YUV
#define U2BF 2.032f
#define U2GF -0.395f
#define V2GF -0.581f
#define V2RF 1.140f
#define U2BI 33292
#define U2GI -6472
#define V2GI -9519
#define V2RI 18678
//from YCrCb
#define CR2RF 1.403f
#define CB2GF -0.344f
#define CR2GF -0.714f
#define CB2BF 1.773f
#define CR2RI 22987
#define CB2GI -5636
#define CR2GI -11698
#define CB2BI 29049
///////////////////////////////////// RGB <-> GRAY ////////////////////////////////////// ///////////////////////////////////// RGB <-> GRAY //////////////////////////////////////
__constant float c_RGB2GrayCoeffs_f[3] = { 0.114f, 0.587f, 0.299f }; __constant float c_RGB2GrayCoeffs_f[3] = { B2YF, G2YF, R2YF };
__constant int c_RGB2GrayCoeffs_i[3] = { B2Y, G2Y, R2Y }; __constant int c_RGB2GrayCoeffs_i[3] = { B2Y, G2Y, R2Y };
__kernel void RGB2Gray(int cols, int rows, int src_step, int dst_step, __kernel void RGB2Gray(int cols, int rows, int src_step, int dst_step,
...@@ -135,7 +168,7 @@ __kernel void RGB2Gray(int cols, int rows, int src_step, int dst_step, ...@@ -135,7 +168,7 @@ __kernel void RGB2Gray(int cols, int rows, int src_step, int dst_step,
#ifndef INTEL_DEVICE #ifndef INTEL_DEVICE
#ifdef DEPTH_5 #ifdef DEPTH_5
dst[dst_idx] = src[src_idx + bidx] * 0.114f + src[src_idx + 1] * 0.587f + src[src_idx + (bidx^2)] * 0.299f; dst[dst_idx] = src[src_idx + bidx] * B2YF + src[src_idx + 1] * G2YF + src[src_idx + (bidx^2)] * R2YF;
#else #else
dst[dst_idx] = (DATA_TYPE)CV_DESCALE((src[src_idx + bidx] * B2Y + src[src_idx + 1] * G2Y + src[src_idx + (bidx^2)] * R2Y), yuv_shift); dst[dst_idx] = (DATA_TYPE)CV_DESCALE((src[src_idx + bidx] * B2Y + src[src_idx + 1] * G2Y + src[src_idx + (bidx^2)] * R2Y), yuv_shift);
#endif #endif
...@@ -221,8 +254,8 @@ __kernel void Gray2RGB(int cols, int rows, int src_step, int dst_step, ...@@ -221,8 +254,8 @@ __kernel void Gray2RGB(int cols, int rows, int src_step, int dst_step,
///////////////////////////////////// RGB <-> YUV ////////////////////////////////////// ///////////////////////////////////// RGB <-> YUV //////////////////////////////////////
__constant float c_RGB2YUVCoeffs_f[5] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; __constant float c_RGB2YUVCoeffs_f[5] = { B2YF, G2YF, R2YF, B2UF, R2VF };
__constant int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, 8061, 14369 }; __constant int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, B2UI, R2VI };
__kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step, __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
__global const DATA_TYPE* src, __global DATA_TYPE* dst, __global const DATA_TYPE* src, __global DATA_TYPE* dst,
...@@ -252,13 +285,13 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step, ...@@ -252,13 +285,13 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
const DATA_TYPE rgb[] = {src_ptr[0], src_ptr[1], src_ptr[2]}; const DATA_TYPE rgb[] = {src_ptr[0], src_ptr[1], src_ptr[2]};
#ifdef DEPTH_5 #ifdef DEPTH_5
float Y = rgb[0] * coeffs[bidx^2] + rgb[1] * coeffs[1] + rgb[2] * coeffs[bidx]; float Y = rgb[0] * coeffs[bidx] + rgb[1] * coeffs[1] + rgb[2] * coeffs[bidx^2];
float U = (rgb[bidx^2] - Y) * coeffs[3] + HALF_MAX; float U = (rgb[bidx] - Y) * coeffs[3] + HALF_MAX;
float V = (rgb[bidx] - Y) * coeffs[4] + HALF_MAX; float V = (rgb[bidx^2] - Y) * coeffs[4] + HALF_MAX;
#else #else
int Y = CV_DESCALE(rgb[0] * coeffs[bidx^2] + rgb[1] * coeffs[1] + rgb[2] * coeffs[bidx], yuv_shift); int Y = CV_DESCALE(rgb[0] * coeffs[bidx] + rgb[1] * coeffs[1] + rgb[2] * coeffs[bidx^2], yuv_shift);
int U = CV_DESCALE((rgb[bidx^2] - Y) * coeffs[3] + delta, yuv_shift); int U = CV_DESCALE((rgb[bidx] - Y) * coeffs[3] + delta, yuv_shift);
int V = CV_DESCALE((rgb[bidx] - Y) * coeffs[4] + delta, yuv_shift); int V = CV_DESCALE((rgb[bidx^2] - Y) * coeffs[4] + delta, yuv_shift);
#endif #endif
dst_ptr[0] = SAT_CAST( Y ); dst_ptr[0] = SAT_CAST( Y );
...@@ -274,23 +307,22 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step, ...@@ -274,23 +307,22 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
const float2 c1 = r0.s15; const float2 c1 = r0.s15;
const float2 c2 = r0.s26; const float2 c2 = r0.s26;
const float2 Y = (bidx == 0) ? (c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0]) : (c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2]); const float2 Y = (bidx == 0) ? (c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2]) : (c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0]);
const float2 U = (bidx == 0) ? ((c2 - Y) * coeffs[3] + HALF_MAX) : ((c0 - Y) * coeffs[3] + HALF_MAX); const float2 U = (bidx == 0) ? ((c0 - Y) * coeffs[3] + HALF_MAX) : ((c2 - Y) * coeffs[3] + HALF_MAX);
const float2 V = (bidx == 0) ? ((c0 - Y) * coeffs[4] + HALF_MAX) : ((c2 - Y) * coeffs[4] + HALF_MAX); const float2 V = (bidx == 0) ? ((c2 - Y) * coeffs[4] + HALF_MAX) : ((c0 - Y) * coeffs[4] + HALF_MAX);
#else #else
const int2 c0 = convert_int2(r0.s04); const int2 c0 = convert_int2(r0.s04);
const int2 c1 = convert_int2(r0.s15); const int2 c1 = convert_int2(r0.s15);
const int2 c2 = convert_int2(r0.s26); const int2 c2 = convert_int2(r0.s26);
const int2 yi = (bidx == 0) ? CV_DESCALE(c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0], yuv_shift) : CV_DESCALE(c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2], yuv_shift); const int2 yi = (bidx == 0) ? CV_DESCALE(c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2], yuv_shift) : CV_DESCALE(c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0], yuv_shift);
const int2 ui = (bidx == 0) ? CV_DESCALE((c2 - yi) * coeffs[3] + delta, yuv_shift) : CV_DESCALE((c0 - yi) * coeffs[3] + delta, yuv_shift); const int2 ui = (bidx == 0) ? CV_DESCALE((c0 - yi) * coeffs[3] + delta, yuv_shift) : CV_DESCALE((c2 - yi) * coeffs[3] + delta, yuv_shift);
const int2 vi = (bidx == 0) ? CV_DESCALE((c0 - yi) * coeffs[4] + delta, yuv_shift) : CV_DESCALE((c2 - yi) * coeffs[4] + delta, yuv_shift); const int2 vi = (bidx == 0) ? CV_DESCALE((c2 - yi) * coeffs[4] + delta, yuv_shift) : CV_DESCALE((c0 - yi) * coeffs[4] + delta, yuv_shift);
const VECTOR2 Y = SAT_CAST2(yi); const VECTOR2 Y = SAT_CAST2(yi);
const VECTOR2 U = SAT_CAST2(ui); const VECTOR2 U = SAT_CAST2(ui);
const VECTOR2 V = SAT_CAST2(vi); const VECTOR2 V = SAT_CAST2(vi);
#endif #endif
vstore8((VECTOR8)(Y.s0, U.s0, V.s0, 0, Y.s1, U.s1, V.s1, 0), 0, dst_ptr); vstore8((VECTOR8)(Y.s0, U.s0, V.s0, 0, Y.s1, U.s1, V.s1, 0), 0, dst_ptr);
} }
#elif (4 == pixels_per_work_item) #elif (4 == pixels_per_work_item)
...@@ -302,14 +334,13 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step, ...@@ -302,14 +334,13 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
const int4 c1 = convert_int4(r0.s159d); const int4 c1 = convert_int4(r0.s159d);
const int4 c2 = convert_int4(r0.s26ae); const int4 c2 = convert_int4(r0.s26ae);
const int4 yi = (bidx == 0) ? CV_DESCALE(c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0], yuv_shift) : CV_DESCALE(c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2], yuv_shift); const int4 yi = (bidx == 0) ? CV_DESCALE(c0 * coeffs[0] + c1 * coeffs[1] + c2 * coeffs[2], yuv_shift) : CV_DESCALE(c0 * coeffs[2] + c1 * coeffs[1] + c2 * coeffs[0], yuv_shift);
const int4 ui = (bidx == 0) ? CV_DESCALE((c2 - yi) * coeffs[3] + delta, yuv_shift) : CV_DESCALE((c0 - yi) * coeffs[3] + delta, yuv_shift); const int4 ui = (bidx == 0) ? CV_DESCALE((c0 - yi) * coeffs[3] + delta, yuv_shift) : CV_DESCALE((c2 - yi) * coeffs[3] + delta, yuv_shift);
const int4 vi = (bidx == 0) ? CV_DESCALE((c0 - yi) * coeffs[4] + delta, yuv_shift) : CV_DESCALE((c2 - yi) * coeffs[4] + delta, yuv_shift); const int4 vi = (bidx == 0) ? CV_DESCALE((c2 - yi) * coeffs[4] + delta, yuv_shift) : CV_DESCALE((c0 - yi) * coeffs[4] + delta, yuv_shift);
const VECTOR4 Y = SAT_CAST4(yi); const VECTOR4 Y = SAT_CAST4(yi);
const VECTOR4 U = SAT_CAST4(ui); const VECTOR4 U = SAT_CAST4(ui);
const VECTOR4 V = SAT_CAST4(vi); const VECTOR4 V = SAT_CAST4(vi);
vstore16((VECTOR16)(Y.s0, U.s0, V.s0, 0, Y.s1, U.s1, V.s1, 0, Y.s2, U.s2, V.s2, 0, Y.s3, U.s3, V.s3, 0), 0, dst_ptr); vstore16((VECTOR16)(Y.s0, U.s0, V.s0, 0, Y.s1, U.s1, V.s1, 0, Y.s2, U.s2, V.s2, 0, Y.s3, U.s3, V.s3, 0), 0, dst_ptr);
#endif #endif
} }
...@@ -317,8 +348,8 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step, ...@@ -317,8 +348,8 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
} }
} }
__constant float c_YUV2RGBCoeffs_f[5] = { 2.032f, -0.395f, -0.581f, 1.140f }; __constant float c_YUV2RGBCoeffs_f[5] = { U2BF, U2GF, V2GF, V2RF };
__constant int c_YUV2RGBCoeffs_i[5] = { 33292, -6472, -9519, 18678 }; __constant int c_YUV2RGBCoeffs_i[5] = { U2BI, U2GI, V2GI, V2RI };
__kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step, __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
__global const DATA_TYPE* src, __global DATA_TYPE* dst, __global const DATA_TYPE* src, __global DATA_TYPE* dst,
...@@ -347,13 +378,13 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step, ...@@ -347,13 +378,13 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
const DATA_TYPE yuv[] = {src_ptr[0], src_ptr[1], src_ptr[2]}; const DATA_TYPE yuv[] = {src_ptr[0], src_ptr[1], src_ptr[2]};
#ifdef DEPTH_5 #ifdef DEPTH_5
float B = yuv[0] + (yuv[2] - HALF_MAX) * coeffs[3]; float B = yuv[0] + (yuv[1] - HALF_MAX) * coeffs[0];
float G = yuv[0] + (yuv[2] - HALF_MAX) * coeffs[2] + (yuv[1] - HALF_MAX) * coeffs[1]; float G = yuv[0] + (yuv[1] - HALF_MAX) * coeffs[1] + (yuv[2] - HALF_MAX) * coeffs[2];
float R = yuv[0] + (yuv[1] - HALF_MAX) * coeffs[0]; float R = yuv[0] + (yuv[2] - HALF_MAX) * coeffs[3];
#else #else
int B = yuv[0] + CV_DESCALE((yuv[2] - HALF_MAX) * coeffs[3], yuv_shift); int B = yuv[0] + CV_DESCALE((yuv[1] - HALF_MAX) * coeffs[0], yuv_shift);
int G = yuv[0] + CV_DESCALE((yuv[2] - HALF_MAX) * coeffs[2] + (yuv[1] - HALF_MAX) * coeffs[1], yuv_shift); int G = yuv[0] + CV_DESCALE((yuv[1] - HALF_MAX) * coeffs[1] + (yuv[2] - HALF_MAX) * coeffs[2], yuv_shift);
int R = yuv[0] + CV_DESCALE((yuv[1] - HALF_MAX) * coeffs[0], yuv_shift); int R = yuv[0] + CV_DESCALE((yuv[2] - HALF_MAX) * coeffs[3], yuv_shift);
#endif #endif
dst_ptr[bidx] = SAT_CAST( B ); dst_ptr[bidx] = SAT_CAST( B );
...@@ -372,17 +403,17 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step, ...@@ -372,17 +403,17 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
const float2 U = r0.s15; const float2 U = r0.s15;
const float2 V = r0.s26; const float2 V = r0.s26;
const float2 c0 = (bidx == 0) ? (Y + (V - HALF_MAX) * coeffs[3]) : (Y + (U - HALF_MAX) * coeffs[0]); const float2 c0 = (bidx != 0) ? (Y + (V - HALF_MAX) * coeffs[3]) : (Y + (U - HALF_MAX) * coeffs[0]);
const float2 c1 = Y + (V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1]; const float2 c1 = Y + (V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1];
const float2 c2 = (bidx == 0) ? (Y + (U - HALF_MAX) * coeffs[0]) : (Y + (V - HALF_MAX) * coeffs[3]); const float2 c2 = (bidx != 0) ? (Y + (U - HALF_MAX) * coeffs[0]) : (Y + (V - HALF_MAX) * coeffs[3]);
#else #else
const int2 Y = convert_int2(r0.s04); const int2 Y = convert_int2(r0.s04);
const int2 U = convert_int2(r0.s15); const int2 U = convert_int2(r0.s15);
const int2 V = convert_int2(r0.s26); const int2 V = convert_int2(r0.s26);
const int2 c0i = (bidx == 0) ? (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)) : (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)); const int2 c0i = (bidx != 0) ? (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)) : (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift));
const int2 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift); const int2 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift);
const int2 c2i = (bidx == 0) ? (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)) : (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)); const int2 c2i = (bidx != 0) ? (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)) : (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift));
const VECTOR2 c0 = SAT_CAST2(c0i); const VECTOR2 c0 = SAT_CAST2(c0i);
const VECTOR2 c1 = SAT_CAST2(c1i); const VECTOR2 c1 = SAT_CAST2(c1i);
...@@ -404,9 +435,9 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step, ...@@ -404,9 +435,9 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
const int4 U = convert_int4(r0.s159d); const int4 U = convert_int4(r0.s159d);
const int4 V = convert_int4(r0.s26ae); const int4 V = convert_int4(r0.s26ae);
const int4 c0i = (bidx == 0) ? (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)) : (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)); const int4 c0i = (bidx != 0) ? (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)) : (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift));
const int4 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift); const int4 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift);
const int4 c2i = (bidx == 0) ? (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)) : (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift)); const int4 c2i = (bidx != 0) ? (Y + CV_DESCALE((U - HALF_MAX) * coeffs[0], yuv_shift)) : (Y + CV_DESCALE((V - HALF_MAX) * coeffs[3], yuv_shift));
const VECTOR4 c0 = SAT_CAST4(c0i); const VECTOR4 c0 = SAT_CAST4(c0i);
const VECTOR4 c1 = SAT_CAST4(c1i); const VECTOR4 c1 = SAT_CAST4(c1i);
...@@ -484,8 +515,8 @@ __kernel void YUV2RGBA_NV12(int cols, int rows, int src_step, int dst_step, ...@@ -484,8 +515,8 @@ __kernel void YUV2RGBA_NV12(int cols, int rows, int src_step, int dst_step,
///////////////////////////////////// RGB <-> YCrCb ////////////////////////////////////// ///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
__constant float c_RGB2YCrCbCoeffs_f[5] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f}; __constant float c_RGB2YCrCbCoeffs_f[5] = {R2YF, G2YF, B2YF, YCRF, YCBF};
__constant int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, 11682, 9241}; __constant int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, YCRI, YCBI};
__kernel void RGB2YCrCb(int cols, int rows, int src_step, int dst_step, __kernel void RGB2YCrCb(int cols, int rows, int src_step, int dst_step,
__global const DATA_TYPE* src, __global DATA_TYPE* dst, __global const DATA_TYPE* src, __global DATA_TYPE* dst,
...@@ -579,8 +610,8 @@ __kernel void RGB2YCrCb(int cols, int rows, int src_step, int dst_step, ...@@ -579,8 +610,8 @@ __kernel void RGB2YCrCb(int cols, int rows, int src_step, int dst_step,
} }
} }
__constant float c_YCrCb2RGBCoeffs_f[4] = { 1.403f, -0.714f, -0.344f, 1.773f }; __constant float c_YCrCb2RGBCoeffs_f[4] = { CR2RF, CR2GF, CB2GF, CB2BF };
__constant int c_YCrCb2RGBCoeffs_i[4] = { 22987, -11698, -5636, 29049 }; __constant int c_YCrCb2RGBCoeffs_i[4] = { CR2RI, CR2GI, CB2GI, CB2BI };
__kernel void YCrCb2RGB(int cols, int rows, int src_step, int dst_step, __kernel void YCrCb2RGB(int cols, int rows, int src_step, int dst_step,
__global const DATA_TYPE* src, __global DATA_TYPE* dst, __global const DATA_TYPE* src, __global DATA_TYPE* dst,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment