I'm trying to convert YUV file(UYUV, YUV 422 Interleaved,BT709) to RGB with C++. I've took the example from here: https://stackoverflow.com/a/72907817/2584197 This is my code:
Size iSize(1920,1080);
int iYUV_Size = iSize.width * (iSize.height + iSize.height / 2);
Mat mSrc_YUV420(cv::Size(iSize.width, iSize.height + iSize.height / 2),CV_8UC1);
ifstream FileIn;
FileIn.open(filename, ios::binary | ios::in);
if (FileIn.is_open())
{
FileIn.read((char*)mSrc_YUV420.data, iYUV_Size);
FileIn.close();
}
else
{
printf("[Error] Unable to Read the Input File! \n");
}
Mat mSrc_RGB(cv::Size(iSize.width, iSize.height), CV_8UC1);
cv::cvtColor(mSrc_YUV420, mSrc_RGB, COLOR_YUV2RGB_UYVY);
cv::imwrite(output_filename, mSrc_RGB);
But I get this error:
terminating with uncaught exception of type cv::Exception: OpenCV(4.5.5) /build/master_pack-android/opencv/modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function 'cv::impl::(anonymous namespace)::CvtHelper<cv::impl::(anonymous namespace)::Set<2, -1, -1>, cv::impl::(anonymous namespace)::Set<3, 4, -1>, cv::impl::(anonymous namespace)::Set<0, -1, -1>, cv::impl::(anonymous namespace)::NONE>::CvtHelper(cv::InputArray, cv::OutputArray, int) [VScn = cv::impl::(anonymous namespace)::Set<2, -1, -1>, VDcn = cv::impl::(anonymous namespace)::Set<3, 4, -1>, VDepth = cv::impl::(anonymous namespace)::Set<0, -1, -1>, sizePolicy = cv::impl::(anonymous namespace)::NONE]' Invalid number of channels in input image: 'VScn::contains(scn)' where 'scn' is 1
When I change the CV_8UC1 to CV_8UC2, I don't get error, but this is the result:
I was able to do the conversion using the following python code:
with open(input_name, "rb") as src_file:
raw_data = np.fromfile(src_file, dtype=np.uint8, count=img_width*img_height*2)
im = raw_data.reshape(img_height, img_width, 2)
rgb = cv2.cvtColor(im, cv2.COLOR_YUV2RGB_UYVY)
The problem was that UYVY is 2 bytes, so I have to double the size of the image. Now with thelines
int iYUV_Size = iSize.width * iSize.height * 2;
Mat mSrc_YUV420(cv::Size(iSize.width, iSize.height),CV_8UC2);
it works well.
Thanks, @micka for the help!