opencv 读取 yuv(4:2:0)

#include <opencv/highgui.h>
#include <stdio.h>

 

//#include <>

#define nWidth 352
#define nHeight 288
#define FrameSize nWidth*nHeight*3/2
int _tmain(int argc, _TCHAR* argv[])
{
 /*IplImage *img = cvLoadImage("D:\\workspace\\cv_yun\\DSC_1598.JPG");
 cvNamedWindow("a");
 cvShowImage("a",img);
 cvWaitKey(0);
 */


 FILE *f ;
 if(!(f = fopen("目录\\foreman_cif.yuv","rb")))
 {
  printf("file open error!");
 }


 // calculate the frame num
 fseek(f, 0, SEEK_END);
 int frame_count = 0;
 long file_size = 0;
 frame_count = (int) ((int)ftell(f)/((nWidth * nHeight * 3) / 2));  // ftell 用于求文件大小
 printf("frame num is %d \n", frame_count);
 printf("file length is   %d",ftell(f));


 fseek(f, 0, SEEK_SET);//文件内位置定位到文件头
 //IplImage *img = cvCreateImage(cvSize(352,288),IPL_DEPTH_8U,1);
 //IplImage *grey;
 IplImage *yimg = cvCreateImage(cvSize(nWidth, nHeight),IPL_DEPTH_8U,1);
 //IplImage *uimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);  
    //IplImage *vimg = cvCreateImageHeader(cvSize(nWidth/2, nHeight/2),IPL_DEPTH_8U,1);
 

 //----------------------------------------------------------------------实现读取一个文件 显示照片
 unsigned char *pBuf = new unsigned char[nWidth*nHeight*3/2];
 fread(pBuf, 1, (nWidth * nHeight * 3) / 2, f);// nWidth*nHeight*3/2  means 本程序使用 yuv:4:2:0 yuv分为 Y Cb Cr 三部分
 cvSetData(yimg, pBuf, nWidth);

 cvNamedWindow("a");
 cvShowImage("a", yimg);
 cvWaitKey( 0 );


 //----------------------------------------------------------------------读取yuv文件的y部分 类似于播放器效果 
 /*unsigned char *pBuf = new unsigned char[nWidth*nHeight*3/2];
 int pos = 0;
 for(int i = 0; i<frame_count-1; i++ )
 {
  fseek(f, pos, SEEK_SET);
  fread(pBuf,1 , FrameSize, f );
  cvSetData(yimg, pBuf, nWidth);
  cvNamedWindow("a");
  cvShowImage("a", yimg);
  cvWaitKey( 33 );
  pos += FrameSize;
 }
 */


 cvDestroyWindow("a");
 cvReleaseImage(&yimg);
 delete []pBuf;

 fclose(f);
 return 0;
}
原文链接http://blog.csdn.net/david412306524/article/details/7672517
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV可以通过cv::VideoCapture类读取常见的视频文件格式,如.avi和.mp4等。然而,在某些应用场景中,我们需要读取yuv格式的原始视频数据,例如压缩算法的研究或图像处理的探索。在这种情况下,OpenCV提供了一个cv::VideoCapture类,可以读取yuv格式的视频数据。 使用cv::VideoCapture::open()打开yuv文件时,需要指定文件的路径,并设置四个参数:视频宽度、视频高度、帧率和视频格式。对于yuv文件,格式通常是YUV 4:2:0或YUV 4:2:2。例如: cv::VideoCapture capture; std::string filename = "path/to/yuvfile.yuv"; int width = 1920; int height = 1080; int fps = 30; int format = CV_8UC1; // YUV格式通常为单通道 bool success = capture.open(filename, cv::CAP_ANY); if (!success) { std::cerr << "Error: Failed to open the video file." << std::endl; return -1; } 读取yuv文件时,每个帧通常由Y、U和V三个分量组成。因此,我们需要使用不同的函数读取不同的分量。例如: cv::Mat yuv_image; cv::Mat y_plane(height, width, format); cv::Mat u_plane(height / 2, width / 2, format); cv::Mat v_plane(height / 2, width / 2, format); while (capture.read(yuv_image)) { // 分离y、u、v分量 cv::extractChannel(yuv_image, y_plane, 0); cv::extractChannel(yuv_image, u_plane, 1); cv::extractChannel(yuv_image, v_plane, 2); // 处理y分量 // ... // 将分量合并以重构原始图像 cv::Mat bgr_image; cv::merge(std::vector<cv::Mat>{y_plane, u_plane, v_plane}, bgr_image); // 显示图像 cv::imshow("Video", bgr_image); cv::waitKey(1); } 需要注意的是,由于yuv文件的像素值通常不是8位,而是10位,12位等,因此需要根据实际情况对像素值进行缩放和偏移。此外,在将Y、U和V三个分量合并以重构原始图像之前,需要将U和V分量上采样到与Y分量相同的分辨率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值