@@ -819,16 +819,18 @@ template<typename _Tp> struct RGB2YCrCb_f
819
819
{
820
820
typedef _Tp channel_type;
821
821
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 )
823
823
{
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 ]));
826
827
if (blueIdx==0 ) std::swap (coeffs[0 ], coeffs[2 ]);
827
828
}
828
829
829
830
void operator ()(const _Tp* src, _Tp* dst, int n) const
830
831
{
831
832
int scn = srccn, bidx = blueIdx;
833
+ int yuvOrder = !isCrCb; // 1 if YUV, 0 if YCrCb
832
834
const _Tp delta = ColorChannel<_Tp>::half ();
833
835
float C0 = coeffs[0 ], C1 = coeffs[1 ], C2 = coeffs[2 ], C3 = coeffs[3 ], C4 = coeffs[4 ];
834
836
n *= 3 ;
@@ -837,10 +839,11 @@ template<typename _Tp> struct RGB2YCrCb_f
837
839
_Tp Y = saturate_cast<_Tp>(src[0 ]*C0 + src[1 ]*C1 + src[2 ]*C2);
838
840
_Tp Cr = saturate_cast<_Tp>((src[bidx^2 ] - Y)*C3 + delta);
839
841
_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;
841
843
}
842
844
}
843
845
int srccn, blueIdx;
846
+ bool isCrCb;
844
847
float coeffs[5 ];
845
848
};
846
849
@@ -849,16 +852,18 @@ template<typename _Tp> struct RGB2YCrCb_i
849
852
{
850
853
typedef _Tp channel_type;
851
854
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)
854
857
{
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 ]));
857
861
if (blueIdx==0 ) std::swap (coeffs[0 ], coeffs[2 ]);
858
862
}
859
863
void operator ()(const _Tp* src, _Tp* dst, int n) const
860
864
{
861
865
int scn = srccn, bidx = blueIdx;
866
+ int yuvOrder = !isCrCb; // 1 if YUV, 0 if YCrCb
862
867
int C0 = coeffs[0 ], C1 = coeffs[1 ], C2 = coeffs[2 ], C3 = coeffs[3 ], C4 = coeffs[4 ];
863
868
int delta = ColorChannel<_Tp>::half ()*(1 << yuv_shift);
864
869
n *= 3 ;
@@ -868,11 +873,12 @@ template<typename _Tp> struct RGB2YCrCb_i
868
873
int Cr = CV_DESCALE ((src[bidx^2 ] - Y)*C3 + delta, yuv_shift);
869
874
int Cb = CV_DESCALE ((src[bidx] - Y)*C4 + delta, yuv_shift);
870
875
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);
873
878
}
874
879
}
875
880
int srccn, blueIdx;
881
+ bool isCrCb;
876
882
int coeffs[5 ];
877
883
};
878
884
@@ -881,23 +887,25 @@ template<typename _Tp> struct YCrCb2RGB_f
881
887
{
882
888
typedef _Tp channel_type;
883
889
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)
886
892
{
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 ]));
889
896
}
890
897
void operator ()(const _Tp* src, _Tp* dst, int n) const
891
898
{
892
899
int dcn = dstcn, bidx = blueIdx;
900
+ int yuvOrder = !isCrCb; // 1 if YUV, 0 if YCrCb
893
901
const _Tp delta = ColorChannel<_Tp>::half (), alpha = ColorChannel<_Tp>::max ();
894
902
float C0 = coeffs[0 ], C1 = coeffs[1 ], C2 = coeffs[2 ], C3 = coeffs[3 ];
895
903
n *= 3 ;
896
904
for (int i = 0 ; i < n; i += 3 , dst += dcn)
897
905
{
898
906
_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 ];
901
909
902
910
_Tp b = saturate_cast<_Tp>(Y + (Cb - delta)*C3);
903
911
_Tp g = saturate_cast<_Tp>(Y + (Cb - delta)*C2 + (Cr - delta)*C1);
@@ -909,6 +917,7 @@ template<typename _Tp> struct YCrCb2RGB_f
909
917
}
910
918
}
911
919
int dstcn, blueIdx;
920
+ bool isCrCb;
912
921
float coeffs[4 ];
913
922
};
914
923
@@ -917,24 +926,26 @@ template<typename _Tp> struct YCrCb2RGB_i
917
926
{
918
927
typedef _Tp channel_type;
919
928
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)
922
931
{
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 ]));
925
935
}
926
936
927
937
void operator ()(const _Tp* src, _Tp* dst, int n) const
928
938
{
929
939
int dcn = dstcn, bidx = blueIdx;
940
+ int yuvOrder = !isCrCb; // 1 if YUV, 0 if YCrCb
930
941
const _Tp delta = ColorChannel<_Tp>::half (), alpha = ColorChannel<_Tp>::max ();
931
942
int C0 = coeffs[0 ], C1 = coeffs[1 ], C2 = coeffs[2 ], C3 = coeffs[3 ];
932
943
n *= 3 ;
933
944
for (int i = 0 ; i < n; i += 3 , dst += dcn)
934
945
{
935
946
_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 ];
938
949
939
950
int b = Y + CV_DESCALE ((Cb - delta)*C3, yuv_shift);
940
951
int g = Y + CV_DESCALE ((Cb - delta)*C2 + (Cr - delta)*C1, yuv_shift);
@@ -948,6 +959,7 @@ template<typename _Tp> struct YCrCb2RGB_i
948
959
}
949
960
}
950
961
int dstcn, blueIdx;
962
+ bool isCrCb;
951
963
int coeffs[4 ];
952
964
};
953
965
@@ -3864,10 +3876,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
3864
3876
{
3865
3877
CV_Assert ( scn == 3 || scn == 4 );
3866
3878
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);
3871
3880
3872
3881
_dst.create (sz, CV_MAKETYPE (depth, 3 ));
3873
3882
dst = _dst.getMat ();
@@ -3878,12 +3887,12 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
3878
3887
if ((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb (src, dst, bidx))
3879
3888
break ;
3880
3889
#endif
3881
- CvtColorLoop (src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i ));
3890
+ CvtColorLoop (src, dst, RGB2YCrCb_i<uchar>(scn, bidx, isCrCb ));
3882
3891
}
3883
3892
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 ));
3885
3894
else
3886
- CvtColorLoop (src, dst, RGB2YCrCb_f<float >(scn, bidx, coeffs_f ));
3895
+ CvtColorLoop (src, dst, RGB2YCrCb_f<float >(scn, bidx, isCrCb ));
3887
3896
}
3888
3897
break ;
3889
3898
@@ -3893,20 +3902,17 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
3893
3902
if ( dcn <= 0 ) dcn = 3 ;
3894
3903
CV_Assert ( scn == 3 && (dcn == 3 || dcn == 4 ) );
3895
3904
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);
3900
3906
3901
3907
_dst.create (sz, CV_MAKETYPE (depth, dcn));
3902
3908
dst = _dst.getMat ();
3903
3909
3904
3910
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 ));
3906
3912
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 ));
3908
3914
else
3909
- CvtColorLoop (src, dst, YCrCb2RGB_f<float >(dcn, bidx, coeffs_f ));
3915
+ CvtColorLoop (src, dst, YCrCb2RGB_f<float >(dcn, bidx, isCrCb ));
3910
3916
}
3911
3917
break ;
3912
3918
0 commit comments