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

视频输入设备-V4L2的开发流程简述

一、摄像头的工作原理与应用

 基本概念

V4L2的全称是Video For Linux Two,其实指的是V4L的升级版,是linux系统关于视频设备的内核驱动,同时V4L2也包含Linux系统下关于视频以及音频采集的接口,只需要配合对应的视频采集设备就可以实现对视频以及音频进行采集。 

Linux下包含V4L2的接口资源(宏定义、枚举、请求码等),这些资源被包含在一个头文件中,头文件名字叫做videodev2.h,头文件路径:/usr/include/linux/videodev2.h,用户需要在程序中使用该头文件 #include <linux/videodev2.h>

在这个头文件的末尾部分有很多关于视频采集的请求码,这些请求码通过一个系统调用中的ioctl()函数,通过发送不同请求码给内核驱动,内核驱动会返回对应的信息。

 

ioctl函数使用说明

头文件:#include <sys/ioctl.h>

函数原型:int ioctl(int fd, unsigned long request, ...);   变参函数

函数参数

参数一:fd  需要操作的文件的描述符   open函数的返回值

参数二:request    传递给设备驱动的对应请求

.....

返回值   成功  返回0   失败  返回-1

注意:ioctl是专门作为设备输入输出操作的系统调用,需要传入对应设备的命令码,不同的设备会定义不同的命令码

开发流程

Video for Linux Two是一套针对不同类型视频设备及相关数据的关联驱动规范。设备的类型决定了通过read()和write()传递的数据类型,以及驱动支持的ioctl命令集。已经定义或计划定义几种设备类型如下图:

由于需要使用摄像头捕捉画面,所以需要调用open函数打开摄像头,插入摄像头之后Linux系统提供的摄像头的设备节点是 /dev/video7。(每个人插入摄像头之后提供的设备节点可能不一样,需要注意)

以下代码都是对V4L2原码的解读以及注释:

  (1) 使用视频采集设备之前需要提前打开设备,利用Linux系统的open函数打开设备文件!

 

(2)根据用户需求设置摄像头采集画面的格式,利用v4l2提供的struct v4l2_format结构体!

现在市面的摄像头的采集画面的格式有多种,如果购买的摄像头价格比较便宜,则一般采集的画面的格式都是YUV4:2:2格式,YUYV(YUV4:2:2)格式指的是每4个字节代表两个像素点,所以YUYV格式的图像一个像素点大小为2个字节,并且Y和UV交替存储。

YUV是一种常用的颜色编码格式,主要用在电视系统和模拟视频领域,也是使用3个分量表示颜色,Y指的是亮度,U和V指的是色度,用来描述影像色彩和饱和度。YUV格式大体上分为两大类:平面格式(YUV分量分开存)和打包格式(YUV分量合在一起按照一定的编码格式存)。

主流的采样方式有三种:YUV4:2:2 、YUV4:2:0、YUV4:4:4 

YUV4:2:0 : 对于每4个像素(2*2的块),共享一组U和Y值,每个像素都有独立的Y值

YUV4:4:4  :对于每个像素,Y、U、V都有独立的采样值

YUV4:2:2  :对于每2个水平相邻的像素,共享一组U和V值,而每个独立的像素都有一个Y值

如果想要把YUV格式的图像显示到LCD屏幕上就要做相应的转换,如下图。

在摄像头采集画面之前,需要设置摄像头采集画面的参数,比如帧宽度、帧高度、图像格式等,要通过一个结构体struct v4l2_format进行设置,注意,当前使用的摄像头只支持YUYV格式的采集(这里我的摄像头只支持YUYV格式的采集)。

V4L2设备以流的形式处理多媒体数据,流由包含格式化数据的缓冲区组成。一个设备可以有多个同时的流。大多数流是视频图像,但也可能存在其他类型。v4l2_format结构包含一个联合体,用于处理不同的格式结构,以便以后可以添加更多。应用程序必须始终设置类型字段,用于指示正在使用的格式类型以及它适用于哪个流。

(3)向v4l2驱动申请帧缓存区,利用帧缓存循环存储摄像头捕获到的图像,一般申请4个!

需要定义struct v4l2_requestbuffers结构体变量,在这个结构体中可以设置需要申请的帧缓存的数量,一般申请4个帧缓存,这样每个帧缓存都会存储一帧图像,循环调用就可以提高视频采集的效率。

内存映射方式:有以下三种

直接读取:利用read、write,直接对内存数据不断拷贝,占用大量内存空间(不推荐)

内存映射:利用mmap函数把驱动的帧缓存映射到应用程序的内存中,效率高(推荐)

用户指针:内存片段由应用程序自己分配,需要设置V4L2_MEMORY_USERPTR(不推荐)

(4)获取申请成功的每个帧缓存的参数信息,并且为每个帧缓存申请捕获图像大小的堆内存

