当前位置: 首页 > news >正文

Linux基于V4L2的视频捕捉

简介

linux环境使用V4l2实现摄像头捕捉,界面流畅播放并可以保存图片到本地。

代码

void VideoCapture::run()
{qDebug() << "VideoCapture start";// 打开设备int fd = open("/dev/video0", O_RDWR);if(fd < 0){qDebug("video设备打开失败\n");return;}else{qDebug("video设备打开成功\n");}//查看设备是否为视频采集设备struct v4l2_capability vcap;ioctl(fd, VIDIOC_QUERYCAP, &vcap);if (!(V4L2_CAP_VIDEO_CAPTURE & vcap.capabilities)){qDebug("No capture video device!\n");return;}// 枚举帧格式struct v4l2_fmtdesc fmtdesc;fmtdesc.index = 0;fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;qDebug("Video支持所有格式如下:");while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0){qDebug("v4l2_format %d:%s",fmtdesc.index, fmtdesc.description);fmtdesc.index++;}// 枚举分辨率struct v4l2_frmsizeenum frmsize;frmsize.index = 0;frmsize.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;qDebug("Video支持分辨率如下:");while(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0){qDebug("%d frame_size<%d*%d %d>", frmsize.index, frmsize.discrete.width, frmsize.discrete.height, frmsize.pixel_format);frmsize.index++;}// 枚举某分辨率下的帧速率int pixel_width = 1280;int pixel_height = 720;struct v4l2_frmivalenum frmival;frmival.index = 0;frmival.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;frmival.pixel_format = V4L2_PIX_FMT_MJPEG;frmival.width = pixel_width;frmival.height = pixel_height;while(ioctl(fd,VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == 0){qDebug("<%d*%d> support frame_size %dfps", frmival.width, frmival.height, frmival.discrete.denominator / frmival.discrete.numerator);frmival.index++;}// 设置采集格式struct v4l2_format vfmt;vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;vfmt.fmt.pix.width = pixel_width;vfmt.fmt.pix.height = pixel_height;vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;if(ioctl(fd, VIDIOC_S_FMT, &vfmt) < 0){qDebug("video设置格式失败\n");return;}// 检查设置参数是否生效if(ioctl(fd, VIDIOC_G_FMT, &vfmt) < 0){qDebug("video获取格式失败\n");return;}// 获取帧信息struct v4l2_streamparm streamparm;streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;ioctl(fd, VIDIOC_G_PARM, &streamparm);qDebug("current frameRate <%d * %d>\n", streamparm.parm.capture.timeperframe.numerator, streamparm.parm.capture.timeperframe.denominator);// 设置帧信息if(V4L2_CAP_TIMEPERFRAME & streamparm.parm.capture.capability){streamparm.parm.capture.timeperframe.numerator = 1;streamparm.parm.capture.timeperframe.denominator = 30;
//        if(ioctl(fd, VIDIOC_S_PARM, &streamparm) < 0)
//        {
//            qDebug("video设置帧率失败 <%d * %d>", streamparm.parm.capture.timeperframe.numerator, streamparm.parm.capture.timeperframe.denominator);
//        }}// 申请缓冲区空间struct v4l2_requestbuffers reqbuf;reqbuf.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;reqbuf.count = m_frameCount;reqbuf.memory = V4L2_MEMORY_MMAP;if(ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0){qDebug("video申请缓冲区失败\n");return;}// 将帧缓冲映射到进程地址空间struct v4l2_buffer buf;buf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;// 将每一帧对应的缓冲区的起始地址保存在m_userVideoBuf数组中,读取采集数据时,只需直接读取映射区即可for(buf.index=0; buf.index<m_frameCount; buf.index++){ioctl(fd, VIDIOC_QUERYBUF, &buf);m_userVideoBuf[buf.index] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);m_userVideoBufSize[buf.index] = buf.length;if(m_userVideoBuf[buf.index] == MAP_FAILED){qDebug("video mmap failed\n");return;}// 入队操作if(ioctl(fd, VIDIOC_QBUF, &buf) < 0){qDebug("入队失败\n");return;}}// 开始采集enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (ioctl(fd, VIDIOC_STREAMON, &type) < 0){qDebug("video开始采集失败");m_isRun = false;}//持续读取图像数据 使用select监听数据fd_set fds;struct timeval tv;tv.tv_sec  = 2;tv.tv_usec = 0;//图片文件缓存char *fileBuf = new char[3*1024*1024];while(m_isRun){FD_ZERO(&fds);FD_SET(fd, &fds);int ret = select(fd+1, &fds, NULL, NULL, &tv);if(ret < 0){qDebug("select io error\n");break;}// 读取帧struct v4l2_buffer readbuffer;readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;readbuffer.memory = V4L2_MEMORY_MMAP;if(ioctl(fd, VIDIOC_DQBUF, &readbuffer) < 0){qDebug("读取帧失败\n");}//        qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss:zzz");//重点:帧数据处理const uchar *data = (const uchar *)m_userVideoBuf[readbuffer.index];int length = readbuffer.length;//构造并显示QImage image = QImage::fromData(data, length);emit sigUpdateImage(image.copy());// 再次入队if(ioctl(fd, VIDIOC_QBUF, &readbuffer) < 0){qDebug("再次入队失败\n");}}// 停止采集if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0){qDebug("停止采集失败\n");}// 释放映射for(uint i=0; i<m_frameCount; i++){munmap(m_userVideoBuf[i], m_userVideoBufSize[i]);}//关闭文件emit sigUpdateImage(QImage());close(fd);delete[] fileBuf;qDebug() << "VideoCapture stop";
}

