opencv 读取 yuv(4:2:0)

YUV文件读取与显示
本文介绍了一个简单的C++程序,该程序使用OpenCV库从YUV格式的文件中读取帧,并将它们显示出来。程序首先打开指定的YUV文件,计算总的帧数,然后读取并显示每一帧。

#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;
}

 

虽然所给引用未直接提及OpenCV读取V4L2设备YUV格式数据的方法,但可以从相关内容中获取一些思路。 在某些场景下,由于要将程序移植到板子上,不能直接使用OpenCV读取摄像头的函数,需要借助V4L2来实现读取视频的功能,例如使用V4L2读取MJPEG格式数据时,在OpenCV4中要修改缓存区图像尺寸以及通道数,避免因传输进Imdecode中尺寸不匹配报错 [^1][^2]。 对于读取YUV格式数据,可能也需要进行类似的处理,并且要考虑YUV格式的特点。由于YUV数据量较大,可能会影响摄像头读取速度和视频数据传输扩展,需要在处理时进行优化。 以下是一个简单的伪代码示例,展示可能的实现框架: ```python # 假设存在V4L2Capture类来从V4L2设备获取数据 class V4L2Capture: def __init__(self): # 初始化V4L2设备 pass def getFrame(self): # 从V4L2设备获取YUV格式数据 # 返回YUV数据和数据大小 return yuv_data, data_size def backFrame(self): # 释放图像资源 pass import cv2 import numpy as np # 创建V4L2Capture对象 cap = V4L2Capture() while True: # 获取YUV数据 yuv_data, data_size = cap.getFrame() # 将YUV数据转换为OpenCV可处理的格式 # 这里需要根据具体的YUV格式进行转换 # 例如,假设是YUV422格式 img_me = np.frombuffer(yuv_data, dtype=np.uint8) img_me = img_me.reshape((capH, capW, 2)) # 根据实际尺寸调整 # 将YUV转换为BGR格式 img_bgr = cv2.cvtColor(img_me, cv2.COLOR_YUV2BGR_YUYV) # 显示图像 cv2.imshow('YUV Image', img_bgr) # 释放图像资源 cap.backFrame() # 按 'q' 键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cv2.destroyAllWindows() ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值