//extra color conversions supported implicitly\r
enum\r
{\r
- CX_BGRA2HLS = CV_COLORCVT_MAX + CV_BGR2HLS,\r
- CX_BGRA2HLS_FULL = CV_COLORCVT_MAX + CV_BGR2HLS_FULL,\r
- CX_BGRA2HSV = CV_COLORCVT_MAX + CV_BGR2HSV,\r
- CX_BGRA2HSV_FULL = CV_COLORCVT_MAX + CV_BGR2HSV_FULL,\r
- CX_BGRA2Lab = CV_COLORCVT_MAX + CV_BGR2Lab,\r
- CX_BGRA2Luv = CV_COLORCVT_MAX + CV_BGR2Luv,\r
- CX_BGRA2XYZ = CV_COLORCVT_MAX + CV_BGR2XYZ,\r
- CX_BGRA2YCrCb = CV_COLORCVT_MAX + CV_BGR2YCrCb,\r
- CX_BGRA2YUV = CV_COLORCVT_MAX + CV_BGR2YUV,\r
- CX_HLS2BGRA = CV_COLORCVT_MAX + CV_HLS2BGR,\r
- CX_HLS2BGRA_FULL = CV_COLORCVT_MAX + CV_HLS2BGR_FULL,\r
- CX_HLS2RGBA = CV_COLORCVT_MAX + CV_HLS2RGB,\r
- CX_HLS2RGBA_FULL = CV_COLORCVT_MAX + CV_HLS2RGB_FULL,\r
- CX_HSV2BGRA = CV_COLORCVT_MAX + CV_HSV2BGR,\r
- CX_HSV2BGRA_FULL = CV_COLORCVT_MAX + CV_HSV2BGR_FULL,\r
- CX_HSV2RGBA = CV_COLORCVT_MAX + CV_HSV2RGB,\r
- CX_HSV2RGBA_FULL = CV_COLORCVT_MAX + CV_HSV2RGB_FULL,\r
- CX_Lab2BGRA = CV_COLORCVT_MAX + CV_Lab2BGR,\r
- CX_Lab2LBGRA = CV_COLORCVT_MAX + CV_Lab2LBGR,\r
- CX_Lab2LRGBA = CV_COLORCVT_MAX + CV_Lab2LRGB,\r
- CX_Lab2RGBA = CV_COLORCVT_MAX + CV_Lab2RGB,\r
- CX_LBGRA2Lab = CV_COLORCVT_MAX + CV_LBGR2Lab,\r
- CX_LBGRA2Luv = CV_COLORCVT_MAX + CV_LBGR2Luv,\r
- CX_LRGBA2Lab = CV_COLORCVT_MAX + CV_LRGB2Lab,\r
- CX_LRGBA2Luv = CV_COLORCVT_MAX + CV_LRGB2Luv,\r
- CX_Luv2BGRA = CV_COLORCVT_MAX + CV_Luv2BGR,\r
- CX_Luv2LBGRA = CV_COLORCVT_MAX + CV_Luv2LBGR,\r
- CX_Luv2LRGBA = CV_COLORCVT_MAX + CV_Luv2LRGB,\r
- CX_Luv2RGBA = CV_COLORCVT_MAX + CV_Luv2RGB,\r
- CX_RGBA2HLS = CV_COLORCVT_MAX + CV_RGB2HLS,\r
- CX_RGBA2HLS_FULL = CV_COLORCVT_MAX + CV_RGB2HLS_FULL,\r
- CX_RGBA2HSV = CV_COLORCVT_MAX + CV_RGB2HSV,\r
- CX_RGBA2HSV_FULL = CV_COLORCVT_MAX + CV_RGB2HSV_FULL,\r
- CX_RGBA2Lab = CV_COLORCVT_MAX + CV_RGB2Lab,\r
- CX_RGBA2Luv = CV_COLORCVT_MAX + CV_RGB2Luv,\r
- CX_RGBA2XYZ = CV_COLORCVT_MAX + CV_RGB2XYZ,\r
- CX_RGBA2YCrCb = CV_COLORCVT_MAX + CV_RGB2YCrCb,\r
- CX_RGBA2YUV = CV_COLORCVT_MAX + CV_RGB2YUV,\r
- CX_XYZ2BGRA = CV_COLORCVT_MAX + CV_XYZ2BGR,\r
- CX_XYZ2RGBA = CV_COLORCVT_MAX + CV_XYZ2RGB,\r
- CX_YCrCb2BGRA = CV_COLORCVT_MAX + CV_YCrCb2BGR,\r
- CX_YCrCb2RGBA = CV_COLORCVT_MAX + CV_YCrCb2RGB,\r
- CX_YUV2BGRA = CV_COLORCVT_MAX + CV_YUV2BGR,\r
- CX_YUV2RGBA = CV_COLORCVT_MAX + CV_YUV2RGB\r
+ CX_BGRA2HLS = CV_COLORCVT_MAX + CV_BGR2HLS,\r
+ CX_BGRA2HLS_FULL = CV_COLORCVT_MAX + CV_BGR2HLS_FULL,\r
+ CX_BGRA2HSV = CV_COLORCVT_MAX + CV_BGR2HSV,\r
+ CX_BGRA2HSV_FULL = CV_COLORCVT_MAX + CV_BGR2HSV_FULL,\r
+ CX_BGRA2Lab = CV_COLORCVT_MAX + CV_BGR2Lab,\r
+ CX_BGRA2Luv = CV_COLORCVT_MAX + CV_BGR2Luv,\r
+ CX_BGRA2XYZ = CV_COLORCVT_MAX + CV_BGR2XYZ,\r
+ CX_BGRA2YCrCb = CV_COLORCVT_MAX + CV_BGR2YCrCb,\r
+ CX_BGRA2YUV = CV_COLORCVT_MAX + CV_BGR2YUV,\r
+ CX_HLS2BGRA = CV_COLORCVT_MAX + CV_HLS2BGR,\r
+ CX_HLS2BGRA_FULL = CV_COLORCVT_MAX + CV_HLS2BGR_FULL,\r
+ CX_HLS2RGBA = CV_COLORCVT_MAX + CV_HLS2RGB,\r
+ CX_HLS2RGBA_FULL = CV_COLORCVT_MAX + CV_HLS2RGB_FULL,\r
+ CX_HSV2BGRA = CV_COLORCVT_MAX + CV_HSV2BGR,\r
+ CX_HSV2BGRA_FULL = CV_COLORCVT_MAX + CV_HSV2BGR_FULL,\r
+ CX_HSV2RGBA = CV_COLORCVT_MAX + CV_HSV2RGB,\r
+ CX_HSV2RGBA_FULL = CV_COLORCVT_MAX + CV_HSV2RGB_FULL,\r
+ CX_Lab2BGRA = CV_COLORCVT_MAX + CV_Lab2BGR,\r
+ CX_Lab2LBGRA = CV_COLORCVT_MAX + CV_Lab2LBGR,\r
+ CX_Lab2LRGBA = CV_COLORCVT_MAX + CV_Lab2LRGB,\r
+ CX_Lab2RGBA = CV_COLORCVT_MAX + CV_Lab2RGB,\r
+ CX_LBGRA2Lab = CV_COLORCVT_MAX + CV_LBGR2Lab,\r
+ CX_LBGRA2Luv = CV_COLORCVT_MAX + CV_LBGR2Luv,\r
+ CX_LRGBA2Lab = CV_COLORCVT_MAX + CV_LRGB2Lab,\r
+ CX_LRGBA2Luv = CV_COLORCVT_MAX + CV_LRGB2Luv,\r
+ CX_Luv2BGRA = CV_COLORCVT_MAX + CV_Luv2BGR,\r
+ CX_Luv2LBGRA = CV_COLORCVT_MAX + CV_Luv2LBGR,\r
+ CX_Luv2LRGBA = CV_COLORCVT_MAX + CV_Luv2LRGB,\r
+ CX_Luv2RGBA = CV_COLORCVT_MAX + CV_Luv2RGB,\r
+ CX_RGBA2HLS = CV_COLORCVT_MAX + CV_RGB2HLS,\r
+ CX_RGBA2HLS_FULL = CV_COLORCVT_MAX + CV_RGB2HLS_FULL,\r
+ CX_RGBA2HSV = CV_COLORCVT_MAX + CV_RGB2HSV,\r
+ CX_RGBA2HSV_FULL = CV_COLORCVT_MAX + CV_RGB2HSV_FULL,\r
+ CX_RGBA2Lab = CV_COLORCVT_MAX + CV_RGB2Lab,\r
+ CX_RGBA2Luv = CV_COLORCVT_MAX + CV_RGB2Luv,\r
+ CX_RGBA2XYZ = CV_COLORCVT_MAX + CV_RGB2XYZ,\r
+ CX_RGBA2YCrCb = CV_COLORCVT_MAX + CV_RGB2YCrCb,\r
+ CX_RGBA2YUV = CV_COLORCVT_MAX + CV_RGB2YUV,\r
+ CX_XYZ2BGRA = CV_COLORCVT_MAX + CV_XYZ2BGR,\r
+ CX_XYZ2RGBA = CV_COLORCVT_MAX + CV_XYZ2RGB,\r
+ CX_YCrCb2BGRA = CV_COLORCVT_MAX + CV_YCrCb2BGR,\r
+ CX_YCrCb2RGBA = CV_COLORCVT_MAX + CV_YCrCb2RGB,\r
+ CX_YUV2BGRA = CV_COLORCVT_MAX + CV_YUV2BGR,\r
+ CX_YUV2RGBA = CV_COLORCVT_MAX + CV_YUV2RGB\r
};\r
\r
-CV_ENUM(CvtMode, \r
- CV_BayerBG2BGR, CV_BayerBG2BGR_VNG, CV_BayerBG2GRAY,\r
- CV_BayerGB2BGR, CV_BayerGB2BGR_VNG, CV_BayerGB2GRAY,\r
- CV_BayerGR2BGR, CV_BayerGR2BGR_VNG, CV_BayerGR2GRAY,\r
- CV_BayerRG2BGR, CV_BayerRG2BGR_VNG, CV_BayerRG2GRAY,\r
- \r
- CV_BGR2BGR555, CV_BGR2BGR565, CV_BGR2BGRA, CV_BGR2GRAY, \r
- CV_BGR2HLS, CV_BGR2HLS_FULL, CV_BGR2HSV, CV_BGR2HSV_FULL,\r
- CV_BGR2Lab, CV_BGR2Luv, CV_BGR2RGB, CV_BGR2RGBA, CV_BGR2XYZ,\r
- CV_BGR2YCrCb, CV_BGR2YUV, CV_BGR5552BGR, CV_BGR5552BGRA,\r
- \r
- CV_BGR5552GRAY, CV_BGR5552RGB, CV_BGR5552RGBA, CV_BGR5652BGR,\r
- CV_BGR5652BGRA, CV_BGR5652GRAY, CV_BGR5652RGB, CV_BGR5652RGBA,\r
- \r
- CV_BGRA2BGR, CV_BGRA2BGR555, CV_BGRA2BGR565, CV_BGRA2GRAY, CV_BGRA2RGBA,\r
- CX_BGRA2HLS, CX_BGRA2HLS_FULL, CX_BGRA2HSV, CX_BGRA2HSV_FULL,\r
- CX_BGRA2Lab, CX_BGRA2Luv, CX_BGRA2XYZ,\r
- CX_BGRA2YCrCb, CX_BGRA2YUV,\r
- \r
- CV_GRAY2BGR, CV_GRAY2BGR555, CV_GRAY2BGR565, CV_GRAY2BGRA,\r
+CV_ENUM(CvtMode,\r
+ CV_BayerBG2BGR, CV_BayerBG2BGR_VNG, CV_BayerBG2GRAY,\r
+ CV_BayerGB2BGR, CV_BayerGB2BGR_VNG, CV_BayerGB2GRAY,\r
+ CV_BayerGR2BGR, CV_BayerGR2BGR_VNG, CV_BayerGR2GRAY,\r
+ CV_BayerRG2BGR, CV_BayerRG2BGR_VNG, CV_BayerRG2GRAY,\r
\r
- CV_HLS2BGR, CV_HLS2BGR_FULL, CV_HLS2RGB, CV_HLS2RGB_FULL,\r
- CX_HLS2BGRA, CX_HLS2BGRA_FULL, CX_HLS2RGBA, CX_HLS2RGBA_FULL, \r
- \r
- CV_HSV2BGR, CV_HSV2BGR_FULL, CV_HSV2RGB, CV_HSV2RGB_FULL,\r
- CX_HSV2BGRA, CX_HSV2BGRA_FULL, CX_HSV2RGBA, CX_HSV2RGBA_FULL,\r
- \r
- CV_Lab2BGR, CV_Lab2LBGR, CV_Lab2LRGB, CV_Lab2RGB,\r
- CX_Lab2BGRA, CX_Lab2LBGRA, CX_Lab2LRGBA, CX_Lab2RGBA,\r
- \r
- CV_LBGR2Lab, CV_LBGR2Luv, CV_LRGB2Lab, CV_LRGB2Luv,\r
- CX_LBGRA2Lab, CX_LBGRA2Luv, CX_LRGBA2Lab, CX_LRGBA2Luv,\r
- \r
- CV_Luv2BGR, CV_Luv2LBGR, CV_Luv2LRGB, CV_Luv2RGB,\r
- CX_Luv2BGRA, CX_Luv2LBGRA, CX_Luv2LRGBA, CX_Luv2RGBA,\r
- \r
- CV_RGB2BGR555, CV_RGB2BGR565, CV_RGB2GRAY,\r
- CV_RGB2HLS, CV_RGB2HLS_FULL, CV_RGB2HSV, CV_RGB2HSV_FULL,\r
- CV_RGB2Lab, CV_RGB2Luv, CV_RGB2XYZ, CV_RGB2YCrCb, CV_RGB2YUV,\r
- \r
- CV_RGBA2BGR, CV_RGBA2BGR555, CV_RGBA2BGR565, CV_RGBA2GRAY,\r
- CX_RGBA2HLS, CX_RGBA2HLS_FULL, CX_RGBA2HSV, CX_RGBA2HSV_FULL,\r
- CX_RGBA2Lab, CX_RGBA2Luv, CX_RGBA2XYZ,\r
- CX_RGBA2YCrCb, CX_RGBA2YUV,\r
- \r
- CV_XYZ2BGR, CV_XYZ2RGB, CX_XYZ2BGRA, CX_XYZ2RGBA,\r
- \r
- CV_YCrCb2BGR, CV_YCrCb2RGB, CX_YCrCb2BGRA, CX_YCrCb2RGBA,\r
- CV_YUV2BGR, CV_YUV2RGB, CX_YUV2BGRA, CX_YUV2RGBA\r
- )\r
+ CV_BGR2BGR555, CV_BGR2BGR565, CV_BGR2BGRA, CV_BGR2GRAY,\r
+ CV_BGR2HLS, CV_BGR2HLS_FULL, CV_BGR2HSV, CV_BGR2HSV_FULL,\r
+ CV_BGR2Lab, CV_BGR2Luv, CV_BGR2RGB, CV_BGR2RGBA, CV_BGR2XYZ,\r
+ CV_BGR2YCrCb, CV_BGR2YUV, CV_BGR5552BGR, CV_BGR5552BGRA,\r
+\r
+ CV_BGR5552GRAY, CV_BGR5552RGB, CV_BGR5552RGBA, CV_BGR5652BGR,\r
+ CV_BGR5652BGRA, CV_BGR5652GRAY, CV_BGR5652RGB, CV_BGR5652RGBA,\r
+\r
+ CV_BGRA2BGR, CV_BGRA2BGR555, CV_BGRA2BGR565, CV_BGRA2GRAY, CV_BGRA2RGBA,\r
+ CX_BGRA2HLS, CX_BGRA2HLS_FULL, CX_BGRA2HSV, CX_BGRA2HSV_FULL,\r
+ CX_BGRA2Lab, CX_BGRA2Luv, CX_BGRA2XYZ,\r
+ CX_BGRA2YCrCb, CX_BGRA2YUV,\r
+\r
+ CV_GRAY2BGR, CV_GRAY2BGR555, CV_GRAY2BGR565, CV_GRAY2BGRA,\r
+\r
+ CV_HLS2BGR, CV_HLS2BGR_FULL, CV_HLS2RGB, CV_HLS2RGB_FULL,\r
+ CX_HLS2BGRA, CX_HLS2BGRA_FULL, CX_HLS2RGBA, CX_HLS2RGBA_FULL,\r
+\r
+ CV_HSV2BGR, CV_HSV2BGR_FULL, CV_HSV2RGB, CV_HSV2RGB_FULL,\r
+ CX_HSV2BGRA, CX_HSV2BGRA_FULL, CX_HSV2RGBA, CX_HSV2RGBA_FULL,\r
+\r
+ CV_Lab2BGR, CV_Lab2LBGR, CV_Lab2LRGB, CV_Lab2RGB,\r
+ CX_Lab2BGRA, CX_Lab2LBGRA, CX_Lab2LRGBA, CX_Lab2RGBA,\r
+\r
+ CV_LBGR2Lab, CV_LBGR2Luv, CV_LRGB2Lab, CV_LRGB2Luv,\r
+ CX_LBGRA2Lab, CX_LBGRA2Luv, CX_LRGBA2Lab, CX_LRGBA2Luv,\r
+\r
+ CV_Luv2BGR, CV_Luv2LBGR, CV_Luv2LRGB, CV_Luv2RGB,\r
+ CX_Luv2BGRA, CX_Luv2LBGRA, CX_Luv2LRGBA, CX_Luv2RGBA,\r
+\r
+ CV_RGB2BGR555, CV_RGB2BGR565, CV_RGB2GRAY,\r
+ CV_RGB2HLS, CV_RGB2HLS_FULL, CV_RGB2HSV, CV_RGB2HSV_FULL,\r
+ CV_RGB2Lab, CV_RGB2Luv, CV_RGB2XYZ, CV_RGB2YCrCb, CV_RGB2YUV,\r
+\r
+ CV_RGBA2BGR, CV_RGBA2BGR555, CV_RGBA2BGR565, CV_RGBA2GRAY,\r
+ CX_RGBA2HLS, CX_RGBA2HLS_FULL, CX_RGBA2HSV, CX_RGBA2HSV_FULL,\r
+ CX_RGBA2Lab, CX_RGBA2Luv, CX_RGBA2XYZ,\r
+ CX_RGBA2YCrCb, CX_RGBA2YUV,\r
+\r
+ CV_XYZ2BGR, CV_XYZ2RGB, CX_XYZ2BGRA, CX_XYZ2RGBA,\r
+\r
+ CV_YCrCb2BGR, CV_YCrCb2RGB, CX_YCrCb2BGRA, CX_YCrCb2RGBA,\r
+ CV_YUV2BGR, CV_YUV2RGB, CX_YUV2BGRA, CX_YUV2RGBA\r
+ )\r
+\r
+CV_ENUM(CvtMode2, CV_YUV2BGR_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGB_NV12, CV_YUV2RGBA_NV12, CV_YUV2BGR_NV21, CV_YUV2BGRA_NV21, CV_YUV2RGB_NV21, CV_YUV2RGBA_NV21,\r
+ CV_YUV2BGR_YV12, CV_YUV2BGRA_YV12, CV_YUV2RGB_YV12, CV_YUV2RGBA_YV12, CV_YUV2BGR_IYUV, CV_YUV2BGRA_IYUV, CV_YUV2RGB_IYUV, CV_YUV2RGBA_IYUV,\r
+ COLOR_YUV2GRAY_420)\r
\r
-CV_ENUM(CvtMode2, CV_YUV2BGR_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGB_NV12, CV_YUV2RGBA_NV12, CV_YUV420sp2BGR, CV_YUV420sp2BGRA, CV_YUV420sp2RGB, CV_YUV420sp2RGBA)\r
- \r
struct ChPair\r
{\r
- ChPair(int _scn, int _dcn): scn(_scn), dcn(_dcn) {}\r
- int scn, dcn;\r
+ ChPair(int _scn, int _dcn): scn(_scn), dcn(_dcn) {}\r
+ int scn, dcn;\r
};\r
\r
ChPair getConversionInfo(int cvtMode)\r
{\r
- switch(cvtMode)\r
- {\r
- case CV_BayerBG2GRAY: case CV_BayerGB2GRAY:\r
- case CV_BayerGR2GRAY: case CV_BayerRG2GRAY:\r
- return ChPair(1,1);\r
- case CV_GRAY2BGR555: case CV_GRAY2BGR565:\r
- return ChPair(1,2);\r
- case CV_BayerBG2BGR: case CV_BayerBG2BGR_VNG:\r
- case CV_BayerGB2BGR: case CV_BayerGB2BGR_VNG:\r
- case CV_BayerGR2BGR: case CV_BayerGR2BGR_VNG:\r
- case CV_BayerRG2BGR: case CV_BayerRG2BGR_VNG:\r
- case CV_GRAY2BGR: case CV_YUV2BGR_NV12:\r
- case CV_YUV2RGB_NV12: case CV_YUV420sp2BGR:\r
- case CV_YUV420sp2RGB:\r
- return ChPair(1,3);\r
- case CV_GRAY2BGRA: case CV_YUV2BGRA_NV12:\r
- case CV_YUV2RGBA_NV12: case CV_YUV420sp2BGRA:\r
- case CV_YUV420sp2RGBA:\r
- return ChPair(1,4);\r
- case CV_BGR5552GRAY: case CV_BGR5652GRAY:\r
- return ChPair(2,1);\r
- case CV_BGR5552BGR: case CV_BGR5552RGB:\r
- case CV_BGR5652BGR: case CV_BGR5652RGB:\r
- return ChPair(2,3);\r
- case CV_BGR5552BGRA: case CV_BGR5552RGBA:\r
- case CV_BGR5652BGRA: case CV_BGR5652RGBA:\r
- return ChPair(2,4);\r
- case CV_BGR2GRAY: case CV_RGB2GRAY:\r
- return ChPair(3,1);\r
- case CV_BGR2BGR555: case CV_BGR2BGR565:\r
- case CV_RGB2BGR555: case CV_RGB2BGR565:\r
- return ChPair(3,2);\r
- case CV_BGR2HLS: case CV_BGR2HLS_FULL:\r
- case CV_BGR2HSV: case CV_BGR2HSV_FULL:\r
- case CV_BGR2Lab: case CV_BGR2Luv:\r
- case CV_BGR2RGB: case CV_BGR2XYZ:\r
- case CV_BGR2YCrCb: case CV_BGR2YUV:\r
- case CV_HLS2BGR: case CV_HLS2BGR_FULL:\r
- case CV_HLS2RGB: case CV_HLS2RGB_FULL:\r
- case CV_HSV2BGR: case CV_HSV2BGR_FULL:\r
- case CV_HSV2RGB: case CV_HSV2RGB_FULL:\r
- case CV_Lab2BGR: case CV_Lab2LBGR:\r
- case CV_Lab2LRGB: case CV_Lab2RGB:\r
- case CV_LBGR2Lab: case CV_LBGR2Luv:\r
- case CV_LRGB2Lab: case CV_LRGB2Luv:\r
- case CV_Luv2BGR: case CV_Luv2LBGR:\r
- case CV_Luv2LRGB: case CV_Luv2RGB:\r
- case CV_RGB2HLS: case CV_RGB2HLS_FULL:\r
- case CV_RGB2HSV: case CV_RGB2HSV_FULL:\r
- case CV_RGB2Lab: case CV_RGB2Luv:\r
- case CV_RGB2XYZ: case CV_RGB2YCrCb:\r
- case CV_RGB2YUV: case CV_XYZ2BGR:\r
- case CV_XYZ2RGB: case CV_YCrCb2BGR:\r
- case CV_YCrCb2RGB: case CV_YUV2BGR:\r
- case CV_YUV2RGB:\r
- return ChPair(3,3);\r
- case CV_BGR2BGRA: case CV_BGR2RGBA:\r
- case CX_HLS2BGRA: case CX_HLS2BGRA_FULL:\r
- case CX_HLS2RGBA: case CX_HLS2RGBA_FULL:\r
- case CX_HSV2BGRA: case CX_HSV2BGRA_FULL:\r
- case CX_HSV2RGBA: case CX_HSV2RGBA_FULL:\r
- case CX_Lab2BGRA: case CX_Lab2LBGRA:\r
- case CX_Lab2LRGBA: case CX_Lab2RGBA:\r
- case CX_Luv2BGRA: case CX_Luv2LBGRA:\r
- case CX_Luv2LRGBA: case CX_Luv2RGBA:\r
- case CX_XYZ2BGRA: case CX_XYZ2RGBA:\r
- case CX_YCrCb2BGRA: case CX_YCrCb2RGBA:\r
- case CX_YUV2BGRA: case CX_YUV2RGBA:\r
- return ChPair(3,4);\r
- case CV_BGRA2GRAY: case CV_RGBA2GRAY:\r
- return ChPair(4,1);\r
- case CV_BGRA2BGR555: case CV_BGRA2BGR565:\r
- case CV_RGBA2BGR555: case CV_RGBA2BGR565:\r
- return ChPair(4,2);\r
- case CV_BGRA2BGR: case CX_BGRA2HLS:\r
- case CX_BGRA2HLS_FULL: case CX_BGRA2HSV:\r
- case CX_BGRA2HSV_FULL: case CX_BGRA2Lab:\r
- case CX_BGRA2Luv: case CX_BGRA2XYZ:\r
- case CX_BGRA2YCrCb: case CX_BGRA2YUV:\r
- case CX_LBGRA2Lab: case CX_LBGRA2Luv:\r
- case CX_LRGBA2Lab: case CX_LRGBA2Luv:\r
- case CV_RGBA2BGR: case CX_RGBA2HLS:\r
- case CX_RGBA2HLS_FULL: case CX_RGBA2HSV:\r
- case CX_RGBA2HSV_FULL: case CX_RGBA2Lab:\r
- case CX_RGBA2Luv: case CX_RGBA2XYZ:\r
- case CX_RGBA2YCrCb: case CX_RGBA2YUV:\r
- return ChPair(4,3);\r
- case CV_BGRA2RGBA:\r
- return ChPair(4,4);\r
- default:\r
- ADD_FAILURE() << "Unknown conversion type";\r
- break;\r
- };\r
- return ChPair(0,0);\r
+ switch(cvtMode)\r
+ {\r
+ case CV_BayerBG2GRAY: case CV_BayerGB2GRAY:\r
+ case CV_BayerGR2GRAY: case CV_BayerRG2GRAY:\r
+ case CV_YUV2GRAY_420:\r
+ return ChPair(1,1);\r
+ case CV_GRAY2BGR555: case CV_GRAY2BGR565:\r
+ return ChPair(1,2);\r
+ case CV_BayerBG2BGR: case CV_BayerBG2BGR_VNG:\r
+ case CV_BayerGB2BGR: case CV_BayerGB2BGR_VNG:\r
+ case CV_BayerGR2BGR: case CV_BayerGR2BGR_VNG:\r
+ case CV_BayerRG2BGR: case CV_BayerRG2BGR_VNG:\r
+ case CV_GRAY2BGR:\r
+ case CV_YUV2BGR_NV12: case CV_YUV2RGB_NV12:\r
+ case CV_YUV2BGR_NV21: case CV_YUV2RGB_NV21:\r
+ case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12:\r
+ case CV_YUV2BGR_IYUV: case CV_YUV2RGB_IYUV:\r
+ return ChPair(1,3);\r
+ case CV_GRAY2BGRA:\r
+ case CV_YUV2BGRA_NV12: case CV_YUV2RGBA_NV12:\r
+ case CV_YUV2BGRA_NV21: case CV_YUV2RGBA_NV21:\r
+ case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12:\r
+ case CV_YUV2BGRA_IYUV: case CV_YUV2RGBA_IYUV:\r
+ return ChPair(1,4);\r
+ case CV_BGR5552GRAY: case CV_BGR5652GRAY:\r
+ return ChPair(2,1);\r
+ case CV_BGR5552BGR: case CV_BGR5552RGB:\r
+ case CV_BGR5652BGR: case CV_BGR5652RGB:\r
+ return ChPair(2,3);\r
+ case CV_BGR5552BGRA: case CV_BGR5552RGBA:\r
+ case CV_BGR5652BGRA: case CV_BGR5652RGBA:\r
+ return ChPair(2,4);\r
+ case CV_BGR2GRAY: case CV_RGB2GRAY:\r
+ return ChPair(3,1);\r
+ case CV_BGR2BGR555: case CV_BGR2BGR565:\r
+ case CV_RGB2BGR555: case CV_RGB2BGR565:\r
+ return ChPair(3,2);\r
+ case CV_BGR2HLS: case CV_BGR2HLS_FULL:\r
+ case CV_BGR2HSV: case CV_BGR2HSV_FULL:\r
+ case CV_BGR2Lab: case CV_BGR2Luv:\r
+ case CV_BGR2RGB: case CV_BGR2XYZ:\r
+ case CV_BGR2YCrCb: case CV_BGR2YUV:\r
+ case CV_HLS2BGR: case CV_HLS2BGR_FULL:\r
+ case CV_HLS2RGB: case CV_HLS2RGB_FULL:\r
+ case CV_HSV2BGR: case CV_HSV2BGR_FULL:\r
+ case CV_HSV2RGB: case CV_HSV2RGB_FULL:\r
+ case CV_Lab2BGR: case CV_Lab2LBGR:\r
+ case CV_Lab2LRGB: case CV_Lab2RGB:\r
+ case CV_LBGR2Lab: case CV_LBGR2Luv:\r
+ case CV_LRGB2Lab: case CV_LRGB2Luv:\r
+ case CV_Luv2BGR: case CV_Luv2LBGR:\r
+ case CV_Luv2LRGB: case CV_Luv2RGB:\r
+ case CV_RGB2HLS: case CV_RGB2HLS_FULL:\r
+ case CV_RGB2HSV: case CV_RGB2HSV_FULL:\r
+ case CV_RGB2Lab: case CV_RGB2Luv:\r
+ case CV_RGB2XYZ: case CV_RGB2YCrCb:\r
+ case CV_RGB2YUV: case CV_XYZ2BGR:\r
+ case CV_XYZ2RGB: case CV_YCrCb2BGR:\r
+ case CV_YCrCb2RGB: case CV_YUV2BGR:\r
+ case CV_YUV2RGB:\r
+ return ChPair(3,3);\r
+ case CV_BGR2BGRA: case CV_BGR2RGBA:\r
+ case CX_HLS2BGRA: case CX_HLS2BGRA_FULL:\r
+ case CX_HLS2RGBA: case CX_HLS2RGBA_FULL:\r
+ case CX_HSV2BGRA: case CX_HSV2BGRA_FULL:\r
+ case CX_HSV2RGBA: case CX_HSV2RGBA_FULL:\r
+ case CX_Lab2BGRA: case CX_Lab2LBGRA:\r
+ case CX_Lab2LRGBA: case CX_Lab2RGBA:\r
+ case CX_Luv2BGRA: case CX_Luv2LBGRA:\r
+ case CX_Luv2LRGBA: case CX_Luv2RGBA:\r
+ case CX_XYZ2BGRA: case CX_XYZ2RGBA:\r
+ case CX_YCrCb2BGRA: case CX_YCrCb2RGBA:\r
+ case CX_YUV2BGRA: case CX_YUV2RGBA:\r
+ return ChPair(3,4);\r
+ case CV_BGRA2GRAY: case CV_RGBA2GRAY:\r
+ return ChPair(4,1);\r
+ case CV_BGRA2BGR555: case CV_BGRA2BGR565:\r
+ case CV_RGBA2BGR555: case CV_RGBA2BGR565:\r
+ return ChPair(4,2);\r
+ case CV_BGRA2BGR: case CX_BGRA2HLS:\r
+ case CX_BGRA2HLS_FULL: case CX_BGRA2HSV:\r
+ case CX_BGRA2HSV_FULL: case CX_BGRA2Lab:\r
+ case CX_BGRA2Luv: case CX_BGRA2XYZ:\r
+ case CX_BGRA2YCrCb: case CX_BGRA2YUV:\r
+ case CX_LBGRA2Lab: case CX_LBGRA2Luv:\r
+ case CX_LRGBA2Lab: case CX_LRGBA2Luv:\r
+ case CV_RGBA2BGR: case CX_RGBA2HLS:\r
+ case CX_RGBA2HLS_FULL: case CX_RGBA2HSV:\r
+ case CX_RGBA2HSV_FULL: case CX_RGBA2Lab:\r
+ case CX_RGBA2Luv: case CX_RGBA2XYZ:\r
+ case CX_RGBA2YCrCb: case CX_RGBA2YUV:\r
+ return ChPair(4,3);\r
+ case CV_BGRA2RGBA:\r
+ return ChPair(4,4);\r
+ default:\r
+ ADD_FAILURE() << "Unknown conversion type";\r
+ break;\r
+ };\r
+ return ChPair(0,0);\r
}\r
\r
typedef std::tr1::tuple<Size, CvtMode> Size_CvtMode_t;\r
)\r
)\r
{\r
- Size sz = get<0>(GetParam());\r
- int mode = get<1>(GetParam());\r
- ChPair ch = getConversionInfo(mode);\r
- mode %= CV_COLORCVT_MAX;\r
- \r
- Mat src(sz, CV_8UC(ch.scn));\r
- Mat dst(sz, CV_8UC(ch.dcn));\r
- \r
- declare.in(src, WARMUP_RNG).out(dst);\r
- \r
+ Size sz = get<0>(GetParam());\r
+ int mode = get<1>(GetParam());\r
+ ChPair ch = getConversionInfo(mode);\r
+ mode %= CV_COLORCVT_MAX;\r
+\r
+ Mat src(sz, CV_8UC(ch.scn));\r
+ Mat dst(sz, CV_8UC(ch.dcn));\r
+\r
+ declare.in(src, WARMUP_RNG).out(dst);\r
+\r
TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn);\r
- \r
+\r
SANITY_CHECK(dst, 1);\r
}\r
\r
)\r
{\r
Size sz = get<0>(GetParam());\r
- int mode = get<1>(GetParam());\r
- ChPair ch = getConversionInfo(mode);\r
+ int mode = get<1>(GetParam());\r
+ ChPair ch = getConversionInfo(mode);\r
\r
Mat src(sz.height + sz.height / 2, sz.width, CV_8UC(ch.scn));\r
Mat dst(sz, CV_8UC(ch.dcn));\r
\r
declare.in(src, WARMUP_RNG).out(dst);\r
- \r
+\r
TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn);\r
- \r
+\r
SANITY_CHECK(dst, 1);\r
}\r
Mat* dst;
const uchar* my1, *mu, *mv;
int width, stride;
+ int ustepIdx, vstepIdx;
- YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
- : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
+ YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx)
+ : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {}
void operator()(const BlockedRange& range) const
{
const int rangeBegin = range.begin() * 2;
const int rangeEnd = range.end() * 2;
-
- //R = 1.164(Y - 16) + 1.596(V - 128)
- //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
- //B = 1.164(Y - 16) + 2.018(U - 128)
-
- //R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
- //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
- //B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
+
+ size_t uvsteps[2] = {width/2, stride - width/2};
+ int usIdx = ustepIdx, vsIdx = vstepIdx;
const int cY = 1220542;
const int cUB = 2116026;
const int YUV420_SHIFT = 20;
const uchar* y1 = my1 + rangeBegin * stride;
- const uchar* u1 = mu + (range.begin() / 2) * stride + (range.begin() % 2) * width/2;
- const uchar* v1 = mv + (range.begin() / 2) * stride + (range.begin() % 2) * width/2;
+ const uchar* u1 = mu + (range.begin() / 2) * stride;
+ const uchar* v1 = mv + (range.begin() / 2) * stride;
+
+ if(range.begin() % 2 == 1)
+ {
+ u1 += uvsteps[(usIdx++) & 1];
+ v1 += uvsteps[(vsIdx++) & 1];
+ }
- for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += width / 2, v1 += width / 2)
+ for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1])
{
uchar* row1 = dst->ptr<uchar>(j);
uchar* row2 = dst->ptr<uchar>(j + 1);
row2[4] = saturate_cast<uchar>((y11 + guv) >> YUV420_SHIFT);
row2[3+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
}
-
- if(j % 4 == 2)
- {
- u1 += stride - width;
- v1 += stride - width;
- }
}
}
};
Mat* dst;
const uchar* my1, *mu, *mv;
int width, stride;
+ int ustepIdx, vstepIdx;
- YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
- : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
+ YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx)
+ : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {}
void operator()(const BlockedRange& range) const
{
int rangeBegin = range.begin() * 2;
int rangeEnd = range.end() * 2;
- //R = 1.164(Y - 16) + 1.596(V - 128)
- //G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
- //B = 1.164(Y - 16) + 2.018(U - 128)
-
- //R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
- //G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
- //B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
-
const int cY = 1220542;
const int cUB = 2116026;
const int cUG = -409993;
const int cVG = -852492;
const int cVR = 1673527;
const int YUV420_SHIFT = 20;
+
+ size_t uvsteps[2] = {width/2, stride - width/2};
+ int usIdx = ustepIdx, vsIdx = vstepIdx;
const uchar* y1 = my1 + rangeBegin * stride;
- const uchar* u1 = mu + (range.begin() / 2) * stride + (range.begin() % 2) * width/2;
- const uchar* v1 = mv + (range.begin() / 2) * stride + (range.begin() % 2) * width/2;
+ const uchar* u1 = mu + (range.begin() / 2) * stride;
+ const uchar* v1 = mv + (range.begin() / 2) * stride;
+
+ if(range.begin() % 2 == 1)
+ {
+ u1 += uvsteps[(usIdx++) & 1];
+ v1 += uvsteps[(vsIdx++) & 1];
+ }
- for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += width / 2, v1 += width / 2)
+ for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1])
{
uchar* row1 = dst->ptr<uchar>(j);
uchar* row2 = dst->ptr<uchar>(j + 1);
row2[4+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
row2[7] = uchar(0xff);
}
-
- if(j % 4 == 2)
- {
- u1 += stride - width;
- v1 += stride - width;
- }
}
}
};
}
template<int bIdx>
-inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
+inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx)
{
- YUV420p2RGB888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v);
+ YUV420p2RGB888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx);
#ifdef HAVE_TBB
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
parallel_for(BlockedRange(0, _dst.rows/2), converter);
}
template<int bIdx>
-inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
+inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx)
{
- YUV420p2RGBA8888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v);
+ YUV420p2RGBA8888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx);
#ifdef HAVE_TBB
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
parallel_for(BlockedRange(0, _dst.rows/2), converter);
int srcstep = (int)src.step;
const uchar* y = src.ptr();
const uchar* u = y + srcstep * dstSz.height;
- const uchar* v = u + (srcstep * dstSz.height / 4);
- if(uidx == 1) std::swap(u ,v);
+ const uchar* v = y + srcstep * (dstSz.height + dstSz.height/4) + (dstSz.width/2) * ((dstSz.height % 4)/2);
+
+ int ustepIdx = 0;
+ int vstepIdx = dstSz.height % 4 == 2 ? 1 : 0;
+
+ if(uidx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); };
switch(dcn*10 + bidx)
{
- case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v); break;
- case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v); break;
- case 40: cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v); break;
- case 42: cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v); break;
+ case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
+ case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
+ case 40: cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
+ case 42: cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
}
--- /dev/null
+#include "test_precomp.hpp"\r
+\r
+using namespace cv;\r
+using namespace std;\r
+\r
+#undef RGB\r
+#undef YUV\r
+\r
+typedef Vec3b YUV;\r
+typedef Vec3b RGB;\r
+\r
+int countOfDifferencies(const Mat& gold, const Mat& result, int maxAllowedDifference = 1)\r
+{\r
+ Mat diff;\r
+ absdiff(gold, result, diff);\r
+ return countNonZero(diff.reshape(1) > maxAllowedDifference);\r
+}\r
+\r
+class YUVreader\r
+{\r
+public:\r
+ virtual ~YUVreader() {}\r
+ virtual YUV read(const Mat& yuv, int row, int col) = 0;\r
+ virtual int channels() = 0;\r
+ virtual Size size(Size imgSize) = 0;\r
+\r
+ virtual bool requiresEvenHeight() { return true; }\r
+ virtual bool requiresEvenWidth() { return true; }\r
+\r
+ static YUVreader* getReader(int code);\r
+};\r
+\r
+class RGBwriter\r
+{\r
+public:\r
+ virtual ~RGBwriter() {}\r
+\r
+ virtual void write(Mat& rgb, int row, int col, const RGB& val) = 0;\r
+ virtual int channels() = 0;\r
+\r
+ static RGBwriter* getWriter(int code);\r
+};\r
+\r
+class GRAYwriter\r
+{\r
+public:\r
+ virtual ~GRAYwriter() {}\r
+\r
+ virtual void write(Mat& gray, int row, int col, const uchar& val)\r
+ {\r
+ gray.at<uchar>(row, col) = val;\r
+ }\r
+\r
+ virtual int channels() { return 1; }\r
+\r
+ static GRAYwriter* getWriter(int code);\r
+};\r
+\r
+class RGB888Writer : public RGBwriter\r
+{\r
+ void write(Mat& rgb, int row, int col, const RGB& val)\r
+ {\r
+ rgb.at<Vec3b>(row, col) = val;\r
+ }\r
+\r
+ int channels() { return 3; }\r
+};\r
+\r
+class BGR888Writer : public RGBwriter\r
+{\r
+ void write(Mat& rgb, int row, int col, const RGB& val)\r
+ {\r
+ Vec3b tmp(val[2], val[1], val[0]);\r
+ rgb.at<Vec3b>(row, col) = tmp;\r
+ }\r
+\r
+ int channels() { return 3; }\r
+};\r
+\r
+class RGBA8888Writer : public RGBwriter\r
+{\r
+ void write(Mat& rgb, int row, int col, const RGB& val)\r
+ {\r
+ Vec4b tmp(val[0], val[1], val[2], 255);\r
+ rgb.at<Vec4b>(row, col) = tmp;\r
+ }\r
+\r
+ int channels() { return 4; }\r
+};\r
+\r
+class BGRA8888Writer : public RGBwriter\r
+{\r
+ void write(Mat& rgb, int row, int col, const RGB& val)\r
+ {\r
+ Vec4b tmp(val[2], val[1], val[0], 255);\r
+ rgb.at<Vec4b>(row, col) = tmp;\r
+ }\r
+\r
+ int channels() { return 4; }\r
+};\r
+\r
+class YUV420Reader: public YUVreader\r
+{\r
+ int channels() { return 1; }\r
+ Size size(Size imgSize) { return Size(imgSize.width, imgSize.height * 3 / 2); }\r
+};\r
+\r
+class YUV422Reader: public YUVreader\r
+{\r
+ int channels() { return 2; }\r
+ Size size(Size imgSize) { return imgSize; }\r
+ bool requiresEvenHeight() { return false; }\r
+};\r
+\r
+class NV21Reader: public YUV420Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ uchar y = yuv.ptr<uchar>(row)[col];\r
+ uchar u = yuv.ptr<uchar>(yuv.rows * 2 / 3 + row/2)[(col/2)*2 + 1];\r
+ uchar v = yuv.ptr<uchar>(yuv.rows * 2 / 3 + row/2)[(col/2)*2];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+\r
+struct NV12Reader: public YUV420Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ uchar y = yuv.ptr<uchar>(row)[col];\r
+ uchar u = yuv.ptr<uchar>(yuv.rows * 2 / 3 + row/2)[(col/2)*2];\r
+ uchar v = yuv.ptr<uchar>(yuv.rows * 2 / 3 + row/2)[(col/2)*2 + 1];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class YV12Reader: public YUV420Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ int h = yuv.rows * 2 / 3;\r
+ uchar y = yuv.ptr<uchar>(row)[col];\r
+ uchar u = yuv.ptr<uchar>(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)];\r
+ uchar v = yuv.ptr<uchar>(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class IYUVReader: public YUV420Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ int h = yuv.rows * 2 / 3;\r
+ uchar y = yuv.ptr<uchar>(row)[col];\r
+ uchar u = yuv.ptr<uchar>(h + row/4)[col/2 + ((row/2) % 2) * (yuv.cols/2)];\r
+ uchar v = yuv.ptr<uchar>(h + (row/2 + h/2)/2)[col/2 + ((row/2 + h/2) % 2) * (yuv.cols/2)];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class UYVYReader: public YUV422Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ uchar y = yuv.ptr<Vec2b>(row)[col][1];\r
+ uchar u = yuv.ptr<Vec2b>(row)[(col/2)*2][0];\r
+ uchar v = yuv.ptr<Vec2b>(row)[(col/2)*2 + 1][0];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class YUY2Reader: public YUV422Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ uchar y = yuv.ptr<Vec2b>(row)[col][0];\r
+ uchar u = yuv.ptr<Vec2b>(row)[(col/2)*2][1];\r
+ uchar v = yuv.ptr<Vec2b>(row)[(col/2)*2 + 1][1];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class YVYUReader: public YUV422Reader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ uchar y = yuv.ptr<Vec2b>(row)[col][0];\r
+ uchar u = yuv.ptr<Vec2b>(row)[(col/2)*2 + 1][1];\r
+ uchar v = yuv.ptr<Vec2b>(row)[(col/2)*2][1];\r
+\r
+ return YUV(y, u, v);\r
+ }\r
+};\r
+\r
+class YUV888Reader : public YUVreader\r
+{\r
+ YUV read(const Mat& yuv, int row, int col)\r
+ {\r
+ return yuv.at<YUV>(row, col);\r
+ }\r
+\r
+ int channels() { return 3; }\r
+ Size size(Size imgSize) { return imgSize; }\r
+ bool requiresEvenHeight() { return false; }\r
+ bool requiresEvenWidth() { return false; }\r
+};\r
+\r
+class YUV2RGB_Converter\r
+{\r
+public:\r
+ RGB convert(YUV yuv)\r
+ {\r
+ int y = std::max(0, yuv[0] - 16);\r
+ int u = yuv[1] - 128;\r
+ int v = yuv[2] - 128;\r
+ uchar r = saturate_cast<uchar>(1.164f * y + 1.596f * v);\r
+ uchar g = saturate_cast<uchar>(1.164f * y - 0.813f * v - 0.391f * u);\r
+ uchar b = saturate_cast<uchar>(1.164f * y + 2.018f * u);\r
+\r
+ return RGB(r, g, b);\r
+ }\r
+};\r
+\r
+class YUV2GRAY_Converter\r
+{\r
+public:\r
+ uchar convert(YUV yuv)\r
+ {\r
+ return yuv[0];\r
+ }\r
+};\r
+\r
+YUVreader* YUVreader::getReader(int code)\r
+{\r
+ switch(code)\r
+ {\r
+ case CV_YUV2RGB_NV12:\r
+ case CV_YUV2BGR_NV12:\r
+ case CV_YUV2RGBA_NV12:\r
+ case CV_YUV2BGRA_NV12:\r
+ return new NV12Reader();\r
+ case CV_YUV2RGB_NV21:\r
+ case CV_YUV2BGR_NV21:\r
+ case CV_YUV2RGBA_NV21:\r
+ case CV_YUV2BGRA_NV21:\r
+ return new NV21Reader();\r
+ case CV_YUV2RGB_YV12:\r
+ case CV_YUV2BGR_YV12:\r
+ case CV_YUV2RGBA_YV12:\r
+ case CV_YUV2BGRA_YV12:\r
+ return new YV12Reader();\r
+ case CV_YUV2RGB_IYUV:\r
+ case CV_YUV2BGR_IYUV:\r
+ case CV_YUV2RGBA_IYUV:\r
+ case CV_YUV2BGRA_IYUV:\r
+ return new IYUVReader();\r
+ case CV_YUV2RGB_UYVY:\r
+ case CV_YUV2BGR_UYVY:\r
+ case CV_YUV2RGBA_UYVY:\r
+ case CV_YUV2BGRA_UYVY:\r
+ return new UYVYReader();\r
+ //case CV_YUV2RGB_VYUY = 109,\r
+ //case CV_YUV2BGR_VYUY = 110,\r
+ //case CV_YUV2RGBA_VYUY = 113,\r
+ //case CV_YUV2BGRA_VYUY = 114,\r
+ // return ??\r
+ case CV_YUV2RGB_YUY2:\r
+ case CV_YUV2BGR_YUY2:\r
+ case CV_YUV2RGBA_YUY2:\r
+ case CV_YUV2BGRA_YUY2:\r
+ return new YUY2Reader();\r
+ case CV_YUV2RGB_YVYU:\r
+ case CV_YUV2BGR_YVYU:\r
+ case CV_YUV2RGBA_YVYU:\r
+ case CV_YUV2BGRA_YVYU:\r
+ return new YVYUReader();\r
+ case CV_YUV2GRAY_420:\r
+ return new NV21Reader();\r
+ case CV_YUV2GRAY_UYVY:\r
+ return new UYVYReader();\r
+ case CV_YUV2GRAY_YUY2:\r
+ return new YUY2Reader();\r
+ case CV_YUV2BGR:\r
+ case CV_YUV2RGB:\r
+ return new YUV888Reader();\r
+ default:\r
+ return 0;\r
+ }\r
+}\r
+\r
+RGBwriter* RGBwriter::getWriter(int code)\r
+{\r
+ switch(code)\r
+ {\r
+ case CV_YUV2RGB_NV12:\r
+ case CV_YUV2RGB_NV21:\r
+ case CV_YUV2RGB_YV12:\r
+ case CV_YUV2RGB_IYUV:\r
+ case CV_YUV2RGB_UYVY:\r
+ //case CV_YUV2RGB_VYUY:\r
+ case CV_YUV2RGB_YUY2:\r
+ case CV_YUV2RGB_YVYU:\r
+ case CV_YUV2RGB:\r
+ return new RGB888Writer();\r
+ case CV_YUV2BGR_NV12:\r
+ case CV_YUV2BGR_NV21:\r
+ case CV_YUV2BGR_YV12:\r
+ case CV_YUV2BGR_IYUV:\r
+ case CV_YUV2BGR_UYVY:\r
+ //case CV_YUV2BGR_VYUY:\r
+ case CV_YUV2BGR_YUY2:\r
+ case CV_YUV2BGR_YVYU:\r
+ case CV_YUV2BGR:\r
+ return new BGR888Writer();\r
+ case CV_YUV2RGBA_NV12:\r
+ case CV_YUV2RGBA_NV21:\r
+ case CV_YUV2RGBA_YV12:\r
+ case CV_YUV2RGBA_IYUV:\r
+ case CV_YUV2RGBA_UYVY:\r
+ //case CV_YUV2RGBA_VYUY:\r
+ case CV_YUV2RGBA_YUY2:\r
+ case CV_YUV2RGBA_YVYU:\r
+ return new RGBA8888Writer();\r
+ case CV_YUV2BGRA_NV12:\r
+ case CV_YUV2BGRA_NV21:\r
+ case CV_YUV2BGRA_YV12:\r
+ case CV_YUV2BGRA_IYUV:\r
+ case CV_YUV2BGRA_UYVY:\r
+ //case CV_YUV2BGRA_VYUY:\r
+ case CV_YUV2BGRA_YUY2:\r
+ case CV_YUV2BGRA_YVYU:\r
+ return new BGRA8888Writer();\r
+ default:\r
+ return 0;\r
+ };\r
+}\r
+\r
+GRAYwriter* GRAYwriter::getWriter(int code)\r
+{\r
+ switch(code)\r
+ {\r
+ case CV_YUV2GRAY_420:\r
+ case CV_YUV2GRAY_UYVY:\r
+ case CV_YUV2GRAY_YUY2:\r
+ return new GRAYwriter();\r
+ default:\r
+ return 0;\r
+ }\r
+}\r
+\r
+template<class convertor>\r
+void referenceYUV2RGB(const Mat& yuv, Mat& rgb, YUVreader* yuvReader, RGBwriter* rgbWriter)\r
+{\r
+ convertor cvt;\r
+\r
+ for(int row = 0; row < rgb.rows; ++row)\r
+ for(int col = 0; col < rgb.cols; ++col)\r
+ rgbWriter->write(rgb, row, col, cvt.convert(yuvReader->read(yuv, row, col)));\r
+}\r
+\r
+template<class convertor>\r
+void referenceYUV2GRAY(const Mat& yuv, Mat& rgb, YUVreader* yuvReader, GRAYwriter* grayWriter)\r
+{\r
+ convertor cvt;\r
+\r
+ for(int row = 0; row < rgb.rows; ++row)\r
+ for(int col = 0; col < rgb.cols; ++col)\r
+ grayWriter->write(rgb, row, col, cvt.convert(yuvReader->read(yuv, row, col)));\r
+}\r
+\r
+CV_ENUM(YUVCVTS, CV_YUV2RGB_NV12, CV_YUV2BGR_NV12, CV_YUV2RGB_NV21, CV_YUV2BGR_NV21,\r
+ CV_YUV2RGBA_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGBA_NV21, CV_YUV2BGRA_NV21,\r
+ CV_YUV2RGB_YV12, CV_YUV2BGR_YV12, CV_YUV2RGB_IYUV, CV_YUV2BGR_IYUV,\r
+ CV_YUV2RGBA_YV12, CV_YUV2BGRA_YV12, CV_YUV2RGBA_IYUV, CV_YUV2BGRA_IYUV,\r
+ CV_YUV2RGB_UYVY, CV_YUV2BGR_UYVY, CV_YUV2RGBA_UYVY, CV_YUV2BGRA_UYVY,\r
+ CV_YUV2RGB_YUY2, CV_YUV2BGR_YUY2, CV_YUV2RGB_YVYU, CV_YUV2BGR_YVYU,\r
+ CV_YUV2RGBA_YUY2, CV_YUV2BGRA_YUY2, CV_YUV2RGBA_YVYU, CV_YUV2BGRA_YVYU,\r
+ CV_YUV2GRAY_420, CV_YUV2GRAY_UYVY, CV_YUV2GRAY_YUY2,\r
+ CV_YUV2BGR, CV_YUV2RGB);\r
+\r
+typedef ::testing::TestWithParam<YUVCVTS> Imgproc_ColorYUV;\r
+\r
+TEST_P(Imgproc_ColorYUV, accuracy)\r
+{\r
+ int code = GetParam();\r
+ RNG& random = theRNG();\r
+\r
+ YUVreader* yuvReader = YUVreader::getReader(code);\r
+ RGBwriter* rgbWriter = RGBwriter::getWriter(code);\r
+ GRAYwriter* grayWriter = GRAYwriter::getWriter(code);\r
+\r
+ int dcn = (rgbWriter == 0) ? grayWriter->channels() : rgbWriter->channels();\r
+\r
+ for(int iter = 0; iter < 30; ++iter)\r
+ {\r
+ Size sz(random.uniform(1, 641), random.uniform(1, 481));\r
+\r
+ if(yuvReader->requiresEvenWidth()) sz.width += sz.width % 2;\r
+ if(yuvReader->requiresEvenHeight()) sz.height += sz.height % 2;\r
+\r
+ Size ysz = yuvReader->size(sz);\r
+ Mat src = Mat(ysz.height, ysz.width * yuvReader->channels(), CV_8UC1).reshape(yuvReader->channels());\r
+\r
+ Mat dst = Mat(sz.height, sz.width * dcn, CV_8UC1).reshape(dcn);\r
+ Mat gold(sz, CV_8UC(dcn));\r
+\r
+ random.fill(src, RNG::UNIFORM, 0, 256);\r
+\r
+ if(rgbWriter)\r
+ referenceYUV2RGB<YUV2RGB_Converter>(src, gold, yuvReader, rgbWriter);\r
+ else\r
+ referenceYUV2GRAY<YUV2GRAY_Converter>(src, gold, yuvReader, grayWriter);\r
+\r
+ cv::cvtColor(src, dst, code, -1);\r
+\r
+ EXPECT_EQ(0, countOfDifferencies(gold, dst));\r
+ }\r
+}\r
+\r
+TEST_P(Imgproc_ColorYUV, roi_accuracy)\r
+{\r
+ int code = GetParam();\r
+ RNG& random = theRNG();\r
+\r
+ YUVreader* yuvReader = YUVreader::getReader(code);\r
+ RGBwriter* rgbWriter = RGBwriter::getWriter(code);\r
+ GRAYwriter* grayWriter = GRAYwriter::getWriter(code);\r
+\r
+ int dcn = (rgbWriter == 0) ? grayWriter->channels() : rgbWriter->channels();\r
+\r
+ for(int iter = 0; iter < 30; ++iter)\r
+ {\r
+ Size sz(random.uniform(1, 641), random.uniform(1, 481));\r
+\r
+ if(yuvReader->requiresEvenWidth()) sz.width += sz.width % 2;\r
+ if(yuvReader->requiresEvenHeight()) sz.height += sz.height % 2;\r
+\r
+ int roi_offset_top = random.uniform(0, 6);\r
+ int roi_offset_bottom = random.uniform(0, 6);\r
+ int roi_offset_left = random.uniform(0, 6);\r
+ int roi_offset_right = random.uniform(0, 6);\r
+\r
+ Size ysz = yuvReader->size(sz);\r
+\r
+ Mat src_full(ysz.height + roi_offset_top + roi_offset_bottom, ysz.width + roi_offset_left + roi_offset_right, CV_8UC(yuvReader->channels()));\r
+ Mat dst_full(sz.height + roi_offset_left + roi_offset_right, sz.width + roi_offset_top + roi_offset_bottom, CV_8UC(dcn), Scalar::all(0));\r
+ Mat gold_full(dst_full.size(), CV_8UC(dcn), Scalar::all(0));\r
+\r
+ random.fill(src_full, RNG::UNIFORM, 0, 256);\r
+\r
+ Mat src = src_full(Range(roi_offset_top, roi_offset_top + ysz.height), Range(roi_offset_left, roi_offset_left + ysz.width));\r
+ Mat dst = dst_full(Range(roi_offset_left, roi_offset_left + sz.height), Range(roi_offset_top, roi_offset_top + sz.width));\r
+ Mat gold = gold_full(Range(roi_offset_left, roi_offset_left + sz.height), Range(roi_offset_top, roi_offset_top + sz.width));\r
+\r
+ if(rgbWriter)\r
+ referenceYUV2RGB<YUV2RGB_Converter>(src, gold, yuvReader, rgbWriter);\r
+ else\r
+ referenceYUV2GRAY<YUV2GRAY_Converter>(src, gold, yuvReader, grayWriter);\r
+\r
+ cv::cvtColor(src, dst, code, -1);\r
+\r
+ EXPECT_EQ(0, countOfDifferencies(gold_full, dst_full));\r
+ }\r
+}\r
+\r
+INSTANTIATE_TEST_CASE_P(cvt420, Imgproc_ColorYUV,\r
+ ::testing::Values(CV_YUV2RGB_NV12, CV_YUV2BGR_NV12, CV_YUV2RGB_NV21, CV_YUV2BGR_NV21,\r
+ CV_YUV2RGBA_NV12, CV_YUV2BGRA_NV12, CV_YUV2RGBA_NV21, CV_YUV2BGRA_NV21,\r
+ CV_YUV2RGB_YV12, CV_YUV2BGR_YV12, CV_YUV2RGB_IYUV, CV_YUV2BGR_IYUV,\r
+ CV_YUV2RGBA_YV12, CV_YUV2BGRA_YV12, CV_YUV2RGBA_IYUV, CV_YUV2BGRA_IYUV,\r
+ CV_YUV2GRAY_420));\r
+\r
+INSTANTIATE_TEST_CASE_P(DISABLED_cvt888, Imgproc_ColorYUV,\r
+ ::testing::Values(CV_YUV2BGR, CV_YUV2RGB));\r
+\r
+INSTANTIATE_TEST_CASE_P(DISABLED_cvt422, Imgproc_ColorYUV,\r
+ ::testing::Values(CV_YUV2RGB_UYVY, CV_YUV2BGR_UYVY, CV_YUV2RGBA_UYVY, CV_YUV2BGRA_UYVY,\r
+ CV_YUV2RGB_YUY2, CV_YUV2BGR_YUY2, CV_YUV2RGB_YVYU, CV_YUV2BGR_YVYU,\r
+ CV_YUV2RGBA_YUY2, CV_YUV2BGRA_YUY2, CV_YUV2RGBA_YVYU, CV_YUV2BGRA_YVYU,\r
+ CV_YUV2GRAY_UYVY, CV_YUV2GRAY_YUY2));\r