V4L2+QT+USB摄像头实时显示视频(Arm,Linux,window均适用)

这篇具有很好参考价值的文章主要介绍了V4L2+QT+USB摄像头实时显示视频(Arm,Linux,window均适用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在开头

笔者自从学习了Framebuffer编程和V4L2编程之后,就想实现在LCD屏上显示实时视频

笔者学习过正点I.MX6U Linux C编程中的相关内容,然而原子的例程是针对OV5640摄像头写的,像素格式是RGB

然而USB摄像头大多支持MJPEG或者YUYV格式,如果要在屏幕上显示需要进行格式转换,而转换像素格式是需要处理时间的,自然会影响视频帧率

笔者尝试写过YUYV2RGB888或者YUYV2RGB565,实际跑起来能明显感受到掉帧;
同时,笔者也考虑通过OpenCV来对JPEG或者YUYV进行编解码来显示,然而实际效果也不尽如人意

那有没有办法既能实时显示视频也不用进行图像格式转换还能有用户操作界面?

笔者结合之前所学内容最终决定用QT写界面,V4L2编程来获取实时的帧并将其显示在设计好的界面上

开发环境

  1. 虚拟机Ubuntu 16.04
  2. 编辑器VsCode
  3. 交叉编译工具 arm-linux-gnueabihf
  4. 已制作文件系统,已使能UVC相关驱动
  5. 正点原子ZYNQ7010启明星开发板
  6. USB摄像头淘宝随便买的一个
  7. QT Creator 5.9.6

必备知识

UVC驱动配置可以看我的这一篇: Linux 内核4.14添加UVC配置

QT移植并显示图片可以看我的这一篇: Qt移植正点原子ZYNQ7010-Arm平台显示图片demo,本博客的程序设计也是基于这一篇文章的

V4L2编程入门可以看我的这一篇: V4L2编程之USB摄像头采集jpeg图像

界面布局设计

V4L2+QT+USB摄像头实时显示视频(Arm,Linux,window均适用)
可以先看一下运行效果,主体部分一共就三个:一个QLabel控件用于显示实时图像,两个QPushButton,一个用于控制视频流的显示,另一个用于解放资源并关闭窗口。

界面很简单,本博客只是实现最基础的功能,后续会在此基础上加控件和其他功能。

程序设计思路

  1. 界面布局初始化
  2. 获得用户输入,打开对应摄像头
  3. 摄像头初始化,包括打印摄像头支持的像素格式、分辨率、帧率
  4. 设置采集格式,包括像素格式、帧率设置
  5. 申请内存空间并建立内存映射,进行出队入队操作
  6. 开启视频流
  7. 设置定时器,等待“开始”按钮信号触发定时器开启
  8. 定时器定时获取一帧图像将其显示在QLabel上
  9. 等待“结束”按钮信号触发释放资源并关闭窗口

关键部分在于789三步,这里稍作解释,不想看的可直接去看源码——我的Github仓库: Linux C编程实战代码
我已经将源码连同V4L2编程的API用户手册一并上传了,欢迎大家学习交流

要在ARM平台跑也是可以的,需要自行移植QT到ARM开发板,移植办法详见我往期博客Qt移植正点原子ZYNQ7010-Arm平台显示图片demo

关键代码分析

获取用户输入赋值给v4l2_dev_init()初始化对应的摄像头
引入QCoreApplication获取用户输入的第二个字段,例如执行 ./Qt_V4l2 /dev/video1,device_parm[1] 的内容即/dev/video1
值得注意的是需要进行一个数据类型转换才能作为open()函数的参数

    QStringList device_parm = QCoreApplication::arguments();
    QString str = device_parm[1];

    v4l2_dev_init(str.toStdString());
    
    ......
    
	int MainWindow::v4l2_dev_init(string device_name){
	    /* 打开摄像头 */
	    v4l2_fd = open(device_name.c_str(),O_RDWR);
	    if(v4l2_fd < 0){
	        printf("open camera failed\n");
	        return -1;
	    }
	    printf("open camera success\n");
	    
	    ......
	    
	 }

两个按钮的信号连接代码

    //点击开始按钮,打开定时器
    connect(pushButton[0],SIGNAL(clicked()),this,SLOT(timer_start()));

    //每隔固定的时间显示一帧
    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), this, SLOT(video_show()));

    /* 按钮窗口关闭,先释放设备,再关闭窗口 */
    connect(pushButton[1],SIGNAL(clicked()),this,SLOT(v4l2_device_release()));
    connect(pushButton[1],SIGNAL(clicked()),this,SLOT(close()));

定时器控制帧率,每个33ms触发video_show()显示一帧数据,一秒钟正好显示30帧(笔者的摄像头最大支持30fps,故如此设置)

/* 定时器控制帧 */
void MainWindow::timer_start(){
    // 1000/33约等于30,也就是每一秒显示30帧
    timer->start(33);
}

初始化select()来进行I/O端口复用

    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(v4l2_fd,&fds);

    //设置等待时间为2s
    struct timeval tv;
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    select(v4l2_fd+1,&fds,NULL,NULL,&tv);

此段代码摘自V4L2 API手册最后的示例代码中,相关pdf文档已上传到github

获取一帧图像的数据,见于v4l2_get_one_frame(FrameBuffer *framebuf)
首先从出队队列中取一帧视频数据的视频缓冲区,再将该帧数据拷贝到frame中

    if(0 > ioctl(v4l2_fd,VIDIOC_DQBUF,&one_buf)){
        printf("VIDIOC_DQBUF failed!\n");
        return -1;
    }
	// bytesused 表示buf中已经使用的字节数
	    memcpy(framebuf->buf,(char *)buffer_infos[one_buf.index].start,one_buf.bytesused);
	    framebuf->length = one_buf.bytesused;

