Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Failing to display YUV image correctly

Hello,

I am writing a program that must read from a 4:2:0 chroma subsampled yuv video file and display it on screen. Program is working but shows wrong colors. And I could not find where error is.

Picture I see:

Picture I see

Picture I must see:

Picture I must see

Unfortunately, I must use OpenCV 2.1 and C API (iplimage...).

My code:

int main()
{
    int iFrameWidth = 640;
    int iFrameHeight = 480;

    FILE *fYUV0 = fopen( "C:\\YUV_Videos\\flamenco2_0.yuv", "rb" );

    char *cFileBuffer0 = new char[ iFrameWidth*iFrameHeight*3/2 ];

    IplImage *iplY420Frame = cvCreateImageHeader( cvSize(iFrameWidth  , iFrameHeight  ), IPL_DEPTH_8U, 1 );
    IplImage *iplU420Frame = cvCreateImageHeader( cvSize(iFrameWidth/2, iFrameHeight/2), IPL_DEPTH_8U, 1 );
    IplImage *iplV420Frame = cvCreateImageHeader( cvSize(iFrameWidth/2, iFrameHeight/2), IPL_DEPTH_8U, 1 );

    IplImage *iplY444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );
    IplImage *iplU444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );
    IplImage *iplV444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );

    IplImage *iplYUV444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 3 );

    IplImage *iplRGBFrame0 = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 3 );

    while( fread(cFileBuffer0, 1, iFrameWidth*iFrameHeight*3/2, fYUV0) )
    {
        cvSetData( iplY420Frame, cFileBuffer0, iFrameWidth );
        cvSetData( iplU420Frame, cFileBuffer0 + iFrameWidth*iFrameHeight, iFrameWidth/2 );
        cvSetData( iplV420Frame, cFileBuffer0 + iFrameWidth*iFrameHeight*5/4, iFrameWidth/2 );      
        cvResize( iplY420Frame, iplY444Frame );
        cvResize( iplU420Frame, iplU444Frame );
        cvResize( iplV420Frame, iplY444Frame );
        cvMerge( iplY444Frame, iplU444Frame, iplV444Frame, NULL, iplYUV444Frame );
        cvCvtColor( iplYUV444Frame, iplRGBFrame0, CV_YCrCb2BGR );

        cvNamedWindow( "View0" );
        cvShowImage( "View0", iplRGBFrame0 );
        cvWaitKey( 1000/25 );
    }//end-of-while
    cvDestroyWindow( "View0" );
    return 0;
}//end-of-main

Failing to display YUV image correctly

Hello,

I am writing a program that must read from a 4:2:0 chroma subsampled yuv video file and display it on screen. Program is working but shows wrong colors. And I could not find where error is.

Picture I see:

Picture I see

Picture I must see:

Picture I must see

Unfortunately, I must use OpenCV 2.1 and C API (iplimage...).

My code:

int main()
{
    int iFrameWidth = 640;
    int iFrameHeight = 480;

    FILE *fYUV0 = fopen( "C:\\YUV_Videos\\flamenco2_0.yuv", "rb" );

    char *cFileBuffer0 = new char[ iFrameWidth*iFrameHeight*3/2 ];

    IplImage *iplY420Frame = cvCreateImageHeader( cvSize(iFrameWidth  , iFrameHeight  ), IPL_DEPTH_8U, 1 );
    IplImage *iplU420Frame = cvCreateImageHeader( cvSize(iFrameWidth/2, iFrameHeight/2), IPL_DEPTH_8U, 1 );
    IplImage *iplV420Frame = cvCreateImageHeader( cvSize(iFrameWidth/2, iFrameHeight/2), IPL_DEPTH_8U, 1 );

    IplImage *iplY444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );
    IplImage *iplU444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );
    IplImage *iplV444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 1 );

    IplImage *iplYUV444Frame = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 3 );

    IplImage *iplRGBFrame0 = cvCreateImage( cvSize(iFrameWidth, iFrameHeight), IPL_DEPTH_8U, 3 );

    while( fread(cFileBuffer0, 1, iFrameWidth*iFrameHeight*3/2, fYUV0) )
    {
        cvSetData( iplY420Frame, cFileBuffer0, iFrameWidth );
        cvSetData( iplU420Frame, cFileBuffer0 + iFrameWidth*iFrameHeight, iFrameWidth/2 );
        cvSetData( iplV420Frame, cFileBuffer0 + iFrameWidth*iFrameHeight*5/4, iFrameWidth/2 );      
        cvResize( iplY420Frame, iplY444Frame );
        cvResize( iplU420Frame, iplU444Frame );
        cvResize( iplV420Frame, iplY444Frame );
        cvMerge( iplY444Frame, iplU444Frame, iplV444Frame, NULL, iplYUV444Frame );
        cvCvtColor( iplYUV444Frame, iplRGBFrame0, CV_YCrCb2BGR );

        cvNamedWindow( "View0" );
        cvShowImage( "View0", iplRGBFrame0 );
        cvWaitKey( 1000/25 );
    }//end-of-while
    cvDestroyWindow( "View0" );
    return 0;
}//end-of-main

PS: Using CV_YCrCb2RGB instead of CV_YCrCb2BGR as above, does not help too. I still get some artificial vertical lines.