基于ZedBoard的Webcam设计

2019-03-16 18:06

基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集

硬件平台:DigilentZedBoard + USB 摄像头

开发环境:Windows XP 32 bit + Wmare 8.0 + Ubuntu 10.04 + arm-linux-xilinx-gnueabi交叉编译环境

Zedboardlinux: Digilent OOB Design

一、一些知识 1、V4L和V4L2。

V4L是Linux环境下开发视频采集设备驱动程序的一套规范(API),它为驱动程序的编写提供统一的接口,并将所有的视频采集设备的驱动程序都 纳入其的管理之中。V4L不仅给驱动程序编写者带来极大的方便,同时也方便了应用程序的编写和移植。V4L2是V4L的升级版,由于我们使用的OOB是 3.3的内核,不再支持V4L,因而编程不再考虑V4L的api和参数定义。 2、YUYV与RGB24

RGB是一种颜色的表示法,计算机中一般采用24位来存储,每个颜色占8位。YUV也是一种颜色空间,为什么要出现YUV,主要有两个原因,一个是 为了让彩色信号兼容黑白电视机,另外一个原因是为了减少传输的带宽。YUV中,Y表示亮度,U和V表示色度,总之它是将RGB信号进行了一种处理,根据人 对亮度更敏感些,增加亮度的信号,减少颜色的信号,以这样“欺骗”人的眼睛的手段来节省空间。YUV到RGB颜色空间转换关系是: R = Y + 1.042*(V-128);

G = Y - 0.34414*(U-128) - 0.71414*(V-128); B = Y + 1.772*(U-128);

YUV的格式也很多,不过常见的就是422、420等。YUYV就是422形式,简单来说就是,两个像素点P1、P2本应该有Y1、U1、V1和Y2、U2、V2这六个分量,但是实际只保留Y1、U1、Y2、V2。

图1 YUYV像素

二、应用程序设计

先定义一些宏和结构体,方便后续编程

1#define TRUE 1 2#define FALSE 0 3

4#define FILE_VIDEO \

5#define BMP \ 6#define YUV \ 7

8#define IMAGEWIDTH 640 9#define IMAGEHEIGHT 480 10

11staticintfd;

12staticstruct v4l2_capability cap; 13struct v4l2_fmtdesc fmtdesc; 14struct v4l2_format fmt,fmtack; 15struct v4l2_streamparm setfps; 16struct v4l2_requestbuffers req; 17struct v4l2_buffer buf; 18enum v4l2_buf_type type;

19unsignedcharframe_buffer[IMAGEWIDTH*IMAGEHEIGHT*3]; 其中

#define FILE_VIDEO \是要访问的摄像头设备,默人都是/dev/video0 #define BMP \#define YUV \

是采集后存储的图片,为了方便测试,这里将直接获取的yuv格式数据也保存成文件,可以通过yuvviewer等查看器查看。

staticintfd;

staticstruct v4l2_capability cap; struct v4l2_fmtdesc fmtdesc; struct v4l2_format fmt,fmtack; struct v4l2_streamparm setfps; struct v4l2_requestbuffers req; struct v4l2_buffer buf; enum v4l2_buf_type type;

这些结构体的定义都可以从/usr/include/linux/videodev2.h中找到定义,具体含义在后续编程会做相应解释。

#define IMAGEWIDTH 640

#define IMAGEHEIGHT 480 为采集图像的大小。

定义一个frame_buffer,用来缓存RGB颜色数据

unsigned charframe_buffer[IMAGEWIDTH*IMAGEHEIGHT*3]

这些宏和定义结束后,就可以开始编程配置摄像头并采集图像了。一般来说V4L2采集视频数据分为五个步骤:首先,打开视频设备文件,进行视频采集 的参数初始化,通过V4L2接口设置视频图像的采集窗口、采集的点阵大小和格式;其次,申请若干视频采集的帧缓冲区,并将这些帧缓冲区从内核空间映射到用 户空间,便于应用程序读取/处理视频数据;第三,将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;第四,驱动开始视频数据的采集,应用程序从 视频采集输出队列取出帧缓冲区,处理完后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据;第五,停止视频采集。在本次设计中,定义了 三个函数实现对摄像头的配置和采集。

