androidc++opencvyuv

Convert YUV frames to RGB


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: enter image description here

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)

And this is the result: enter image description here


Solution

  • 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!