想要从帧缓存中得到采集到的数据,需要知道从驱动中申请的每个缓存块的信息(缓存块地址、缓存块的大小),所以需要定义struct v4l2_buffer结构体变量存储,并把缓存进行内存映射。

(5)为了让摄像头可以把采集的图像存储在申请的帧缓存中,所以需要把申请的帧缓存入队

(6)缓存区入队之后,用户可以启动图像捕捉,然后摄像头就可以循环的把图像存入缓存区

(7)依次把缓存区出队,然后用户对缓存区存储的图像数据进行处理,但是要实现超时处理

把缓存块按照索引依次出队,然后保存缓存块中的数据后,再把缓存块重新入队,但是需要使用select()函数实现多路复用检测是否采集到数据,实现超时处理。

select函数一般用于网络编程,该函数可以帮用户监听多个文件描述符的状态,如果监听的多个文件中的某个文件的描述符发生的改变(读写或异常),select函数可以及时通知进程。

(8)把出队的缓存区中的YUYV格式的颜色分量转换为RGB格式的颜色分量并显示在LCD上

本次使用的摄像头只支持采集YUYV格式的图像,而在LCD屏上显示的是RGB数据,所以需要把采集到的图像转换成RGB。RGB对于大家来说并不陌生,看到的光就是由RGB三种颜色按一定比例混合得到,是使用红、绿、蓝三原色的亮度来表示颜色,三种颜色互相叠加实现混色,所以适用于显示屏等器件。在LCD屏中每个像素点的颜色都是由RGB组成的,LCD屏中一个像素点4个字节,RGB分别占用一个字节,每个字节的取值范围都是0~255,不过又加入了透明度,所以LCD屏中一个像素点就是由ARGB构成的。

下面的代码不是V4L2的原码,是我写的将一个YUV格式的像素点转换为RGB格式的函数

===============================================

如果可以实现一个像素点的格式转换,则只需要根据摄像头采集画面的宽和高把所有的像素点依次进行转换。

如果一帧YUV格式的图像已经转换为一帧RGB格式的图像,则只需要把RGB格式图像的像素点拷贝到LCD屏的像素点中即可。

提示:如果需要项目原码可以在我的项目专栏中找到

相关文章:

视频输入设备-V4L2的开发流程简述

一、摄像头的工作原理与应用 基本概念 V4L2的全称是Video For Linux Two&#xff0c;其实指的是V4L的升级版&#xff0c;是linux系统关于视频设备的内核驱动&#xff0c;同时V4L2也包含Linux系统下关于视频以及音频采集的接口&#xff0c;只需要配合对应的视频采集设备就可以实…...

【Manus资料合集】激活码内测渠道+《Manus Al:Agent应用的ChatGPT时刻》(附资源)

DeepSeek 之后&#xff0c;又一个AI沸腾&#xff0c;冲击的不仅仅是通用大模型。 ——全球首款通用AI Agent的破圈启示录 2025年3月6日凌晨&#xff0c;全球AI圈被一款名为Manus的产品彻底点燃。由Monica团队&#xff08;隶属中国夜莺科技&#xff09;推出的“全球首款通用AI…...

Mybatis集合嵌套查询,三级嵌套

三个表&#xff1a;房间 玩家 玩家信息 知识点&#xff1a;Mybatis中级联有关联&#xff08;association&#xff09;、集合&#xff08;collection&#xff09;、鉴别器&#xff08;discriminator&#xff09;三种。其中&#xff0c;association对应一对一关系、collectio…...

thinkphp5.1 在fetch模版就超时

场景 当被渲染模版不存在&#xff0c;请求不响应任何内容&#xff0c;过一会就timeout 排查过程 使用xdebug,追踪代码&#xff0c;发现走到D:\temporary_files\m40285_mini\40285_mini\thinkphp\library\think\exception\Handle.php&#xff0c;进入死循环&#xff0c;一直…...

Dockerfile 深入浅出:从基础到进阶全解析

Dockerfile 深入浅出&#xff1a;从基础到进阶全解析 各位同学&#xff0c;大家好&#xff01;欢迎来到今天的 Dockerfile 课程。Docker 技术在当今的软件开发和部署领域可以说是非常热门&#xff0c;而 Dockerfile 作为构建 Docker 镜像的关键文件&#xff0c;掌握它对于我们…...

CAD2025电脑置要求

Windows 系统 操作系统&#xff1a;64 位 Microsoft Windows 11 和 Windows 10 version 1809 或更高版本。 处理器 基本要求&#xff1a;2.5-2.9GHz 处理器&#xff0c;不支持 ARM 处理器。 推荐配置&#xff1a;3GHz 以上处理器&#xff08;基础&#xff09;&#xff0c;4GHz …...

android App主题颜色动态更换

