基于ARM和Linux的视频图像采集系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于ARM和Linux的视频图像采集系统
摘要:提出了一种基于s3c2440arm处理器、usb摄像头硬件平台和嵌入式linux操作系统的视频采集系统方案。
研究了usb摄像头在linux中的驱动开发,对系统总体结构、
基于v4l2的视频采集以及视频动态显示应用程序等功能模块设计做了具体介绍。
试验结
果表明,本系统实现了在lcd显示器上动态显示usb摄像头采集的图像,且视频采集稳定,图像帧过渡平稳,提供了一种成本低、体积小、功耗低的图像采集方案,能够很好地应用
在视频监控等系统中。
关键词:视频采集;s3c2440;linux;v4l2;qtopia
随着嵌入式系统、网络和图像信息技术的渗透,以及对设备体积和无线的要求越来越多,以嵌入式体系为核心的图像采集系统已成为研究热点。
其中,嵌入式系统具有功耗低、体积小和集成接口丰富等优点[1];嵌入式linux系统具有源代码开放、内核稳定、可裁
减性、支持硬件广泛及驱动丰富等特点,成为嵌入式系统领域不可或缺的操作系统之一;usb摄像头具有性能好、价格低、使用方便、易于集成到嵌入式系统等特点,在视频监控
和网络视频会议等领域有广泛应用[2]。
本文以开发成本低、体积小、功耗低的嵌入式
图像采集系统为目标,采用arm9处理器s3c2440和usb接口的摄像头组成硬件体系,采
用嵌入式linuxos和qtopia文件系统构建应用系统,通过编写usb摄像头驱动和qt视频
显示程序实现视频采集和视频显示程序,很好地完成了图像采集的功能。
由于本系统成本低、扩展简单、体积小,能够很好地扩展到和视频相关的很多领域[3]。
1系统硬件设计
系统硬件总体结构,嵌入式处理器采用三星公司的基于arm920t内核的16/32位risc嵌
入式微处理器s3c2440,其主频高达400mhz,内置丰富的外设资源,包括存储器、lcd控
制器、串口、i2c、i2s和usb等接口控制电路,主要面向高性价比、低功耗的应用,适合于图像和视频处理。
flash存储器采用64mbnand存储器用于存放linux操作系统启动引导程序bootloader、linux系统内核、qt文件系统及系统掉电后要保存的数据。
sdram中用
于存放linux系统运行时的一些临时数据。
lcd显示器大小为4.3英寸,480×272分辨率,并带有触摸屏[4]。
目前用作摄像头的掌控芯片组主要有中芯微公司的zc0301p和美国ov公司的ov511+
芯片。
国内市场上的usb摄像头基本上使用的就是zc0301p,并且中芯微公司的主流掌控
芯片都具有硬件jpeg编码模块,利用这个特性可以轻易从摄像头获得经过放大的图片格式,可以精简应用软件的设计,因此本设计使用zc0301p芯片的130万像素的usb摄像头。
在硬件系统中,通过usbUSB将摄像头与s3c2440相连。
利用u
件实现的细节,使得应用程序可以像操作普通文件一样来操作外部设备,可以使用和
操作文件中相同的、标准的系统调用接口函数来完成对硬件设备的打开、关闭、读写和
i/o控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。
对于usb口摄
像头,其驱动程序中提供了基本的i/o操作接口函数open、read、write、close的实现
以及对i/o通道的控制接口函数ioctl的实现等,并定义在structfile_operations中。
video4linux2(v4l2)是linux中关于视频设备的内核驱动,它为针对视频设备的应用程
序编程提供一系列接口函数,这些视频设备包括现今市场上流行的tv卡、视频捕捉卡和
usb摄像头等。
linux内核提供video4linux2应用程序接口,在程序开发时首先是基于video4linux2api函数来设计程序[6]。
3.2video4linux2下的摄像头采集编程在usb摄
像头被驱动后,只需要再编写一个对视频采集的应用程序就可以了,根据嵌入式系统开发
特征,先在宿主机上编写应用程序,再使用交叉编译器进行编译链接,生成在目标平台的
可执行文件。
宿主机与目标板通常采用打印终端的方式进行交叉调试,成功后移植到目标
平台。
本文编写的视频采集程序是在安装linux操作系统的宿主机pc上进行的,下面是
具体论述[7]。
程序中定义的重要数据结构为:structv4l2_capabilitycap;
structv4l2_fmtdescfmtdesc;structv4l2_formatfmt;
structv4l2_requestbuffersreq;structv4l2_bufferbuf;这些数据结构都是
video4linux2支持的,它们的用途如下。
(1)v4l2_capability包含摄像头的基本信息,例如设备名称、支持的最大及最小分辨率、信号源信息等,分别对应着结构体中成员
变量name、maxwidth、maxheight、minwidth、minheight、channels、type等;(2)structv4l2_fmtdesc获取设备支持的视频格式;(3)v4l2_formatfmt设置视频捕获格式;(4)v4l2_requestbuffers用于请求分配内存;(5)v4l2_buffer代表驱动中
的一帧。
linux下视频图像采集流程。
(1)关上视频设备,赢得文件描述符摄像头在系统中对应的设备文件为
/dev/video0,使用系统调用函数video_fd=open(“/dev/video0”,o_rdwr,0),
video_fd为设备关上后回到的文件描述符,以后的系统调用函数就可以采用它去对设备文件展开操作方式了。
接着用ioctl(video_fd,vidioc_querycap,&cap)函数加载
v4l2_capability中的有关摄像头的信息。
该函数顺利回到后,这些信息从内核空间拷贝
到用户程序空间capability各成员分量中,采用printf函数就可以获得各成员分量信息。
(2)设置图片格式将图片阔降为320,低降为240,其他参数维持预设。
structv4l2_formatfmt;clear(fmt);fmt.type=
v4l2_buf_type_video_capture;fmt.fmt.pix.width=320;
fmt.fmt.pix.height=240;fmt.fmt.pix.field=v4l2_field_interlaced;
fmt.fmt.pix.pixelformat=video_format;if(ioctl(video_fd,vidioc_s_fmt,
&fmt)<0){exit(1);} (3)分配缓冲区structv4l2_requestbuffersreq;clear(req);req.count=4;req.type=v4l2_buf_type_video_capture;
req.memory=v4l2_memory_mmap;if(ioctl(video_fd,vidioc_reqbufs,&req)<0){ exit(1);} 然后通过调用ioctl(video_fd,vidioc_querybuf,&buf)获得缓
冲区的长度(buf.length)和偏移地址(fd,buf.m.offset),将这两个参量作为参数传
给mmap函数:buffers[num].start=mmap(null,buf.length,prot_read|prot_write,map_shared,fd,buf.m.offset);缓冲区分配好之后,驱动并不会向里面写入数据,还
需要将每个缓冲区放入视频采集队列:ioctl(video_fd,vidioc_qbuf,&buf);(4)启动采集过程,读取数据完成以上初始化设置工作后,就可以对视频进行采集了,有直
接读取read()和内存映射mmap()两种方法。
read()通过内核缓冲区来读取数据;
而mmap()通过把设备文件映射到内存中,绕过了内核缓冲区,最快的磁盘访问往往还是慢于最慢的内存访问,因此mmap()方式加速了i/o访问。
另外,mmap()系统调用使得
进程之间通过映射同一文件实现共享内存,各进程可以像访问普通内存一样对文件进行访问,访问时只需要使用指针而不用调用文件操作函数。
因为mmap()的以上优点,所以在程序实现中采用内存映射方式。
应用程序调用vidioc_streamon来启动采集过程:enumv4l2_buf_typetype= v4l2_buf_type_video_capture;ioctl(fd,
vidioc_streamon,&type);采集过程开始以后,驱动会不停地将数据写入分配的缓冲区内,当一个缓冲区的数据准备就绪后,驱动就会将其放入输出队列,等待应用程序的处理。
当所有的缓冲区都进入输出队列后,驱动将停止采集,并等待缓冲区重新放入采集队列。
读取数据时,首先需要将一个缓冲区出队列:structv4l2_bufferbuf;ioctl (fd,vidioc_dqbuf,&buf);驱动会从输出队列取出一个缓冲区,并将其序号赋值给buf.index,应用程序可以通过buffers[buf.index].start来访问缓冲区的数据。
当处理完成后,需要将其重新放入采集队列:ioctl(fd,vidioc_qbuf,&buf);(5)停止采集首先停止采集过程ioctl(fd,vidioc_streamoff,&type),然后使用munmap函数删除映射,最后调用close(fd)函数关闭设备。
视频图像显示模块使用gui软件提供的api函数的方法进行视频图像显示。
视频显示程序基于qt库来编写,原理是将buf 的内容转为image再转为pixmap,然
后表明出。
按照以上撰写流程撰写视频表明程序后,通过交叉编译器编程出来目标平台能继续执行的代码,浏览至开发板中,即可同时实现视频的实时收集。
4测试结果与分析在目标平台上运转撰写的视频收集程序,摄像头所收集至的实时动态图像的图片。
从图中可以窥见,该系统所提供更多的视频画面图像质量较好,全然可以满足用户实际应用领域中对画面质量的建议。
采用内嵌arm9核的s3c2440嵌入式微控制器和zc0301p视频处理芯片,同时结合linux的video4linux视频接口技术和视频流传输技术,实现了快速视频采集的应用[8]。
实践表明,采用高性能的arm9核的微控制器和嵌入式linux操作系统,使视频采集系统的视频画面清晰流畅,其性能优越、稳定而且构建成本低。
该方案可以广泛应用于视频通信和现场监测等智能控制领域,具有广阔的应用前景。