在raspberry上使用USB摄像头做视频采集

来源:互联网 发布:宋定伯卖鬼 知乎 编辑:程序博客网 时间:2024/05/22 01:35

以前看过国嵌的H.264视频采集程序,想在树莓派上试一试,现在记录一下自己尝试的过程。

检查是否支持USB摄像头

插入USB摄像头前

pi@raspberrypi:~$ lsusbBus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 

插入USB摄像头后

pi@raspberrypi:~$ lsusbBus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. Bus 001 Device 004: ID 1e4e:0109 

可以看到raspberry已经识别了USB摄像头。

要想拍摄照片,你要先安装fswebcam,这是一款小型摄像头程序。可以直接通过Raspbian的仓库来安装fswebcam。
$ sudo apt-get install fswebcam
fswebcam安装完成后,在终端中运行下面的命令来抓一张来自摄像头的照片:

$ fswebcam --no-banner -r 640x480 image.jpgpi@raspberrypi:~$ fswebcam --no-banner -r 640x480 image.jpg--- Opening /dev/video0...Trying source module v4l2.../dev/video0 opened.No input was specified, using the first.--- Capturing frame...Captured frame in 0.00 seconds.--- Processing captured image...Disabling banner.Writing JPEG image to 'image.jpg'.

V4L(Video for Linux 标准,按照统一的公共接口去使用不同种类的USB摄像头)
驱动程序与应用程序之间的统一接口,双方都必须遵守该接口的定义。

在宿主机上进行编译,然后将可执行文件放到树莓派上,执行server_arm程序后报错:

pi@raspberrypi:~/H264$ ./server_arm start 2.0...Can't get device information: VIDIOCGCAPDevice name:Width:0 ~ 0Height:0 ~ 0ERROR:VIDIOCGWINERROR:VIDIOCSWINERROR:VIDIOCGPICTERROR: VIDIOCSPICT,Can't set video_picture formatERROR:VIDIOCGMBUF,Can't get video_mbufFrames:0ERROR:mmapBuffer size:0Offset:0ERROR: VIDIOCMCAPTUREERROR: VIDIOCSYNCSegmentation fault

发现是由于获取摄像头基本信息失败造成的,如下所示:

ret = ioctl( cam_fd,VIDIOCGCAP,&cam_cap );  /* 获取摄像头的基本信息 */if( ret<0 ) {    printf("Can't get device information: VIDIOCGCAP\n");}

查证后,发现在V4L2中,规定必须实现 VIDIOC_QUERYCAP命令,而V4L则规定必须实现VIDIOCGCAP,决定尝试改为V4L2的命令,重新编译、运行,有人遇到过该问题v4l(video for Linux)使用摄像头实验的一点小感慨。关于V4L2与V4L的关系可以参考V4L简介及其与V4L2区别。

可以看出raspberry已经安装了V4L2的内核模块,如下:

pi@raspberrypi:~/H264$ lsmod | grep v4lv4l2_common 3777  1 videobuf2_corevideodev  121307  3 uvcvideo,v4l2_common,videobuf2_core

在宿主机上安装V4L的库

zfchen@zfchen-E440:/$ sudo apt-get install libv4l-dev

查看库文件的安装路径

zfchen@zfchen-E440:/usr/lib$ dpkg -L libv4l-dev/./usr/usr/include/usr/include/libv4l1-videodev.h/usr/include/libv4l1.h/usr/include/libv4l2.h/usr/include/libv4lconvert.h/usr/lib/usr/lib/i386-linux-gnu/usr/lib/i386-linux-gnu/pkgconfig/usr/lib/i386-linux-gnu/pkgconfig/libv4l1.pc/usr/lib/i386-linux-gnu/pkgconfig/libv4l2.pc/usr/lib/i386-linux-gnu/pkgconfig/libv4lconvert.pc/usr/share/usr/share/doc/usr/lib/i386-linux-gnu/libv4l1.so/usr/lib/i386-linux-gnu/libv4l2.so/usr/lib/i386-linux-gnu/libv4lconvert.so/usr/share/doc/libv4l-dev

从Linux内核中找到了V4L2的头文件,添加到H264/app/目录下。 头文件路径为:include/linux/videodev2.h头文件,实际上指向/include/uapi/linux/videodev2.h头文件(该路径下面还有v4l2-common.hv4l2-common.h文件)。
编译,make 输出信息如下,包含一些警告信息:

zfchen@zfchen-E440:~/my_repository/H264/app$ makearm-bcm2708hardfp-linux-gnueabi-cc-c -o server_arm.o server_arm.cserver_arm.c: In function 'init_encoder':server_arm.c:265:14: warning: assignment makes pointer from integer without a cast [enabled by default]server_arm.c: In function 'main':server_arm.c:337:3: warning: passing argument 1 of 'printf' from incompatible pointer type [enabled by default]In file included from server_arm.c:7:0:/home/zfchen/my_repository/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/../arm-bcm2708hardfp-linux-gnueabi/sysroot/usr/include/stdio.h:359:12: note: expected 'const char * __restrict__' but argument is of type 'struct _IO_FILE *'

编译通过后,发现执行还是有错,错误信息如下:

pi@raspberrypi:~$ ./server_arm fastspeed.txt start 2.0...Device name:uvcvideoWidth:0 ~ 943285811Height:761426805 ~ 808464432ERROR:VIDIOCGWINERROR:VIDIOCSWINERROR:VIDIOCGPICTERROR: VIDIOCSPICT,Can't set video_picture formatERROR:VIDIOCGMBUF,Can't get video_mbufFrames:0ERROR:mmapBuffer size:0Offset:0ERROR: VIDIOCMCAPTUREERROR: VIDIOCSYNCSegmentation fault

修改 VIDIOCGWIN 指令之后仍然报错,没弄明白。
然后找到一篇根据国嵌的程序改的v4l2程序 ,使用这个代码后发现,服务器端可以执行,但是客户端(PC)的上位机显示为花屏。

1 0
原创粉丝点击