相关文章:

Linux基于V4L2的视频捕捉

简介 linux环境使用V4l2实现摄像头捕捉&#xff0c;界面流畅播放并可以保存图片到本地。 代码 void VideoCapture::run() {qDebug() << "VideoCapture start";// 打开设备int fd open("/dev/video0", O_RDWR);if(fd < 0){qDebug("video设…...

ECS搭建2.8版本的redis

要在ECS&#xff08;Elastic Compute Service&#xff09;上手动搭建Redis 2.8版本&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤1&#xff1a;更新系统和安装依赖 首先&#xff0c;登录到你的ECS实例&#xff0c;确保系统是最新的并安装必要的依赖包&#xff1a; s…...

[机器学习]GPT LoRA 大模型微调,生成猫耳娘

往期热门专栏回顾 专栏描述Java项目实战介绍Java组件安装、使用&#xff1b;手写框架等Aws服务器实战Aws Linux服务器上操作nginx、git、JDK、VueJava微服务实战Java 微服务实战&#xff0c;Spring Cloud Netflix套件、Spring Cloud Alibaba套件、Seata、gateway、shadingjdbc…...

代码随想录算法训练营Day24|216.组合总和III、17.电话号码的字母组合

组合总和III 216. 组合总和 III - 力扣&#xff08;LeetCode&#xff09; 思路和昨日的组合题类似&#xff0c;但注意对回溯算法中&#xff0c;收获时的条件需要写对&#xff0c;path的长度要为k的同时&#xff0c;path中元素总和要为n。 class Solution { public:vector<…...

【Python系列】Python 中方法定义与方法调用详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Java 基础面试300题 (201-230)

Java 基础面试300题 &#xff08;201-230&#xff09; 201.下面代码片段的输出是什么&#xff1f; Predicate<Integer> numberChecker (num)–> num > 20; int input 10; System.out.println(input” greater than 20–”numberChecker.test(input)); //Line 1…...

Go-知识并发控制Context

Go-知识并发控制Context 1. 介绍2. 实现原理2.1 接口定义2.2 Deadline()2.3 Done()2.4 Err()2.5 Value() 3. 空 context4. cancelCtx4.1 Done()4.2 Err()4.3 cancel()4.4 WithCancel4.5 例子4.6 总结 5. timerCtx5.1 Deadline5.2 cancel5.3 WithDeadline5.4 WithTimeout5.5 例子…...

Vue + Nodejs + socket.io 实现聊天

Vue 代码 // 安装 socket.io-clientnpm i socket.io-clientimport io from socket.io-client;mounted () {// * location.origin 表示你的 socket 服务地址// * /XXXX/socket.io 表示 你的 socket 在服务器配置的 访问地址let socket io(location.origin, {path: "/XX…...

cocos creator 3.x实现手机虚拟操作杆

简介 在许多移动游戏中&#xff0c;虚拟操纵杆是一个重要的用户界面元素&#xff0c;用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆&#xff0c;提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆&#xff0c;如固定和跟随&#xff0c;以及如…...

【数据分享】中国电力年鉴(2004-2022)

