Skip to content

Commit d23190d

Browse files
committed
fixed channel order from YVU to YUV
1 parent e3070ed commit d23190d

File tree

2 files changed

+53
-53
lines changed

2 files changed

+53
-53
lines changed

modules/imgproc/src/color.cpp

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -819,16 +819,18 @@ template<typename _Tp> struct RGB2YCrCb_f
819819
{
820820
typedef _Tp channel_type;
821821

822-
RGB2YCrCb_f(int _srccn, int _blueIdx, const float* _coeffs) : srccn(_srccn), blueIdx(_blueIdx)
822+
RGB2YCrCb_f(int _srccn, int _blueIdx, bool _isCrCb) : srccn(_srccn), blueIdx(_blueIdx), isCrCb(_isCrCb)
823823
{
824-
static const float coeffs0[] = {R2YF, G2YF, B2YF, YCRF, YCBF};
825-
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
824+
static const float coeffs_crb[] = { R2YF, G2YF, B2YF, YCRF, YCBF };
825+
static const float coeffs_yuv[] = { R2YF, G2YF, B2YF, R2VF, B2UF };
826+
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 5*sizeof(coeffs[0]));
826827
if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
827828
}
828829

829830
void operator()(const _Tp* src, _Tp* dst, int n) const
830831
{
831832
int scn = srccn, bidx = blueIdx;
833+
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
832834
const _Tp delta = ColorChannel<_Tp>::half();
833835
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
834836
n *= 3;
@@ -837,10 +839,11 @@ template<typename _Tp> struct RGB2YCrCb_f
837839
_Tp Y = saturate_cast<_Tp>(src[0]*C0 + src[1]*C1 + src[2]*C2);
838840
_Tp Cr = saturate_cast<_Tp>((src[bidx^2] - Y)*C3 + delta);
839841
_Tp Cb = saturate_cast<_Tp>((src[bidx] - Y)*C4 + delta);
840-
dst[i] = Y; dst[i+1] = Cr; dst[i+2] = Cb;
842+
dst[i] = Y; dst[i+1+yuvOrder] = Cr; dst[i+2-yuvOrder] = Cb;
841843
}
842844
}
843845
int srccn, blueIdx;
846+
bool isCrCb;
844847
float coeffs[5];
845848
};
846849

@@ -849,16 +852,18 @@ template<typename _Tp> struct RGB2YCrCb_i
849852
{
850853
typedef _Tp channel_type;
851854

852-
RGB2YCrCb_i(int _srccn, int _blueIdx, const int* _coeffs)
853-
: srccn(_srccn), blueIdx(_blueIdx)
855+
RGB2YCrCb_i(int _srccn, int _blueIdx, bool _isCrCb)
856+
: srccn(_srccn), blueIdx(_blueIdx), isCrCb(_isCrCb)
854857
{
855-
static const int coeffs0[] = {R2Y, G2Y, B2Y, YCRI, YCBI};
856-
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 5*sizeof(coeffs[0]));
858+
static const int coeffs_crb[] = { R2Y, G2Y, B2Y, YCRI, YCBI };
859+
static const int coeffs_yuv[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
860+
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 5*sizeof(coeffs[0]));
857861
if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
858862
}
859863
void operator()(const _Tp* src, _Tp* dst, int n) const
860864
{
861865
int scn = srccn, bidx = blueIdx;
866+
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
862867
int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3], C4 = coeffs[4];
863868
int delta = ColorChannel<_Tp>::half()*(1 << yuv_shift);
864869
n *= 3;
@@ -868,11 +873,12 @@ template<typename _Tp> struct RGB2YCrCb_i
868873
int Cr = CV_DESCALE((src[bidx^2] - Y)*C3 + delta, yuv_shift);
869874
int Cb = CV_DESCALE((src[bidx] - Y)*C4 + delta, yuv_shift);
870875
dst[i] = saturate_cast<_Tp>(Y);
871-
dst[i+1] = saturate_cast<_Tp>(Cr);
872-
dst[i+2] = saturate_cast<_Tp>(Cb);
876+
dst[i+1+yuvOrder] = saturate_cast<_Tp>(Cr);
877+
dst[i+2-yuvOrder] = saturate_cast<_Tp>(Cb);
873878
}
874879
}
875880
int srccn, blueIdx;
881+
bool isCrCb;
876882
int coeffs[5];
877883
};
878884