如何在Android开发中更换主题颜色&#xff0c;现在他们又问了关于动态更换应用主题颜色的问题。看来他们可能在实现过程中遇到了困难&#xff0c;或者需要更详细的动态切换指导。首先&#xff0c;我需要回顾之前的回答&#xff0c;看看是否已经覆盖了动态切换的部分&#xff0c…...

微服务,服务治理nacos,负载均衡LOadBalancer,OpenFeign

1.微服务 简单来说&#xff0c;微服务架构风格[1]是一种将一个单一应用程序开发为一组小型服务的方法&#xff0c;每个服务运行在 自己的进程中&#xff0c;服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并 且可通过全自动部署机制独立部署。这…...

浅论数据库聚合:合理使用LambdaQueryWrapper和XML

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算&#xff08;关键优化&#xff09;二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点&#xff1a;使用 XM…...

FastGPT 引申:混合检索完整实例

文章目录 FastGPT 引申&#xff1a;混合检索完整实例1. 各检索方式的初始结果2. RRF合并过程3. 合并后的结果4. Rerank重排序后5. 最终RRF合并6. 内容总结 FastGPT 引申&#xff1a;混合检索完整实例 下边通过一个简单的例子说明不同检索方式的分值变化过程&#xff0c;假设我…...

Socket.IO聊天室

项目代码 https://github.com/R-K05/Socket.IO- 创建项目 服务端项目和客户端项目 安装Socket依赖 服务端 npm i socket.io 客户端 npm i socket.io-client 客户端添加聊天页面 源码 服务端 app.js const express require("express") const app express()co…...

MySQL表中数据基本操作

1.表中数据的插入&#xff1a; 1.insert insert [into] table_name [(column [,column]...)] values (value_list) [,(value_list)] ... 创建一张学生表&#xff1a; 1.1单行指定列插入&#xff1a; insert into student (name,qq) values (‘张三’,’1234455’); values左…...

可狱可囚的爬虫系列课程 16:爬虫重试机制

一、retrying模块简介 在爬虫中&#xff0c;因为我们是在线爬取内容&#xff0c;所以可能会因为网络、服务器等原因导致报错&#xff0c;那么这类错误出现以后&#xff0c;我们想要做的肯定是在报错处进行重试操作&#xff0c;Python提供了一个很好的模块&#xff0c;能够直接帮…...

第十五届蓝桥杯----B组cpp----真题解析(小白版本)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 必看前言&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;一、试题A&#xff1a;握手问题1.题意分析2.代码解答 二、试题B&#xff1a;小球反弹1.题意…...

软考架构师笔记-数据库系统

1.7 数据库系统 三级模式-两级映射 三级模式 外模式&#xff1a;用户视图概念模式&#xff1a;只涉及描述内模式&#xff1a;存储方式的描述 两级映射 外模式-概念模式映射概念模式-内模式映射 数据库的设计 步骤 需求分析 输出为需求分析、数据流图(Data FLow Diagram-DF…...

Spring AI 1.0.0-M6 快速开始(一)

Spring AI 1.0.0-M6 入门一、存储库二、依赖管理完整maven 入门 Spring 是JAVA中我们经常使用的框架之一&#xff0c;Spring AI不断的发展迭代目前已经到M6版本据说上半年会出一个稳定版本。 本节提供了如何开始使用Spring AI的M6。 一、存储库 1.0 M6 -添加Spring存储库 需…...

go 分布式redis锁的实现方式

go 语言以高并发著称。那么在实际的项目中 经常会用到锁的情况。比如说秒杀抢购等等场景。下面主要介绍 redis 布式锁实现的两种高并发抢购场景。其实 高并发 和 分布式锁 是一个互斥的两个状态&#xff1a; 方式一 setNX&#xff1a; 使用 redis自带的API setNX 来实现。能解决…...

Unity中Stack<T>用法以及删除Stack<GameObject>的方法

Unity中Stack用法以及删除Stack的方法 介绍Stack<T>的APIStack<T> 常用方法创建和初始化 Stack<T>Push 和 Pop 操作Stack<T>遍历清空栈检查栈是否包含某个元素 栈的典型应用场景撤销操作深度优先搜索&#xff08;DFS&#xff09;注意事项 总结 介绍 因…...

Vue进阶之Vue3源码解析(二)

Vue3源码解析 运行runtime-coresrc/createApp.tssrc/vnode.ts.tssrc/renderer.ts runtime-domsrc/index.ts 总结 运行 runtime-core src/createApp.ts vue的创建入口 import { createVNode } from "./vnode";export function createAppAPI(render) {return funct…...

linux的文件系统及文件类型

目录 一、Linux支持的文件系统 二、linux的文件类型 2.1、普通文件 2.2、目录文件 2.3、链接文件 2.4、字符设备文件: 2.5、块设备文件 2.6、套接字文件 2.7、管道文件 三、linux的文件属性 3.1、关于权限部分 四、Linux的文件结构 五、用户主目录 5.1、工作目录…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...