基于嵌入式linux的视频图像采集
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于嵌入式linux的视频图像采集[摘要] 本文主要介绍在linux操作系统、arm xsbase270平台上,利用linux内核中已经植入video4linux函数库的数据结构和api函数,通过ov511摄像头实现视频采集的方案,本方案采用qt designer为开发环境,以效率较高的mmap(内存映射)方式截取视频;可保存单张的图片,也可保存为视频。
[关键词] 视频采集 video4linux 嵌入式linux mmap
一、引言
随着多媒体和通信技术的发展,越来越多的人希望能够直接通
过屏幕,看到所要监控的信息。
如:视频监控、webcam、视频会议和可视电话,摄像机等。
嵌入式系统的发展越来越集成化,功能也越来越强大。
本文论述的是基于嵌入式linux系统的视频采集模块的设计与实现。
由于linux对视频的支持是通过video4linux提供的。
并且red hat9.0内核中已经包含了video4linux软件包,所以利用video4linux编程接口就可以在xscale270平台实现对ov511 usb 摄像头图像数据的采集;使用qt进行界面设计,同时对需要的图像进行保存。
最终通过交叉编译连接,生成在arm平台上运行的程序。
作为大学生创新项目,通过相关的开发与研究,可以熟练地掌握嵌
入式系统的开发流程,以及对其中涉及到的相关技术有较为深入的理解。
二、系统内核的定制
在linux系统下对摄像头的支持是通过内核中video4linux模
块的加载来实现的,而该模块的加载可以是静态加载也可以是动态加载。
1.静态加载
这种加载方式使视频支持模块嵌在新生成的内核中;虽然会使内核的尺寸变大,但系统运行可靠。
其基本流程是:
(1)运行make menuconfig或make xconfig;
(2)选择multimedia device->下的video for linux(选为*号标示;这个选项的目的是加载video4linux模块,为视频采集设备提供了编程接口);
(3)在usb support->目录下,选择support for usb和 usb camera ov511 support(同样选为*号标示;这使在内核中加入了对ov511接口芯片的usb数字摄像头的驱动支持);
(4)保存配置并退出;
(5)make dep;make zimage
此时在/tftpboot下就生成了带有ov511驱动的内核。
2.动态加载
这种加载方式不会将视频支持模块嵌在新生成的内核中,只是告诉linux系统在需要的时候以模块方式调用,所以生成的内核相对较小。
与静态加载相比差别在于选择usb camera ov511 support 时选为标示;另外,还要运行make modules编译模块,其它的步骤与静态加载相同。
三、用video4linux api获取视频图像
在linux系统中将设备视为特殊文件以便于对其进行操作。
要用video4linux api获取视频图像,首先,打开视频设备;这通过调用open函数来实现,它返回设备文件描述符,以后的系统调用函数就使用该描述符来对设备进行操作;接着,读取设备信息;这可以得到结构类型各成员域中有关摄像头的信息;然后,设置设备的属性,比如图像的亮度、对比度等等。
最后,进行视频采集。
有两种方法实现视频数据的获取:
1.文件读写
文件读写的方式是通过read()和write()函数对摄像头进行读写,然后分配缓冲区存放。
这样每次都要调用read()对数据进行拷贝,设备的速度相对于内存的速度来说的比较慢的。
2.内存映射
在linux下,设备就是文件,文件的读写是慢速的,mmap方法可以将普通文件映射进内存,这样就可以通过访问内存的速度来访问文件。
图像的信息是非常大的,采用mmap进行读取数据,会整体提高采集性能。
四、视频采集的实现
1.视频采集时一些参数的初始化
定义的函数原型为v4l_grab_init(v4l_device *vd,int width,int height)参数vd为自定义的数据结构struct
_v4l_device,设置宽、高、帧使用情况的属性等。
该函数的重点代码如下:
vd->mmap.width = width;
vd->mmap.height = height;
vd->mmap.format = vd->picture.palette;
vd->frame =0;
vd->framestat[0] =0;
vd->framestat[1] =0;
vd->frame为当前帧,framestat[]标记该帧是否已被使用。
0表示未被使用
2.获取支持的帧数和基地址
v4l_get_mbuf( v4l_device *vd )
v4l_mmap(v4l_device *vd)
首先,使用vidiocgmbuf命令将摄像头的帧缓存的大小映射到
vd->mbuf.size,正使用的帧(0或1)映射到vd->mbuf.frames中,执行完该命令后,就可以用mmap函数将缓存映射到内存中了。
if(ioctl(vd->fd,vidiocgmbuf,&(vd->mbuf))map中,这样才能对获取到的数据进行操作。
在mmap函数里prot_read表示可读取该内存页, prot_write 则是可写入, map_shared 则是让这块mapping的区域和其它进程共享。
第一个参数为0是启始位置,
vd->mbuf.size则是长度(length)。
vd->fd则是设备的文件描述符,最后一个参数是offset。
if((vd->map =(unsigned char*)mmap(0,vd->mbuf.size,
prot_read|prot_write,map_shared,vd->fd,0)) mmap.frame =
frame;
if(ioctl(vd->fd,vidiocmcapture,&(vd->mmap))
framestat[frame] =1;
因为之前用framestat[]数组来记录哪个frame已经被使用,所以一开始要先判断目前的frame是否已经被使用:
if (vd->framestat[frame])
{
printf(“already used.\\n”, frame);
return -1;
}
如果没有被使用,就把mmap的frame填入frame编号,然后利用vidiocmcapture取影像。
结束前要把目前frame的状态标示成使用中,然后把framestat指定成现在的frame,完成工作后离开。
ioctl(vd->fd, vidiocmcapture, &(vd->mmap ) )是非阻塞的函数。
4.等待一帧截取结束
该功能由int v4l_grab_sync(v4l_device *vd ,int a)函数实现,参数vd为自定义的数据结构struct _v4l_device,frame值为0或1,意为第0帧或第1帧数据,成功返回0,失败则为-1;代码如下: if(ioctl(vd->fd,vidiocsync,&frame) framestat[frame] = 0;
return 0;
ioctl(vd->fd, vidiocsync, &(frame))是阻塞的。
利用vidiocsync等待完成后,该函数成功返回则表示表明一帧采集已完成,采集到的图像数据放到内存区中,读取该内存区中的
数据便可得到图像数据。
別忘了将目前frame的状态改回未被使用。
截取出来的视频数据放到了之前利用mmap()方式将device所map 的内存里,因为我们是利用mmap方式,所以会有2个(或以上)的frame,这时就要计算一下offset,才知道到底目前的视频资料被放到那裡了。
5.获得当前视频数据的地址
函数实现如下,参数vd为自定义的数据结构struct
_v4l_device,函数返回值为当前视频数据地址。
基地址是通过mmap 函数得到的,要区分出第0与第1帧的地址,就需将帧的偏移地址算出。
unsigned char *v4l_get_address(v4l_device *vd,int frame) {
return (vd->map + vd->mbuf.offsets[frame]);
}
6.视频的保存
对采集到的视频,系统默认保存为扩展名为.rgb24文件中,文件名是以视频画面的宽、高和保存的时间命名的。
实现的关键代码如下:
sprintf(f,”./picture/%dx%d_%d_%d_%d.rgb24”,set_width ,set_height,time2.hour(),time2.minute(),time2.second());
if((fp=fopen(f,”a+”))==null)
{
perror(“open error!\\n”);return -1;
}
fwrite(buf,x*y*3,1,fp);
fclose(fp);
五、qt界面设计
qt是一个多平台的c++图形用户界面应用程序框架。
它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。
qt是完全面向对象的很容易扩展,并且允许真正地组件编程。
qt设计器是用来设计和实现用户界面并能够在多平台下使用的一种工具。
qt设计器可以使用户界面设计实验变得简单。
在任何时候你可以要求所生成的代码去重建qt设计器产生的用户界面文件,并可以根据你的喜好来改变你的设计。
根据系统功能的需要,通过使用qt提供的相关控件即可方便地设计出如图一所示的视频采集系统的运行主界面。
六、结束语
作为大学生创新性实验项目,通过设计制作一个相对完整的视频数据采集系统,在学到许多实际技能的同时,也意识到自身理论的不足。
例如,视频数据的采集率还不能做的较高;尽管在开发中试图采用双线程采集,但由于受视频video4linux模块的限制,在判断是否采集结束和显示的时候,另外一帧并没有停止采集,当再次判
断另外一帧时,时间就少了很多,所以双线程的方法没有明显的提高帧数。
参考文献:
[1]陈俊宏.embedded linux嵌入式系统原理与实务[m].北京:中国铁道出版社,2004.184.
[2]郑灵翔.嵌入式linux系统设计.北京:北京航空航天大学出版社,2008.217-222.
[3](英)neil matthew, (英)richard stones著.陈健,宋健健译.linux程序设计(第三版)[m].北京:人民邮电出版
社,2007.122-127.
[4]qt帮助文档[eb].
[5]linux的应用——video streaming探讨(5).
本文系福建省大学生创新性实验计划项目编号:mjcx0805。