@@ -881,23 +887,25 @@ template<typename _Tp> struct YCrCb2RGB_f
881887
{
882888
typedef _Tp channel_type;
883889

884-
YCrCb2RGB_f(int _dstcn, int _blueIdx, const float* _coeffs)
885-
: dstcn(_dstcn), blueIdx(_blueIdx)
890+
YCrCb2RGB_f(int _dstcn, int _blueIdx, bool _isCrCb)
891+
: dstcn(_dstcn), blueIdx(_blueIdx), isCrCb(_isCrCb)
886892
{
887-
static const float coeffs0[] = {CR2RF, CR2GF, CB2GF, CB2BF};
888-
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
893+
static const float coeffs_cbr[] = {CR2RF, CR2GF, CB2GF, CB2BF};
894+
static const float coeffs_yuv[] = { V2RF, V2GF, U2GF, U2BF};
895+
memcpy(coeffs, isCrCb ? coeffs_cbr : coeffs_yuv, 4*sizeof(coeffs[0]));
889896
}
890897
void operator()(const _Tp* src, _Tp* dst, int n) const
891898
{
892899
int dcn = dstcn, bidx = blueIdx;
900+
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
893901
const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
894902
float C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
895903
n *= 3;
896904
for(int i = 0; i < n; i += 3, dst += dcn)
897905
{
898906
_Tp Y = src[i];
899-
_Tp Cr = src[i+1];
900-
_Tp Cb = src[i+2];
907+
_Tp Cr = src[i+1+yuvOrder];
908+
_Tp Cb = src[i+2-yuvOrder];
901909

902910
_Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
903911
_Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
@@ -909,6 +917,7 @@ template<typename _Tp> struct YCrCb2RGB_f
909917
}
910918
}
911919
int dstcn, blueIdx;
920+
bool isCrCb;
912921
float coeffs[4];
913922
};
914923

@@ -917,24 +926,26 @@ template<typename _Tp> struct YCrCb2RGB_i
917926
{
918927
typedef _Tp channel_type;
919928

920-
YCrCb2RGB_i(int _dstcn, int _blueIdx, const int* _coeffs)
921-
: dstcn(_dstcn), blueIdx(_blueIdx)
929+
YCrCb2RGB_i(int _dstcn, int _blueIdx, bool _isCrCb)
930+
: dstcn(_dstcn), blueIdx(_blueIdx), isCrCb(_isCrCb)
922931
{
923-
static const int coeffs0[] = {CR2RI, CR2GI, CB2GI, CB2BI};
924-
memcpy(coeffs, _coeffs ? _coeffs : coeffs0, 4*sizeof(coeffs[0]));
932+
static const int coeffs_crb[] = { CR2RI, CR2GI, CB2GI, CB2BI};
933+
static const int coeffs_yuv[] = { V2RI, V2GI, U2GI, U2BI };
934+
memcpy(coeffs, isCrCb ? coeffs_crb : coeffs_yuv, 4*sizeof(coeffs[0]));
925935
}
926936

927937
void operator()(const _Tp* src, _Tp* dst, int n) const
928938
{
929939
int dcn = dstcn, bidx = blueIdx;
940+
int yuvOrder = !isCrCb; //1 if YUV, 0 if YCrCb
930941
const _Tp delta = ColorChannel<_Tp>::half(), alpha = ColorChannel<_Tp>::max();
931942
int C0 = coeffs[0], C1 = coeffs[1], C2 = coeffs[2], C3 = coeffs[3];
932943
n *= 3;
933944
for(int i = 0; i < n; i += 3, dst += dcn)
934945
{
935946
_Tp Y = src[i];
936-
_Tp Cr = src[i+1];
937-
_Tp Cb = src[i+2];
947+
_Tp Cr = src[i+1+yuvOrder];
948+
_Tp Cb = src[i+2-yuvOrder];
938949

939950
int b = Y + CV_DESCALE((Cb - delta)*C3, yuv_shift);
940951
int g = Y + CV_DESCALE((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
@@ -948,6 +959,7 @@ template<typename _Tp> struct YCrCb2RGB_i
948959
}
949960
}
950961
int dstcn, blueIdx;
962+
bool isCrCb;
951963
int coeffs[4];
952964
};
953965

@@ -3864,10 +3876,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
38643876
{
38653877
CV_Assert( scn == 3 || scn == 4 );
38663878
bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2;
3867-
static const float yuv_f[] = { R2YF, G2YF, B2YF, R2VF, B2UF };
3868-
static const int yuv_i[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
3869-
const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
3870-
const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
3879+
const bool isCrCb = (code == CV_BGR2YCrCb || code == CV_RGB2YCrCb);
38713880

38723881
_dst.create(sz, CV_MAKETYPE(depth, 3));
38733882
dst = _dst.getMat();
@@ -3878,12 +3887,12 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
38783887
if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb(src, dst, bidx))
38793888
break;
38803889
#endif
3881-
CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i));
3890+
CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, isCrCb));
38823891
}
38833892
else if( depth == CV_16U )
3884-
CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, coeffs_i));
3893+
CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, isCrCb));
38853894
else
3886-
CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f));
3895+
CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, isCrCb));
38873896
}
38883897
break;
38893898

@@ -3893,20 +3902,17 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
38933902
if( dcn <= 0 ) dcn = 3;
38943903
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
38953904
bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2;
3896-
static const float yuv_f[] = {V2RF, V2GF, U2GF, U2BF};
3897-
static const int yuv_i[] = { V2RI, V2GI, U2GI, U2BI };
3898-
const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
3899-
const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
3905+
const bool isCrCb = (code == CV_YCrCb2BGR || code == CV_YCrCb2RGB);
39003906