Qt 提供了四个用于处理图像数据的类,而 QPixmap 正是为在屏幕上显示图像而设计和优化
最后将获取保存在frame中的数据用QPixmap转换就可以显示了

     FrameBuffer frame;
     QPixmap pix;

     //获取一帧显示
     v4l2_get_one_frame(&frame);
     pix.loadFromData(frame.buf, frame.length);
     pix.scaled(displayLabel->width(),displayLabel->height(),Qt::KeepAspectRatio);
     displayLabel->setPixmap(pix);

结束语

本博客的程序已上传到github中,往期博客有关Linux C编程的代码也一并上传,需要的自行下载
地址:https://github.com/Huge-Hammer/Linux-C-Coding

后续会继续更新,通过程序设计来实现拍照截图、图像处理、视频流的存储和推流等功能,慢慢完善了

我是爱学习的诸葛铁锤,觉得有帮助的话记得点个赞再走吧,wakuwaku!

V4L2+QT+USB摄像头实时显示视频(Arm,Linux,window均适用)文章来源地址https://www.toymoban.com/news/detail-401330.html

到了这里,关于V4L2+QT+USB摄像头实时显示视频(Arm,Linux,window均适用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c 摄像头利用v4l2直接生成avi视频(不利用ffmpeg)

    自定义avi结构头文件。现在不能实时显示摄像头画面,准备参照fim(终端中显示图片),直接对显示framebuffer操作,显示视频。不用qt等。 生成的视频根据机子的性能不同,诂计要手动调一下生成视频的帧率。 播放: $ aplay  musicdemo.wmv 录音: $ arecord -c 2 -r 44100 -f S16_LE musicd

    2024年02月08日
    浏览(42)
  • 使用QT的QML实时显示海康威视网络摄像头的视频数据

    需求背景: 开发的监控软件中有个监控页面需要实时显示网络摄像头的数据,整个监控软件是基于QT的QML语言开发的。在QML中播放视频使用MediaPlayer组件就可以,但网上看到的一些都是播放录制好的视频文件,对于实时播放摄像头数据介绍的比较少。 开发环境: Debian11.3 Qt

    2024年02月09日
    浏览(109)
  • opencv-python调用摄像头失败 global /io/opencv/modules/videoio/src/cap_v4l.cpp (1000) tryIoctl VIDEOIO(V4L2

    Ubuntu 18.04 aarch64 Python 3.7.15 opencv-python 4.6.0 插入USB摄像头后, /dev/video0 会正常出现,使用 fswebcam 也能正常拍摄照片。但运行 opencv-python 的视频拍摄例程时出错,例程如下。 如果例程正确运行,屏幕窗口中将显示灰度处理后的摄像头实时视频。 报错信息如下 单步调试后,发现

    2023年04月24日
    浏览(77)
  • RK3568-USB摄像头实时AI物品识别

    RK3568具有1TOPS算力的NPU,可以在板子上进行AI计算。飞凌OK3568板子资料中自带了一些AI识别的例子,但只是对一张图片进行识别,且需要单独使用图片查看工具查看识别结果。 为了更直观的体验RK3568的AI算力,将AI识别例程与摄像头功能结合起来,对摄像头的每一帧图像进行物

    2024年02月10日
    浏览(56)
  • Ubuntu下python-opencv无法打开摄像头,open VIDEOIO(V4L2:/dev/video0): can‘t open camera by index

    我们在ubuntu下使用opencv获取摄像头画面是,报错 open VIDEOIO(V4L2:/dev/video0): can‘t open camera by index 然后观察虚拟机桌面的右下角,如果出现摄像头有小绿点表示连接成功 然后我们来测试一下,摄像头的画面 ####### 这是摄像头传输回来的画面

    2024年02月16日
    浏览(47)
  • Python OpenCV读取并显示USB UVC摄像头

    1. 安装Python, 略。 2. 安装 OpenCV:         3. 预览摄像头画面脚本:

    2024年02月13日
    浏览(51)
  • RK3588安装Qt+opencv+采集USB摄像头画面

    Qt:5.12.8 opencv:3.4.14 qt安装 ---------------------------------------------------------------------------------- 因为使用官网下载的版本始终安装失败,所以我可以直接使用命令行进行下载安装: 1:首先先将ubuntu的软件更新,并更新镜像源 sudo apt-get update sudo apt-get upgrade 2:使用如下步骤安装Qt

    2023年04月10日
    浏览(59)
  • linux v4l2架构分析之异步注册v4l2_async_subdev_notifier_register、v4l2_async_register_subdev、v4l2_async_notifie

            在camera驱动注册中,v4l2_async_subdev_notifier_register、v4l2_async_register_subdev、v4l2_async_notifier_register这几个函数都会被使用到,三者在异步注册的实现中是紧密关联的,所以本文将三者放在一起进行分析。本文主要介绍异步注册的功能的整体实现框架,为了更好把握整体思

    2024年02月14日
    浏览(51)
  • python调用海康网络摄像头,实时显示监控内容

    用网线将海康威视摄像头与电脑连接在一起;(或者用交换机,在一个交换机下面) 海康摄像头的默认ip是192.168.1.64 效果:和通过海康摄像头网址效果一样 rtsp://用户名:密码@ip地址/Streaming/Channels/2

    2024年02月16日
    浏览(42)
  • 使用 MFC 和 OpenCV 实现实时摄像头视频显示

    1、引言 MFC 是一个在 Windows 平台上编写 C++ 应用程序的库,提供了丰富的用户界面功能。OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,包含了丰富的图像处理和计算机视觉功能。本文将向大家展示如何将这两个库结合起来,实现一个实时显示摄像头画面的简

    2024年02月13日
    浏览(98)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包