Linux环境下使用V4L2+opencv以MJPEG格式读取USB摄像头并实时显示

本文详述了在Linux环境下利用V4L2与MJPEG格式读取USB摄像头视频的过程,包括参数初始化、帧缓冲区申请、视频采集及显示,最终实现了1920*1080分辨率的实时视频流处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转眼间,V4L2已经搞了很长时间,从最开始的一窍不通,到后来的渐渐熟悉,从最开始照猫画虎的使用YUYV格式之间转换,到后来使用MJPEG格式读取,中间颇有周折。趁任务完成间隙,来简单总结下V4L2的使用。(文章只主要写了过程,完整程序已经附在最后)

有读者要问,opencv已经有相关的读取摄像头的函数,为什么要使用V4L2这么麻烦呢。其实主要是因为后面要将程序移植到板子上,而在板子上不能直接使用opencv中读取摄像头的函数的,所以需要借助V4L2来实现读取视频的功能。还有,既然YUYV格式这么简单(见文章末尾附的大神的博客),为什么要用MJPEG格式呢?这一点主要是考虑到YUYV数据量较大,影响摄像头读取速度,也会影响到后面都视频数据传输的扩展。

V4L2主要应用于linux读取USB摄像头,有关它的介绍网上有很多资料,这里不再赘述。结合主题,本文主要讲述如何使用MJPEG格式读取并将其转换为OpenCV中的IplImage格式,以方便进行图像处理,最后以视频的形式进行实时显示。截至到今天晚上,已经使得程序能够实时以MJPEG格式读取并显示,图像分辨率为1920*1080,速度100ms每帧。由于项目需要,所以尽可能使用较大分辨率,导致速度有点慢,如果使用普通的640*480,速度比较会比较快。

有点啰嗦,下面进入主题:使用MJPEG格式读取视频,并实时显示。整个过程主要分为以下几个步骤:

1.      打开视频设备文件,并进行参数初始化,设置采集分辨率、格式等;

该步骤中主要使用函数:

Open(“/dev/video0”,O_RDWR);//打开USB摄像头

ioctl(fd,VIDIOC_QUERYCAP,&cap);//查询设备的信息

ioctl(fd,VIDIOC_S_STD,&fmt);//设置视频的格式

2.      申请帧缓冲区,并将其映射到用户空间;

ioctl(fd,VIDIOC_REQBUFS,&req);//申请缓冲帧

malloc(req.count*sizeof(*buffer));

ioctl(fd,VIDIOC_QUERYBUF,&buf);//将申请到的帧缓冲映射到用户空间

3.      将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;

ioctl(fd,VIDIOC_QBUF,&buf);//将申请到的帧缓冲全部加入队列

ioctl(fd,VIDIOC_STREAMON,&byte);//开始采集

4.      应用程序从视频采集输入队列取出帧缓冲区,将其转换为OpenCV中的通用数据格式,然后显示,之后重新放入视频采集队列,循环该过程;

ioctl(fd,VIDIOC_DQBUF,&buf);//取缓冲帧

CvMatcvmat=cvMat(IMAGEHEIGHT,IMAGEWIDTH,CV_8UC3,(void*)buffer);//将帧内容赋值给CvMat格式的数据

IplImage img =cvDecodeImage(&cvmat,1);//解码,这一步将数据转换为IplImage格式

cvShowImage(“one”,img);//显示图像

cvReleaseImage(&img);//释放图像空间

ioctl(fd,VIDIOC_QBUF,&buf);//将缓冲重新加入队尾

循环上面的步骤,就可以形成视频啦

5.      停止视频采集,关闭设备文件。

ioctl(fd,VIDIOC_STREAMOFF,&byte);

close(fd);

 

由于时间关系,上面只是简单介绍了一下整个过程,相关函数的使用和函数中的结构体参数网上都有很多资料可供参考,当然也可以看下官方给的API手册,讲的很详细,但是有点长,且是英文的。下面列出我学习时找到的一些资料,

最后附上我自己的程序,目前程序能够实现基本的功能,但是本人还想进一步优化以提高效率,有其他好的想法的朋友可以与我联系。Mail:tsuibeyond@foxmail.com

一个大神的博客,最开始我就是按照这个学习的

网址:<http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html>

V4L2的官方手册:

网址:<http://v4l.videotechnology.com/dwg/v4l2.pdf>

我自己的程序:

网址:<http://download.youkuaiyun.com/download/tsuibeyond/10256918>

程序是在linux环境下使用QT编译的,需要自己安装OPENCV,并在.pro文件中配置,我的.pro文件中已经将相关路径写入,读者使用时可以按照自己安装OPENCV的路径修改。

最后,加上效果图展示,由于分辨率较大,屏幕不能显示完整窗口:

在本文中,我们将探讨如何利用OpenCV4和V4L2读取双目摄像头MJPEG视频流。双目摄像头由两个排传感器组成,能够捕捉立体图像实现深度感知。OpenCV4是一个功能强大的计算机视觉库,而V4L2Linux内核中用于与视频设备通信的接口。我们将重点了解OpenCV4中的VideoCapture类,它是OpenCV捕获视频的核心组件,支持多种视频源,包括摄像头和视频文件等。在我们的应用场景中,我们将通过该类连接V4L2驱动,读取双目摄像头MJPEG流。为此,我们需要分别打开两个VideoCapture实例,对应双目摄像头的左、右镜头。代码示例如下: 其中,"/dev/video0"和"/dev/video1"是双目摄像头左、右镜头在系统中的设备文件路径,需根据实际设备进行调整。接下来,我们需设置摄像头参数,如分辨率和帧率,可通过调用VideoCapture的set()函数实现: 设置好参数后,即可开始读取帧。由于摄像头输出的是MJPEG格式,需先解码再处理图像。OpenCV4支持MJPEG解码,但需在读取帧时设置正确格式: 之后,可循环读取处理每帧图像: 处理双目图像通常涉及立体视觉算法,如SGBM或BM。这些算法通过比较左右两帧图像的像素差异来计算深度值,但在实际应用中还需考虑对齐、校正、遮挡处理等复杂步骤。总之,OpenCV4结合V4L2库能方便地读取处理双目摄像头MJPEG视频流。掌握VideoCapture类的使用摄像头参数设置及MJPEG解码后,可构建基础双目视觉系统。然而,这只是起点,实现高效的深度感知和三维重建还需深入理解和实践立体视觉算法。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值