39013907
_dst.create(sz, CV_MAKETYPE(depth, dcn));
39023908
dst = _dst.getMat();
39033909

39043910
if( depth == CV_8U )
3905-
CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i));
3911+
CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, isCrCb));
39063912
else if( depth == CV_16U )
3907-
CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, coeffs_i));
3913+
CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, isCrCb));
39083914
else
3909-
CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, coeffs_f));
3915+
CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, isCrCb));
39103916
}
39113917
break;
39123918

modules/ocl/src/opencl/cvt_color.cl

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
295295
#endif
296296

297297
dst_ptr[0] = SAT_CAST( Y );
298-
dst_ptr[1] = SAT_CAST( V ); //sic! store channels as YVU, not YUV
299-
dst_ptr[2] = SAT_CAST( U );
298+
dst_ptr[1] = SAT_CAST( U );
299+
dst_ptr[2] = SAT_CAST( V );
300300
}
301301
#elif (2 == pixels_per_work_item)
302302
{
@@ -323,8 +323,7 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
323323
const VECTOR2 U = SAT_CAST2(ui);
324324
const VECTOR2 V = SAT_CAST2(vi);
325325
#endif
326-
//sic! store channels as YVU, not YUV
327-
vstore8((VECTOR8)(Y.s0, V.s0, U.s0, 0, Y.s1, V.s1, U.s1, 0), 0, dst_ptr);
326+
vstore8((VECTOR8)(Y.s0, U.s0, V.s0, 0, Y.s1, U.s1, V.s1, 0), 0, dst_ptr);
328327
}
329328
#elif (4 == pixels_per_work_item)
330329
{
@@ -342,8 +341,7 @@ __kernel void RGB2YUV(int cols, int rows, int src_step, int dst_step,
342341
const VECTOR4 Y = SAT_CAST4(yi);
343342
const VECTOR4 U = SAT_CAST4(ui);
344343
const VECTOR4 V = SAT_CAST4(vi);
345-
//sic! store channels as YVU, not YUV
346-
vstore16((VECTOR16)(Y.s0, V.s0, U.s0, 0, Y.s1, V.s1, U.s1, 0, Y.s2, V.s2, U.s2, 0, Y.s3, V.s3, U.s3, 0), 0, dst_ptr);
344+
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);
347345
#endif
348346
}
349347
#endif //pixels_per_work_item
@@ -377,8 +375,7 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
377375

378376
#if (1 == pixels_per_work_item)
379377
{
380-
//sic! channels stored as YVU, not YUV
381-
const DATA_TYPE yuv[] = {src_ptr[0], src_ptr[2], src_ptr[1]};
378+
const DATA_TYPE yuv[] = {src_ptr[0], src_ptr[1], src_ptr[2]};
382379

383380
#ifdef DEPTH_5
384381
float B = yuv[0] + (yuv[1] - HALF_MAX) * coeffs[0];
@@ -402,19 +399,17 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
402399
const VECTOR8 r0 = vload8(0, src_ptr);
403400

404401
#ifdef DEPTH_5
405-
//sic! channels stored as YVU, not YUV
406402
const float2 Y = r0.s04;
407-
const float2 U = r0.s26;
408-
const float2 V = r0.s15;
403+
const float2 U = r0.s15;
404+
const float2 V = r0.s26;
409405

410406
const float2 c0 = (bidx != 0) ? (Y + (V - HALF_MAX) * coeffs[3]) : (Y + (U - HALF_MAX) * coeffs[0]);
411407
const float2 c1 = Y + (V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1];
412408
const float2 c2 = (bidx != 0) ? (Y + (U - HALF_MAX) * coeffs[0]) : (Y + (V - HALF_MAX) * coeffs[3]);
413409
#else
414-
//sic! channels stored as YVU, not YUV
415410
const int2 Y = convert_int2(r0.s04);
416-
const int2 U = convert_int2(r0.s26);
417-
const int2 V = convert_int2(r0.s15);
411+
const int2 U = convert_int2(r0.s15);
412+
const int2 V = convert_int2(r0.s26);
418413

419414
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));
420415
const int2 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift);
@@ -436,10 +431,9 @@ __kernel void YUV2RGB(int cols, int rows, int src_step, int dst_step,
436431
#ifndef DEPTH_5
437432
const VECTOR16 r0 = vload16(0, src_ptr);
438433

439-
//sic! channels stored as YVU, not YUV
440434
const int4 Y = convert_int4(r0.s048c);
441-
const int4 U = convert_int4(r0.s26ae);
442-
const int4 V = convert_int4(r0.s159d);
435+
const int4 U = convert_int4(r0.s159d);
436+
const int4 V = convert_int4(r0.s26ae);
443437

444438
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));
445439
const int4 c1i = Y + CV_DESCALE((V - HALF_MAX) * coeffs[2] + (U - HALF_MAX) * coeffs[1], yuv_shift);

0 commit comments

Comments
 (0)