OpenCV - 无法正确显示 YUV 图像
OpenCV - Failing to display YUV image correctly
我正在编写一个程序,简要地执行以下操作:
- 从 .yuv 文件读取 YUV 4:2:0 帧
- 将帧从 YUV 转换为 RGB
- 对RGB帧进行一些操作
- 显示RGB帧
- 重复前面的步骤,直到 .yuv 文件中没有剩余帧
我目前省略了第3步,我现在不对RGB帧进行任何操作。因为我的程序没有以正确的颜色显示框架。
这是我使用 OpenCV 2.1 的代码:
我的代码有什么问题??
我还添加了第一帧的实际颜色和错误颜色的图片。错误的彩色图片是从 YUV 转换为 BGR (CV_YCrCb2BGR) 的结果。但是不幸的是,从 YUV 转换为 RGB (CV_YCrCb2RGB) 没有帮助。
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
第一帧的实际颜色,从 YUV 播放器获取:
http://i59.tinypic.com/2n7ee6h.jpg
第一帧颜色错误,我的程序输出:
找到了!实际上我发现它已经两个多星期了但是在这里:我正在将 V 组件调整为 Y 组件。
...
cvResize( iplY420Frame, iplY444Frame );
cvResize( iplU420Frame, iplU444Frame );
cvResize( iplV420Frame, iplY444Frame ); // iplY444Frame must be corrected as iplV444Frame
...
经验教训:
永远不要只用一个字母命名变量,单词永远是最好的。
我正在编写一个程序,简要地执行以下操作:
- 从 .yuv 文件读取 YUV 4:2:0 帧
- 将帧从 YUV 转换为 RGB
- 对RGB帧进行一些操作
- 显示RGB帧
- 重复前面的步骤,直到 .yuv 文件中没有剩余帧
我目前省略了第3步,我现在不对RGB帧进行任何操作。因为我的程序没有以正确的颜色显示框架。
这是我使用 OpenCV 2.1 的代码:
我的代码有什么问题??
我还添加了第一帧的实际颜色和错误颜色的图片。错误的彩色图片是从 YUV 转换为 BGR (CV_YCrCb2BGR) 的结果。但是不幸的是,从 YUV 转换为 RGB (CV_YCrCb2RGB) 没有帮助。
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
第一帧的实际颜色,从 YUV 播放器获取:
http://i59.tinypic.com/2n7ee6h.jpg
第一帧颜色错误,我的程序输出:
找到了!实际上我发现它已经两个多星期了但是在这里:我正在将 V 组件调整为 Y 组件。
...
cvResize( iplY420Frame, iplY444Frame );
cvResize( iplU420Frame, iplU444Frame );
cvResize( iplV420Frame, iplY444Frame ); // iplY444Frame must be corrected as iplV444Frame
...
经验教训:
永远不要只用一个字母命名变量,单词永远是最好的。