大家好&#xff01;今天我要向大家介绍一份重要的中国电力统计数据资源——《中国电力年鉴》。这份年鉴涵盖了从2004年到2022年中国电力统计全面数据&#xff0c;并提供限时免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 自1993年首次出版以来&#xf…...

两个数组的交集Ⅱ-力扣

想到的解法是使用两个map来进行记录&#xff0c;mp1用来统计num1中每个元素出现的次数。当nums2的元素能够在mp1中查找到时&#xff0c;将这个元素添加到mp2&#xff0c;按照这个规则统计得到nums2和nums1重复的元素&#xff0c;mp2中的value记录了nums2中这个元素出现的次数最…...

【TCP协议中104解析】wireshark抓取流量包工具,群殴协议解析基础

Tcp ,104 ,wireshark工具进行解析 IEC104 是用于监控和诊断工业控制网络的一种标准&#xff0c;而 Wireshark则是一款常用的网络协议分析工具&#xff0c;可以用干解析TEC104 报文。本文将介绍如何使用 Wireshark解析 IEC104报文&#xff0c;以及解析过 程中的注意事项。 一、安…...

[个人笔记] 记录docker-compose使用和Harbor的部署过程

容器技术 第三章 记录docker-compose使用和Harbor的部署过程 容器技术记录docker-compose使用和Harbor的部署过程Harborhttps方式部署&#xff1a;测试环境部署使用自签名SSL证书https方式部署&#xff1a;正式环境部署使用企业颁发的SSL证书给Docker守护进程添加Harbor的SSL证…...

详细介绍运算符重载函数,清晰明了

祝各位六一快乐~ 前言 1.为什么要进行运算符重载&#xff1f; C中预定义的运算符的操作对象只能是基本数据类型。但实际上&#xff0c;对于许多用户自定义类型&#xff08;例如类&#xff09;&#xff0c;也需要类似的运算操作。这时就必须在C中重新定义这些运算符&#xff…...

国内外知名的低代码开发平台下载地址

以下是国内外几款低代码开发平台的列表&#xff0c;包含了下载地址、适应操作系统、是否可以独立部署、优点、缺点以及是否包含流程引擎的信息。 平台名称 下载地址 适应操作系统 是否可以独立部署 优点 缺点 是否包含流程引擎 国内平台 阿里云宜搭 阿里云官网 跨平台…...

【Pr学习】01新建项目起步

【Pr学习】01新建项目起步 1、新建项目2.序列设置2.1新建序列2.2序列参数讲解2.3自定义设置 3.PR窗口认识3.1 项目窗口3.2 源窗口2.4 保存面板 4.剪辑导入4.1 素材导入4.2 视图切换4.3 时间轴4.4轨道工具4.5 节目窗口素材导入 5.基础操作5.1 取消视频音频链接5.2 单独渲染&…...

【Redis延迟队列】redis中的阻塞队列和延迟队列

阻塞队列&#xff08;RBlockingQueue&#xff09; 作用和特点&#xff1a; 实时性&#xff1a;阻塞队列用于实时处理消息。生产者将消息放入队列&#xff0c;消费者可以立即从队列中取出并处理消息。阻塞特性&#xff1a;如果队列为空&#xff0c;消费者在尝试获取消息时会被…...

el-tree常用操作

一、定义 <el-treeclass"myTreeClass":data"dirTreeData":props"dirTreeProps":filter-node-method"filterDirTree":expand-on-click-node"false"node-key"id"node-click"dirTreeNodeClick":allow-…...

SQL 语言:存储过程和触发器

文章目录 基本概述创建触发器更改和删除触发器总结 基本概述 存储过程&#xff0c;类似于高阶语言的函数或者方法&#xff0c;包含SQL语句序列&#xff0c;是可复用的语句&#xff0c;保存在数据库中&#xff0c;在服务器中执行。特点是复用&#xff0c;提高了效率&#xff0c…...

Ubuntu Linux 24.04 使用certbot生成ssl证书

设置域名 1. 将需要生成SSL证书的域名解析到IP地址 idealand.xyz <> 64.176.82.190 检查防火墙的设置 1. 首先查看防火墙的状态&#xff1a; # ufw status 2. 如果防火墙开启了&#xff0c;要开放80和443端口用于certbot验证 # ufw allow 80 # ufw allow 443 生…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...