用v4l2和framebuffer实现usb摄像头图像采集并显示
前言
很多天了,看了数不尽的论坛和各网站的帖子后,我把我遇到的问题都解决的差不多了,感觉应该是把摄像头跑起来了,但还是遇到了一些问题,似乎是图像处理方面的,我好像解决不了这个问题了,我好想有个人帮帮我。写这篇文章估计得花3~4小时,我真心希望哪位朋友能明白我的想法,能顺手帮帮我。
正文
一,我的思路
我想用一幅图来说明我所做的事情,如图1所示(图中uvcdriver标错了,应该是uvcvideo)。
图1
图1左侧是图像采集,右侧是图像显示。采集的帧速是30 帧/秒。
二,v4l2(video for linux two)
驱动摄像头的是uvcdriver,该驱动设计时采用了v4l系列的标准(该标准好像是linuxTV制定的,linuxTV的官网是http://linuxtv.org/),我的CentOS6.3(内核是linux-2.6.32.60)采用的是v4l2标准。一开始我编写应用程序的时候什么都不懂,见论坛上帖子怎么讲,我就怎么写,当中很多是参照v4l标准,我当时不知道,直接照抄,出了问题,改用v4l2标准后才解决了问题。v4l2 API的在/usr/include/linux/videodev2.h头文件中,很容易就找到了。
采集图像的实例程序网上很多,但最经典的还是linuxTV官网推出的capture.c,这里给出地址http://linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/v4l2spec/capture.c这个程序写的很好,很值得研究。
我就是借鉴的这个程序,然后得到我的摄像头设备的信息,如图2(那个pixel_format应该用十六进制表示的,我没注意,十六进制的话应该是0x56595559,即YUYV的意思)所示。
图2
一插上摄像头,uvcvideo就直接把我的摄像头识别了。
v4l2我不想再多写了,基本上只要看了那个经典的capture.c就够了。
三,framebuffer
就目前我这水平,我还不想涉及到QT或者别的什么面向对象编程,我想简单一点,慢慢来。于是我直接选择了framebuffer,它的API在usr/include/linux/fb.h头文件中。刚开始用open函数打开/dev/fb0的时候根本就打不开,愣是要把grub设置一下,如图3所示。后面显示的时候要切记切换到命令行模式。
图3
关于那个vga=0x311以及一系列的frambuffer编程我是参照http://bbs.chinaunix.net/thread-2000076-1-1.html这个人的文章的,这里我复制一下他的一张表到下面,如表1所示。
4bit 8bit 15bit 16bit 24bit 32bit
640x400 x 0x300 x x x x
640x480 x 0x301 0x310 0x311 0x312 x
800x600 0x302 0x303 0x313 0x314 0x315 x
1024x768 x 0x305 0x316