-
703N Openwrt固件 UVC免驱摄像头WIFI智能小车机器人专用
2021-02-03 10:01:41703N Openwrt固件 UVC免驱摄像头WIFI智能小车机器人专用 该固件已经集成了ser2net,mjpg-streamer,UVC摄像头驱动,刷上后不需要任何设置即可直接控制WIFI智能小车机器人。 WIFI机器人网·机器人创意工作室出品 ... -
stm32F4系列实现USB UVC免驱摄像头
2018-08-23 17:32:291,用的库是官方的HAL库 2,硬件是原子的F429核心板(底板没有。。),用到的外设有,NANDFLASH、SDRAM、USB、一个按键 3,播放设备用的是windows的ECap软件。 4,NANDFLASH里面预存了原子的测试文件夹,里面有做好... -
USB摄像头,UVC免驱于嵌入式中应用
2020-11-17 20:51:18USB摄像头,UVC免驱于嵌入式中应用。 一、make menuconfig。 二、修改内核配置参数。 1、进入Device Drivers。 2、进入Multimedia support。 3、修改如下。 4、进入Video capture adapters。 5、进入...USB摄像头,UVC免驱于嵌入式中应用。
一、make menuconfig。
二、修改内核配置参数。1、进入Device Drivers。
2、进入Multimedia support。
3、修改如下。
4、进入Video capture adapters。
5、进入V4L USB devices。
6、配置如下。
7、退出并保存,重新编译内核。
三、查询。
于/dev下查看,出现video*,说明摄像头识别成功。
-
树莓派教程 - 2.1 树莓派USB摄像头 树莓派罗技免驱摄像头 fswebcam常用参数
2020-07-21 20:40:07一般的USB摄像头都是UVC免驱的,而且可以方便的插拔和安装,平时最为常用。 一、硬件设备 usb摄像头使用的 罗技c310。(只要是UVC免驱就可以) 二、连接并测试摄像头 lsusb 并将usb摄像头插上 插入usb...树莓派外接摄像头,最常用的有两种:CSI摄像头、USB摄像头。当然网络摄像头也是可以的。
一般的USB摄像头都是UVC免驱的,而且可以方便的插拔和安装,平时最为常用。
一、硬件设备
usb摄像头使用的 罗技c310。(只要是UVC免驱就可以)
二、连接并测试摄像头
(1)使用命令检测usb设备:lsusb
插入usb摄像头后,会显示设备ID和信息,像我的:Bus 001 Device 008: ID 046d:081b Logitech, Inc. Webcam C310
(2)之后使用命令,查看设备文件名称。
ls -l /dev/video*
usb摄像头插入后增加了 video0 和video1 这两个设备,我测试操作这两个都可以用,都是同一个设备。至于为什么跟别人不一样是两个,不得而知。
之后安装摄像头软件:fswebcam
sudo apt-get install fswebcam
安装完成后,使用指令抓拍一张照片。
fswebcam /dev/video0 --no-banner -r 640x480 ~/image01.jpg
三、常用参数
fswebcam /dev/video0 --no-banner -r 640x480 ~/image01.jpg 中的参数功能:
/dev/video0:指定操作设备,像我插入usb摄像头后增加了两个设备,实测 video0 和video1 都可以用,都是同一个摄像头。
--no-banner:图片上隐藏横幅。
-r 640x480:设置分辨率 640x480。
~/image01.jpg:存储路径,当前用户目录下,保存为 image01.jpg。
fswebcam /dev/video0 -r 640x480 ~/image01.jpg
在图片上有横幅,上面有时间戳信息。
四、fswebcam详细参数
--help显示此帮助页面并退出。
-c,--config <文件名>从文件加载配置。
-q,--quiet隐藏除错误以外的所有消息。
-v,--verbose在捕获时显示其他消息
--version显示版本并退出。
-l,--loop <seconds>在循环模式下运行。
-b,--background在后台运行。
-o,--output <文件名>将日志输出到文件。
-d,--device <名称>设置要使用的源。
-i,--input <数字/名称>选择要使用的输入。
-t,--tuner <number>选择要使用的调谐器。
-f,--frequency <number>选择使用的频率。
-p,--palette <名称>选择要使用的调色板格式。
-D,--delay <数字>设置预捕获延迟时间。 (秒)
-r,--resolution <size>设置捕获分辨率。
--fps <framerate>设置捕获帧速率。
-F,--frames <number>设置要捕获的帧数。
-S,--skip <number>设置要跳过的帧数。
--dumpframe <文件名>将原始帧转储到文件。
-s,--set <名称> = <值>设置控制值。
--revert恢复原始捕获的图像。
--flip <direction>翻转图像。 (h,v)
--crop <大小> [,<偏移量>]裁剪图像的一部分。
--scale <size>缩放图像。
--rotate <角度>以直角旋转图像。
--deinterlace减少交错伪像。
--invert反转图像颜色。
--greyscale删除图像的颜色。
--swapchannels <c1c2>交换通道c1和c2。
--no-banner隐藏横幅。
--top-banner将横幅放在顶部。
--bottom-banner将横幅放在底部。 (默认)
--banner-colour <colour>设置横幅颜色。 (#AARRGGBB)
--line-colour <colour>设置横幅线的颜色。
--text-colour <colour>设置文本颜色。
--font <[名称] [:大小]>设置字体和/或大小。
--no-shadow禁用文本阴影。
--shadow启用文本阴影。
--title <文本>设置主标题。 (左上方)
--no-title清除主标题。
--subtitle <文本>设置字幕。 (左下方)
--no-subtitle清除字幕。
--timestamp <格式>设置时间戳格式。 (右上)
--no-timestamp清除时间戳记。
--gmt使用GMT代替本地时区。
--info <文本>设置信息文本。 (右下)
--no-info清除信息文本。
--underlay <PNG图像>设置参考图像。
--no-underlay清除参考底图。
--overlay <PNG图像>设置覆盖图像。
--no-overlay清除覆盖。
--jpeg <factor>输出JPEG图像。 (-1,0-95)
--png <factor>输出PNG图像。 (-1,0-10)
--save <文件名>将图像保存到文件。
--exec <命令>执行命令并等待其完成。 -
在Linux系统如何识别和打开摄像头(UVC免驱)
2021-02-02 19:50:29至于从哪个版本开始内核支持UVC,官方的话是“Linux 2.6.26 and newer includes the Linux UVC driver natively.” 1、查看摄像头ID: [root@151 dev]# lsusb Bus 002 Device 013: ID 0ac8:3313 Z-Star ...我感觉是不是我的UAV驱动出问题了,所以导致摄像头都不能识别到了,可能是之前apt upgrade更新导致的?
是的,我插入USB摄像头用lsusb能识别到,感觉可能是UVC出了问题
http://xiaoyatec.com/2018/12/02/ubuntu-16-04-%E5%AE%89%E8%A3%85-uvcvideo%E9%A9%B1%E5%8A%A8/
默认情况下,ubuntu16.04系统是自带相关驱动的,但某次意外情况,在玩深度摄像头时,不小心把uvcvideo驱动删除了,导致笔记本摄像头无法识别,插入USB网络摄像头时也无法识别:也就是用命令“ls /dev/video*”命令没有任何摄像头信息; 但使用命令“lsusb”命令,能查找到相关摄像头设备信息的。这就是说摄像头设备缺少驱动。一般市面上的USB的网络摄像头使用UVC都是能够驱动的,这个相当与linux下的万能摄像头驱动。
在Linux系统如何识别和打开摄像头
yangzhi113 2013-05-26 14:59:38 11826 收藏 5
今晚很高兴,捣鼓了几天,郁闷了几天的事,今天解决了一些了。起码我能在linux下看到摄像头的图像了。
提起USB摄像在linux下的使用,无论是百度还是Google,出现的多数是法国人写的一个通用驱动程序,即spca5xx,我也是找了很久才找到,——因为在网上看到的那个网站已经不能登陆了,就是说不再维护了(这个后来再作说明),所以找了很久。可惜不能用。因为我make都不通过,出现的错误如下:
make -C /lib/modules/`uname -r`/build SUBDIRS=/usr/local/gspcav1-20071224 CC=cc modules
make[1]: Entering directory `/usr/src/linux-2.6.30.2'
CC [M] /usr/local/gspcav1-20071224/gspca_core.o
/usr/local/gspcav1-20071224/gspca_core.c:54:27: error: asm/semaphore.h: No such file or directory
In file included from /usr/local/gspcav1-20071224/gspca_core.c:845:
/usr/local/gspcav1-20071224/utils/spcausb.h: In function ‘spca5xxRegRead’:
/usr/local/gspcav1-20071224/utils/spcausb.h:95: error: implicit declaration of function ‘info’
/usr/local/gspcav1-20071224/utils/spcausb.h: In function ‘spca_set_interface’:
/usr/local/gspcav1-20071224/utils/spcausb.h:278: error: implicit declaration of function ‘warn’
In file included from /usr/local/gspcav1-20071224/gspca_core.c:853:
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h: In function ‘sp5xxfw2_init’:
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:122: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:136: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:141: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:148: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:176: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h: In function ‘sp5xxfw2_start’:
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:214: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/Sunplus-jpeg/sp5xxfw2.h:230: error: called object ‘info’ is not a function
/usr/local/gspcav1-20071224/gspca_core.c: In function ‘spca5xx_ioctl’:
/usr/local/gspcav1-20071224/gspca_core.c:2463: error: implicit declaration of function ‘video_usercopy’
/usr/local/gspcav1-20071224/gspca_core.c: At top level:
/usr/local/gspcav1-20071224/gspca_core.c:2609: error: unknown field ‘owner’ specified in initializer
/usr/local/gspcav1-20071224/gspca_core.c:2609: warning: initialization from incompatible pointer type
/usr/local/gspcav1-20071224/gspca_core.c:2611: error: unknown field ‘type’ specified in initializer
/usr/local/gspcav1-20071224/gspca_core.c:2615: warning: initialization from incompatible pointer type
/usr/local/gspcav1-20071224/gspca_core.c: In function ‘spca50x_create_sysfs’:
/usr/local/gspcav1-20071224/gspca_core.c:2769: error: implicit declaration of function ‘video_device_create_file’
/usr/local/gspcav1-20071224/gspca_core.c:2780: error: implicit declaration of function ‘video_device_remove_file’
/usr/local/gspcav1-20071224/gspca_core.c: In function ‘spca5xx_probe’:
/usr/local/gspcav1-20071224/gspca_core.c:4301: error: incompatible types in assignment
make[2]: *** [/usr/local/gspcav1-20071224/gspca_core.o] Error 1
make[1]: *** [_module_/usr/local/gspcav1-20071224] Error 2
make[1]: Leaving directory `/usr/src/linux-2.6.30.2'
make: *** [default] Error 2
以我现在的能力,我不能解决,我google过,但得不到好的解决方法。
更重要的是,现在想找一个几年前驱动支持的摄像头很难啊!现在都流行免驱了——根据OS相关理论,这是不成功的,设备没有驱动哪能访问?他们说的是用户免去安装驱动程序这一步骤,——是这个“免驱”。我买的摄像头不在spca5xx支持范围之中。我好容易找到一个,是小郭用的,摄像头ID刚好是上述驱动所支持的。当时很兴奋,心想,万事俱备,只差编译、测试了。可惜,以失败告终。错误如上所述。
我试的几个版本为spca5xx-20060501和gspcav1-20071224,都不行。
在网上找了那么多文章看,但一个也行不通。我不知大家的感受是什么,反正我很郁闷,很无奈。
后来,在插入我买的摄像头时,使用了lsusb,将ID那一行复制到google中,一不小心,发现了一个好网站:http://linux-uvc.berlios.de/。 上面竟然有我摄像头的ID号!!继续研究,发现有UVC这个东东,我在配置内核时也碰到过,但没有注意,没想到如此有用!后来在一个网站中找到有关使用 UVC驱动摄像头的文章,地址忘了,我也不知是怎么搜索到的。此外还下载一个观看图像的小软件。结果成了!可以显示图像了!
下面写一下过程:
如果你能在http://linux-uvc.berlios.de/找到你的摄像头的ID,即UVC支持的,那么就可以在linux下使用了。至于从哪个版本开始内核支持UVC,官方的话是“Linux 2.6.26 and newer includes the Linux UVC driver natively.”
1、查看摄像头ID:
[root@151 dev]# lsusb
Bus 002 Device 013: ID 0ac8:3313 Z-Star Microelectronics Corp.
0xc8:3313在UVC中支持了。
2、插入摄像头后,就可以在/dev/下查看是否有video设备文件:
[root@151 dev]# ls | grep video
video
video0
其中,video是video0的连接。如果没有再现,可能UVC没有配置到内核中,重新配置就可以了(大致在Device DriversàMultimedia devicesàVideo capture adaptersàV4L USB devices下面)。如果内核配置了,还是不出现,可以使用modprobe uvcvideo来加载该模块。
3、先看看摄像头的相关信息:
lshal | grep Cam
出现:
info.product = 'Vega USB 2.0 Camera.' (string)
usb_device.product = 'Vega USB 2.0 Camera.' (string)
usb.interface.description = 'Vega USB 2.0 Camera.' (string)
info.product = 'Vega USB 2.0 Camera.' (string)
input.product = 'Vega USB 2.0 Camera.' (string)
info.product = 'Vega USB 2.0 Camera.' (string)
对USB有研究的,就很熟悉这些字段。
再看一下系统能不能识别出摄像头:
[root@151 log]# dmesg | grep Cam
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input6
usb 2-7: Product: Vega USB 2.0 Camera.
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input7
usb 2-7: Product: Vega USB 2.0 Camera.
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
input: Vega USB 2.0 Camera. as /class/input/input8
usb 2-7: Product: Vega USB 2.0 Camera.
[root@151 ~]# dmesg | grep video
pci 0000:05:00.0: Boot video device
Linux video capture interface: v2.00
usbcore: registered new interface driver uvcvideo
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
uvcvideo 2-7:1.0: usb_probe_interface
uvcvideo 2-7:1.0: usb_probe_interface - got id
uvcvideo: Found UVC 1.00 device Vega USB 2.0 Camera. (0ac8:3313)
哈哈,识别出来了!可以测试了。
4、我使用的软件是luvcview,这个软件google就可以找到的。安装过程很简单,——make,make install就可以了。
下面这个过程是测试过程,从看到图像到结束的过程:
[root@151 dev]# luvcview -d /dev/video0 -f yuv -s 640x480
uvcview verion 0.1.4
size width: 640 height: 480
Video driver: x11
A window manager is available
video /dev/video0
Stop asked
Clean Up done Quit
[root@151 dev]#
解释命令:
-d 设备名,这里/dev/video或/dev/video0都可以,因为它们都是一个文件
-f 格式,有yuv和jpg两种,后者测试不行
-s 大小,能支持的最大尺度可能由luvcview决定,也可能由摄像头决定,(应该是后者,暂没有研究)
更具体的参见luvcview目录下的README文件。
另外,如果没有插入摄像头,即使modprobe uvcvideo也不会出现/dev/video设备文件;插入摄像头,即使没有modprobe uvcvideo,也会出现/dev/video设备文件,当然这是我的测试,没有代表性,也没有理论根据的。
注:
1、UVC:USB Video Class
2、gspcav不是不再维护,而是在某一版本开始已经纳入内核了,至于哪个版本,就不太清楚了。特此说明。
3、这次毕业设计所不再编译gspca到内核中了。不支持它,直接使用UVC。
原文请参考:http://weijb0606.blog.163.com/blog/static/131286274201063145356429/
-
Linux平台基于v4l2开发免驱摄像头->输出为Opencv Mat
2019-12-10 18:37:10V4L2 简介 作者:onesixthree ...来源:简书 Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版。V4L2是linux操作系统下用于采集图片、视频和音频数据的API接口,配合适当的视频采集设备和相应...可以对uvc免驱...对使用uvc免驱的摄像头的读取视频流
- 首先对于Linux系统上的摄像头读取,应该首选基于v4l2的API去进行开发,避免使用Opencv的VideoCapture,因为v4l2提供的API更全面,方便我们获取摄像头的状态。
- 面对一个 video 设备 节点可能对应多个视频源,获取对应的视频源。
- 在v4l2的基础上采集视频图像,并封装成opencv的cv::Mat 方便后续算法开发使用。
- 在以上的需求上,我开发封装了一套C++的接口,以实现对应的功能。
下面是我开源的实现该功能的代码:
https://github.com/xxradon/libv4l2_opencv_mat
下面介绍来源于
链接:https://www.jianshu.com/p/fd5730e939e7
https://www.cnblogs.com/edver/p/7749628.html
感谢分享
V4L2
简介
Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版。V4L2是linux操作系统下用于采集图片、视频和音频数据的API接口,配合适当的视频采集设备和相应的驱动程序,可以实现图片、视频、音频等的采集。可以对uvc免驱摄像头直接操作。在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的应用。
V4L2视频采集原理
V4L2支持内存映射方式(mmap)和直接读取方式(read)来采集数据,前者一般用于连续视频数据的采集,后者常用于静态图片数据的采集。我们一般使用内存映射方式来进行视频采集。
V4L2采集视频数据的五个步骤:
首先,打开视频设备文件,进行视频采集的参数初始化,通过V4L2接口设置视频图像的采集窗口、采集的点阵大小和格式;
其次,申请若干视频采集的帧缓冲区,并将这些帧缓冲区从内核空间映射到用户空间,便于应用程序读取/处理视频数据;
第三,将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;
第四,驱动开始视频数据的采集,应用程序从视频采集输出队列取出帧缓冲区,处理完后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据;
第五,停止视频采集。
打开设备-> 检查和设置设备属性-> 设置帧格式-> 设置一种输入输出方法(缓冲 区管理)-> 循环获取数据-> 关闭设备。
具体实现流程图如下:
其实其他的都比较简单,就是通过ioctl这个接口去设置一些参数。最主要linux opencv imshow 编译的就是buf管理。他有一个或者多个输入队列和输出队列。
启动视频采集后,驱动程序开始采集一帧数据,把采集的数据放入视频采集输入队列的第一个帧缓冲区,一帧数据采集完成,也就是第一个帧缓冲区存满一帧数据后,驱动程序将该帧缓冲区移至视频采集输出队列,等待应用程序从输出队列取出。驱动程序接下来采集下一帧数据,放入第二个帧缓冲区,同样帧缓冲区存满下一帧数据后,被放入视频采集输出队列。
应用程序从视频采集输出队列中取出含有视频数据的帧缓冲区,处理帧缓冲区中的视频数据,如存储或压缩。
最后,应用程序将处理完数据的帧缓冲区重新放入视频采集输入队列,这样可以循环采集,如图所示。下面主要讲解一下v4l2的主要使用的操作,就是open, close, ioctl
V4L2(Video For Linux Two) 是内核提供给应用程序访问音、视频驱动的统一接口。V4L2 的相关定义包含在头文件<linux/videodev2.h> 中.
1.设备打开和关闭
//打开 #include <fcntl.h> int open(const char *device_name, int flags);
//关闭 #include <unistd.h> int close(int fd);
实验使用UVC摄像头,插入后自动生成设备“/dev/vedio0”,打开关闭实例如下
int fd = open("/dev/video0",O_RDWR); close(fd);
2. 查询设备属性: VIDIOC_QUERYCAP
函数使用:
int ioctl(int fd, int request, struct v4l2_capability *argp);
v4l2相关结构体定义:
struct v4l2_capability { u8 driver[16]; // 驱动名字 u8 card[32]; // 设备名字 u8 bus_info[32]; // 设备在系统中的位置 u32 version;// 驱动版本号 u32 capabilities;// 设备支持的操作 u32 reserved[4]; // 保留字段 };
capabilities 常用值:
V4L2_CAP_VIDEO_CAPTURE // 是否支持图像获取
例如:显示设备信息
struct v4l2_capability cap; ioctl(fd,VIDIOC_QUERYCAP,&cap); //printf(“Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n”,cap.driver,cap.card,cap.bus_info,cap.capabilities); std::cout << "driver:" << cap.driver << " capabilities:" << std::hex << cap.capabilities << " mandatory:" << mandatoryCapabilities << std::dec; std::cout << "card:" << cap.card << " Bus info: " << cap.bus_info;
3. 设置视频的制式和帧格式
制式包括PAL,NTSC,帧的格式个包括宽度和高度等。
相关函数:
int ioctl(int fd, int request, struct v4l2_fmtdesc *argp); int ioctl(int fd, int request, struct v4l2_format *argp);
相关结构体:
struct v4l2_format { enum v4l2_buf_type type; // 帧类型,应用程序设置 union fmt { struct v4l2_pix_format pix; // 视频设备使用 struct v4l2_window win; struct v4l2_vbi_format vbi;struct v4l2_sliced_vbi_format sliced; u8 raw_data[200]; }; };
v4l2_format 结构体用来设置摄像头的视频制式、帧格式等,在设置这个参数时应先填 好 v4l2_format 的各个域,如 type(传输流类型),fmt.pix.width(宽),
fmt.pix.heigth(高),fmt.pix.field(采样区域,如隔行采样),fmt.pix.pixelformat(采样类型,如 YUV4:2:2),然后通过 VIDIO_S_FMT 操作命令设置视频捕捉格式。
v4l2_cropcap 结构体用来设置摄像头的捕捉能力,在捕捉上视频时应先先设置v4l2_cropcap 的 type 域,再通过 VIDIO_CROPCAP 操作命令获取设备捕捉能力的参数,保存于 v4l2_cropcap 结构体中,包括 bounds(最大捕捉方框的左上角坐标和宽高),defrect(默认捕捉方框的左上角坐标和宽高)等。
3.1 查询并显示所有支持的格式:VIDIOC_ENUM_FMT
int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);
v4l2_fmtdesc结构体定义:struct v4l2_fmtdesc { u32 index;// 要查询的格式序号,应用程序设置 enum v4l2_buf_type type; // 帧类型,应用程序设置 u32 flags;// 是否为压缩格式 u8 description[32]; // 格式名称 u32 pixelformat;// 格式 u32 reserved[4]; // 保留 };
例:显示所有支持的格式
struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; printf("Support format:\n"); while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1) { printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description); fmtdesc.index++; }
5.2 查看或设置当前格式: VIDIOC_G_FMT, VIDIOC_S_FMT
检查是否支持某种格式:VIDIOC_TRY_FMT相关函数:
int ioctl(int fd, int request, struct v4l2_format *argp);
v4l2_format结构体定义
struct v4l2_format { enum v4l2_buf_type type; // 帧类型,应用程序设置 union fmt { struct v4l2_pix_format pix; // 视频设备使用 struct v4l2_window win; struct v4l2_vbi_format vbi;struct v4l2_sliced_vbi_format sliced; u8 raw_data[200]; }; }; struct v4l2_pix_format { u32 width;// 帧宽,单位像素 u32 height;// 帧高,单位像素 u32 pixelformat;// 帧格式 enum v4l2_field field; u32 bytesperline; u32 sizeimage; enum v4l2_colorspace colorspace; u32 priv; };
例:显示当前帧的相关信息
struct v4l2_format fmt; fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; ioctl(fd, VIDIOC_G_FMT, &fmt); printf("Current data format information:\n\twidth:%d\n\theight:%d\n",fmt.fmt.pix.width,fmt.fmt.pix.height); struct v4l2_fmtdesc fmtdesc; fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) { if(fmtdesc.pixelformat & fmt.fmt.pix.pixelformat) { printf("\tformat:%s\n",fmtdesc.description); break; } fmtdesc.index++; }
例:检查是否支持某种帧格式(如RGB32)
struct v4l2_format fmt; fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB32; if(ioctl(fd,VIDIOC_TRY_FMT,&fmt)==-1) if(errno==EINVAL) printf("not support format RGB32!\n");
4. 图像的缩放 VIDIOC_CROPCAP
相关函数:
int ioctl(int fd, int request, struct v4l2_cropcap *argp); int ioctl(int fd, int request, struct v4l2_crop *argp); int ioctl(int fd, int request, const struct v4l2_crop *argp);
相关结构体:
Cropping 和 scaling 主要指的是图像的取景范围及图片的比例缩放的支持。Crop 就 是把得到的数据作一定的裁剪和伸缩,裁剪可以只取样我们可以得到的图像大小的一部分, 剪裁的主要参数是位置、长度、宽度。而 scale 的设置是通过 VIDIOC_G_FMT 和 VIDIOC_S_FMT 来获得和设置当前的 image 的长度,宽度来实现的。看下图
image
我们可以假设 bounds 是 sensor 最大能捕捉到的图像范围,而 defrect 是设备默认 的最大取样范围,这个可以通过 VIDIOC_CROPCAP 的 ioctl 来获得设备的 crap 相关的属 性 v4l2_cropcap,其中的 bounds 就是这个 bounds,其实就是上限。每个设备都有个默 认的取样范围,就是 defrect,就是 default rect 的意思,它比 bounds 要小一些。这 个范围也是通过 VIDIOC_CROPCAP 的 ioctl 来获得的 v4l2_cropcap 结构中的 defrect 来表示的,我们可以通过 VIDIOC_G_CROP 和 VIDIOC_S_CROP 来获取和设置设备当前的 crop 设置。
4.1 设置设备捕捉能力的参数
相关函数:
int ioctl(int fd, int request, struct v4l2_cropcap *argp);
v4l2_cropcap结构体定义:
struct v4l2_cropcap { enum v4l2_buf_type type; // 数据流的类型,应用程序设置 struct v4l2_rect bounds; // 这是 camera 的镜头能捕捉到的窗口大小的局限 struct v4l2_rect defrect; // 定义默认窗口大小,包括起点位置及长,宽的大小,大小以像素为单位 struct v4l2_fract pixelaspect; // 定义了图片的宽高比 };
6.2 设置窗口取景参数 VIDIOC_G_CROP 和 VIDIOC_S_CROP
相关函数:int ioctl(int fd, int request, struct v4l2_crop *argp); int ioctl(int fd, int request, const struct v4l2_crop *argp);
相关结构体:
struct v4l2_crop { enum v4l2_buf_type type;// 应用程序设置 struct v4l2_rect c; }
7.video Inputs and Outputs
VIDIOC_G_INPUT 和 VIDIOC_S_INPUT 用来查询和选则当前的 input,一个 video 设备 节点可能对应多个视频源,比如 saf7113 可以最多支持四路 cvbs 输入,如果上层想在四 个cvbs视频输入间切换,那么就要调用 ioctl(fd, VIDIOC_S_INPUT, &input) 来切换。
VIDIOC_G_INPUT and VIDIOC_G_OUTPUT 返回当前的 video input和output的index.
相关函数:
int ioctl(int fd, int request, struct v4l2_input *argp);
v4l2_input结构体定义:
struct v4l2_input { __u32 index;/* Which input*/ __u8 name[32]; /* Label*/ __u32 type;/* Type of input*/ __u32 audioset;/* Associated audios (bitfield)*/ __u32 tuner;/* Associated tuner*/ v4l2_std_id std; __u32 status; __u32 reserved[4]; };
我们可以通过VIDIOC_ENUMINPUT and VIDIOC_ENUMOUTPUT 分别列举一个input或者 output的信息,我们使用一个v4l2_input结构体来存放查询结果,这个结构体中有一个 index域用来指定你索要查询的是第几个input/ouput,如果你所查询的这个input是当前正 在使用的,那么在v4l2_input还会包含一些当前的状态信息,如果所 查询的input/output 不存在,那么回返回EINVAL错误,所以,我们通过循环查找,直到返回错误来遍历所有的 input/output. VIDIOC_G_INPUT and VIDIOC_G_OUTPUT 返回当前的video input和output 的index.
例: 列举当前输入视频所支持的视频格式
struct v4l2_input input; struct v4l2_standard standard; memset (&input, 0, sizeof (input)); //首先获得当前输入的 index,注意只是 index,要获得具体的信息,就的调用列举操作 if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) { perror (”VIDIOC_G_INPUT”); exit (EXIT_FAILURE); } //调用列举操作,获得 input.index 对应的输入的具体信息 if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) { perror (”VIDIOC_ENUM_INPUT”); exit (EXIT_FAILURE); } printf (”Current input%s supports:\n”, input.name); memset (&standard, 0, sizeof (standard)); standard.index = 0; //列举所有的所支持的 standard,如果 standard.id 与当前 input 的 input.std 有共同的 //bit flag,意味着当前的输入支持这个 standard,这样将所有驱动所支持的 standard 列举一个 //遍,就可以找到该输入所支持的所有 standard 了。 while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) { if (standard.id & input.std) printf (”%s\n”, standard.name); standard.index++; } /* EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception.*/ if (errno != EINVAL || standard.index == 0) { perror (”VIDIOC_ENUMSTD”); exit (EXIT_FAILURE); }
6. Video standards
相关函数:
v4l2_std_id std_id; //这个就是个64bit得数 int ioctl(int fd, int request, struct v4l2_standard *argp);
v4l2_standard结构体定义:
typedef u64 v4l2_std_id; struct v4l2_standard { u32 index; v4l2_std_id id; u8 name[24]; struct v4l2_fract frameperiod; /* Frames, not fields */ u32 framelines; u32 reserved[4]; };
当然世界上现在有多个视频标准,如NTSC和PAL,他们又细分为好多种,那么我们的设 备输入/输出究竟支持什么样的标准呢?我们的当前在使用的输入和输出正在使用的是哪 个标准呢?我们怎么设置我们的某个输入输出使用的标准呢?这都是有方法的。
查询我们的输入支持什么标准,首先就得找到当前的这个输入的index,然后查出它的 属性,在其属性里面可以得到该输入所支持的标准,将它所支持的各个标准与所有的标准 的信息进行比较,就可以获知所支持的各个标准的属性。一个输入所支持的标准应该是一 个集合,而这个集合是用bit与的方式用一个64位数字表示。因此我们所查到的是一个数字。
Example: Information about the current video standard v4l2_std_id std_id; //这个就是个64bit得数
struct v4l2_standard standard; // VIDIOC_G_STD就是获得当前输入使用的standard,不过这里只是得到了该标准的id // 即flag,还没有得到其具体的属性信息,具体的属性信息要通过列举操作来得到。 if (-1 == ioctl (fd, VIDIOC_G_STD, &std_id)) { //获得了当前输入使用的standard // Note when VIDIOC_ENUMSTD always returns EINVAL this is no video device // or it falls under the USB exception, and VIDIOC_G_STD returning EINVAL // is no error. perror (”VIDIOC_G_STD”); exit (EXIT_FAILURE); } memset (&standard, 0, sizeof (standard)); standard.index= 0; //从第一个开始列举 // VIDIOC_ENUMSTD用来列举所支持的所有的video标准的信息,不过要先给standard // 结构的index域制定一个数值,所列举的标 准的信息属性包含在standard里面, // 如果我们所列举的标准和std_id有共同的bit,那么就意味着这个标准就是当前输 // 入所使用的标准,这样我们就得到了当前输入使用的标准的属性信息 while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) { if (standard.id & std_id) { printf (”Current video standard:%s\n”, standard.name); exit (EXIT_SUCCESS); } standard.index++; } /* EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception.*/ if (errno == EINVAL || standard.index == 0) { perror (”VIDIOC_ENUMSTD”); exit (EXIT_FAILURE); }
7. 申请和管理缓冲区
应用程序和设备有三种交换数据的方法,直接 read/write、内存映射(memory mapping)和用户指针。这里只讨论内存映射(memory mapping)。
7.1 向设备申请缓冲区 VIDIOC_REQBUFS
相关函数:
int ioctl(int fd, int request, struct v4l2_requestbuffers *argp);
相关结构体:
struct v4l2_requestbuffers { u32 count;// 缓冲区内缓冲帧的数目 enum v4l2_buf_type type; // 缓冲帧数据格式 enum v4l2_memory memory; // 区别是内存映射还是用户指针方式 u32 reserved[2]; };
注:enum v4l2_memoy
{ V4L2_MEMORY_MMAP, V4L2_MEMORY_USERPTR }; //count,type,memory 都要应用程序设置
例:申请一个拥有四个缓冲帧的缓冲区
struct v4l2_requestbuffers req; req.count=4; req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory=V4L2_MEMORY_MMAP; ioctl(fd,VIDIOC_REQBUFS,&req);
7.2 获取缓冲帧的地址,长度:VIDIOC_QUERYBUF
相关函数:
int ioctl(int fd, int request, struct v4l2_buffer *argp);
相关结构体:
struct v4l2_buffer { u32 index;//buffer 序号 enum v4l2_buf_type type; //buffer 类型 u32 byteused;//buffer 中已使用的字节数 u32 flags;// 区分是MMAP 还是USERPTR enum v4l2_field field; struct timeval timestamp; // 获取第一个字节时的系统时间 struct v4l2_timecode timecode; u32 sequence;// 队列中的序号 enum v4l2_memory memory; //IO 方式,被应用程序设置 union m { u32 offset;// 缓冲帧地址,只对MMAP 有效 unsignedlong userptr; }; u32 length;// 缓冲帧长度 u32 input; u32 reserved; };
9.3 内存映射MMAP 及定义一个结构体来映射每个缓冲帧。
相关结构体:
struct buffer { void* start; unsigned int length; }*buffers;
相关函数:
#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) //addr 映射起始地址,一般为NULL ,让内核自动选择 //length 被映射内存块的长度 //prot 标志映射后能否被读写,其值为PROT_EXEC,PROT_READ,PROT_WRITE, PROT_NONE //flags 确定此内存映射能否被其他进程共享,MAP_SHARED,MAP_PRIVATE //fd,offset, 确定被映射的内存地址 返回成功映射后的地址,不成功返回MAP_FAILED ((void*)-1) 相关函数: int munmap(void *addr, size_t length);// 断开映射 //addr 为映射后的地址,length 为映射后的内存长度 例:将四个已申请到的缓冲帧映射到应用程序,用buffers 指针记录。 复制代码 buffers = (buffer*)calloc (req.count, sizeof (*buffers)); if (!buffers) { // 映射 fprintf (stderr,"Out of memory/n"); exit (EXIT_FAILURE); } for (unsigned int n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; memset(&buf,0,sizeof(buf)); buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory= V4L2_MEMORY_MMAP; buf.index= n_buffers; // 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小 if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) exit(-1); buffers[n_buffers].length= buf.length; // 映射内存 buffers[n_buffers].start=mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) exit(-1); }
8. 缓冲区处理好之后,就可以开始获取数据了
8.1 启动 或 停止数据流 VIDIOC_STREAMON, VIDIOC_STREAMOFF
int ioctl(int fd, int request, const int *argp); //argp 为流类型指针,如V4L2_BUF_TYPE_VIDEO_CAPTURE.
10.2 在开始之前,还应当把缓冲帧放入缓冲队列:
VIDIOC_QBUF// 把帧放入队列
VIDIOC_DQBUF// 从队列中取出帧
int ioctl(int fd, int request, struct v4l2_buffer *argp);
例:把四个缓冲帧放入队列,并启动数据流
unsigned int i; enum v4l2_buf_type type; for (i = 0; i < 4; ++i) // 将缓冲帧放入队列 { struct v4l2_buffer buf; buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory= V4L2_MEMORY_MMAP; buf.index= i; ioctl (fd, VIDIOC_QBUF,&buf); } type= V4L2_BUF_TYPE_VIDEO_CAPTURE; ioctl (fd, VIDIOC_STREAMON,&type); // 这有个问题,这些buf 看起来和前面申请的buf 没什么关系,为什么呢?
例:获取一帧并处理
struct v4l2_buffer buf; CLEAR (buf); buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory= V4L2_MEMORY_MMAP; ioctl (fd, VIDIOC_DQBUF,&buf); // 从缓冲区取出一个缓冲帧 process_image (buffers[buf.index.]start);// ioctl (fdVIDIOC_QBUF&buf); //
-
imx6ull开发板,usb免驱摄像头的配置
2021-02-09 20:02:05在/dev下面,只能找到video0,说明开发板并没有识别出有新连接进来的摄像头。 需要在内核中,配置支持UVC标准的USB驱动,重新配置即可。 -
OTG-UVC免驱安卓用视频APP
2018-12-28 22:03:05难得很不好找的安卓OTG摄像头APP,可以录像也可以拍照,我做钓鱼水下摄像头用的 -
OpenWRT下使用UVC摄像头
2017-05-21 18:44:40准备在OpenWRT系统使用UVC免驱摄像头采集图像,编译的系统使用默认的配置。使用程序对摄像头进行数据采集的时候发现程序只能进行支持的格式读取,不能进行格式设置、缓冲区分配和图像采集,一开始怀疑是摄像头不支持... -
内核配置zc301 uvc USB摄像头 android usb 摄像头
2013-07-22 15:39:12开发板系统: ...插上zc301 USB 免驱摄像头,/dev/目录下并没有此设备。需要在内核中去配置zc301系列USB摄像头。 make menuconfig Device Drivers ---> Multimedia support ---> * > Video For Linu -
Linux下控制免驱USB摄像头的信息
2016-07-15 20:56:15(这里我说的是UVC的USB摄像头哈,也就是所谓的免驱摄像头) 一般来说也就下面几步。 1、打开摄像头 2、获取摄像头信息 3、设置摄像头信息 4、控制摄像头开始摄像 5、设置视频数据的内存映射 6、获取视频数据... -
如何在QT中将Qwidget类提升为USB(uvc)摄像头类的使用
2020-07-15 21:39:18UVC是一种摄像头协议,USB摄像头基本都是UVC协议的 很多商家都说摄像头”免驱”,并不是真正免驱动,只不过是系统自带这个UVC驱动而已,所以它们敢说”免驱”. 因为UVC摄像头使用非常非常非常广泛,所以很多系统都集成了... -
uvc linux usb摄像头驱动
2010-05-31 11:59:01linux下usb摄像头的驱动,支持绝大多数windows免驱摄像头,绝对好东西 -
ROS教程之使用UVC摄像头
2018-03-08 19:25:36ROS版本:indigo Ubuntu14.04 ...免驱摄像头,即为UVC。2.安装UVC摄像头驱动。注明:我的已经安装过了。 3.将驱动source到ros路径中。4.显示图片 参考:http://blog.csdn.net/jasmine_shine/article/details/4671... -
Windows平台使用DirectShow获取UVC摄像头上按键后的抓拍图
2018-10-22 09:56:52UVC是一种标准的USB视频设备协议,就是传说中的免驱摄像头。UVC是Usb Video Class的简称。 Windows平台上UVC驱动文档 DirectShow简介 DirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的新一代... -
uvc的usb摄像头笔记
2017-05-03 17:25:06现在绝大多数摄像头所采用的是免驱摄像头,一般有两种传输格式,YUY2和MJPG, 前者是无压缩图像格式的视频,系统资源占用少(因为不用解码),不需要解码器,缺点是帧率稍慢(受限于USB分配的带宽), 后者是相当于... -
iTOP-iMX6ULL开发板-Qt5下使用UVC摄像头
2020-08-31 14:08:14本章节介绍如何在 Qt5 文件系统测试USB免驱摄像头,例程中使用迅为 i.MX6ULL 终结者开发板,yocto 的 Qt5 文件系统和编译器,测试程序(Qt5Camera)在本章节同一目录下。 将 UVC 摄像头连接到开发板的 USB 接口... -
【Linux编程】UVC摄像头采集与显示(V4L2编程)
2020-12-08 14:11:31手头有一个UVC(usb video class)摄像头(也称为免驱摄像头),就顺便学习了一下V4L2编程 ,写代码的过程中参考了前辈的博客,觉得写的非常的好,特将链接贴在这里 ... 关于V4L2讲解的可以学习前辈的博客,这里只是... -
使用V4L2读取摄像头并在LCD上显示
2019-01-30 18:21:20我的环境是友善之臂的fire3,Ubuntu1604,使用的是uvc免驱摄像头 大致的工作流程如下 一、获取摄像头图片 1、打开摄像头 2、获取摄像头的一些信息,比如支持的格式等等 3、设置摄像头的一些参数,比如输出格式... -
OK210-uvc摄像头采集并显示在屏幕上(v4l2编程)
2016-05-21 14:00:52手头有一个UVC(usb video class)摄像头(也称为免驱摄像头),就顺便学习了一下V4L2编程 ,写代码的过程中参考了前辈的博客,觉得写的非常的好,特将链接贴在这里 ...关于V4L2讲解的可以学习前辈的博客,这里只是写... -
[迅为开发板资料]iMX6ULL开发板QT5下使用UVC摄像头
2020-10-21 10:46:46本文转自迅为《i.MX6ULL开发板使用手册》第九十六章 i.MX6ULL终结者手册下载链接 ... ...本章节使用的资料已经放到了开发板网盘资料中,路径为:11_Linux 系统...本章节介绍如何在Qt5文件系统测试USB免驱摄像头,... -
UVC 摄像头在 RK3399 上的应用
2019-11-18 10:13:08UVC 全称 USB Video Class 、是 USB-IF 定制的一套标准,所有遵循这一标准的 USB 接口摄像头在 Windows Linux 等系统下,几乎能直接使用,达到类似免驱的效果。 当然了,并不是说真正的不需要驱动,而是只要某个 USB... -
安卓双USB摄像头 免驱的可用
2018-10-22 10:51:01支持带麦克风的USB网络摄像头和UVC视频采集卡,并且设备必须支持MJPEG格式! 不支持麒麟940及以前的SoC! 推荐Android 5.0及以上系统运行,一些修改过的ROM可能无法运行。《USB双摄像头》可以让你的Android设备通过... -
Ehome:智能家居之基于USB摄像头免驱的视频采集服务器
2017-03-14 23:11:10内核中自带了满足uvc格式的摄像头驱动,如果你手中的摄像头满足uvc规范,该摄像头就是免驱,只需要对内核进行配置,将uvc模块对应的代码编译到uImage 判断摄像头满足uvc格式规范? #:' lsusb 再将摄像头插入... -
ubuntu-Linux系统读取USB摄像头数据(uvc)
2017-12-26 12:22:59我想现在用的摄像头是UVC免驱的。根据国嵌的教程中有一个gspca摄像头的程序。我发现把gspca的采集程序用到uvc上时,在显示图像的时候提示没有huffman表。但是在显示gspca的摄像头时却没有问题。为此特别找了以下的... -
UVC(USB Video Class)规范
2011-12-09 15:53:18最新USB Video Class 1.1规范,开发UVC免驱USB摄像头必读资料