int init_v4l2(void); int v4l2_grab(void); int close_v4l2(void);

同时由于采集到的图像数据是YUYV格式,需要进行颜色空间转换,定义了转换函数。 int yuyv_2_rgb888(void); 下面就详细介绍这几个函数的实现。 1、初始化V4l2

(1)打开视频。linux对摄像头的访问和普通设备一样,使用open函数就可以,返回值是设备的id。

1if ((fd = open(FILE_VIDEO, O_RDWR)) == -1) 2{

3printf(\); 4return (FALSE); 5 }

(2)读video_capability中信息。通过调用IOCTL函数和接口命令VIDIOC_QUERYCAP查询摄像头的信息,结构体 v4l2_capability中有包括驱动名称driver、card、bus_info、version以及属性capabilities。这里我们 需要检查一下是否是为视频采集设备V4L2_CAP_VIDEO_CAPTURE以及是否支持流IO操作V4L2_CAP_STREAMING。

1if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) 2{

3printf(\,FILE_VIDEO); 4return (FALSE); 5}

6else 7{

8printf(\,cap.driver); 9printf(\,cap.card);

10printf(\,cap.bus_info); 11printf(\,cap.version);

12printf(\,cap.capabilities); 13

14if ((cap.capabilities& V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE) 15 {

16printf(\,FILE_VIDEO); 17 } 18

19if ((cap.capabilities& V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING) 20 {

21printf(\,FILE_VIDEO); 22 } 23 }

(3)列举摄像头所支持像素格式。使用命令VIDIOC_ENUM_FMT,获取到的信息通过结构体

v4l2_fmtdesc查询。这步很关键,不 同的摄像头可能支持的格式不一样,V4L2可以支持的格式很多,/usr/include/linux/videodev2.h文件中可以看到。

1fmtdesc.index=0;

2fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; 3printf(\);

4while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) 5{

6printf(\,fmtdesc.index+1,fmtdesc.description); 7fmtdesc.index++; 8 }

(4)设置像素格式。一般的USB摄像头都会支持YUYV,有些还支持其他的格式。通过前一步对摄像头所支持像素格式查询,下面需要对格式进行设 置。命令为VIDIOC_S_FMT,通过结构体

v4l2_format把图像的像素格式设置为V4L2_PIX_FMT_YUYV,高度和宽度设置为 IMAGEHEIGHT和IMAGEWIDTH。一般情况下一个摄像头所支持的格式是不可以随便更改的,我尝试把把一个只支持YUYV和MJPEG的摄像 头格式改为RGB24或者JPEG,都没有成功。

1fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

2fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 3fmt.fmt.pix.height = IMAGEHEIGHT; 4fmt.fmt.pix.width = IMAGEWIDTH;

5fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 6

7if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) 8{

9printf(\); 10return FALSE; 11 }

为了确保设置的格式作用到摄像头上,再通过命令VIDIOC_G_FMT将摄像头设置读取回来。

1if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) 2{

3printf(\); 4return FALSE; 5} 6{

7printf(\,fmt.type);

8printf(\,fmt.fmt.pix.pixelformat&0xFF, (fmt.fmt.pix.pixelformat>>8) &0xFF,(fmt.fmt.pix.pixelformat>>16) &0xFF, (fmt.fmt.pix.pixelformat>>24) &0xFF);

9printf(\,fmt.fmt.pix.height); 10printf(\,fmt.fmt.pix.width); 11printf(\,fmt.fmt.pix.field); 12 }

完整的初始化代码如下:

1int init_v4l2(void) 2{ 3inti;

4int ret = 0; 5

6//opendev

7if ((fd = open(FILE_VIDEO, O_RDWR)) == -1) 8 {

9printf(\); 10return (FALSE); 11 } 12

13//query cap

14if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) 15 {

16printf(\,FILE_VIDEO); 17return (FALSE); 18 }


基于ZedBoard的Webcam设计.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:A 6022开关、插座、风扇安装检验批质量验收记录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: