嵌入式平台下双路图像的采集与传输
2013-08-13张倩倩裴海龙
张倩倩,裴海龙
(华南理工大学自动化科学与工程学院,广东 广州 510640)
随着电子和信息技术的发展,视频处理在现代生活中得到广泛应用,如视频监控、视频会议、多媒体信息传递等,同时视频处理平台也在随着科技的进步发生着显著的变化。如今以应用为中心且软硬件可剪裁的嵌入式系统已经进入了人们生活的方方面面,成为当今最热门的领域之一。而Linux作为嵌入式操作系统又有诸多优势,例如它的低成本开发、多平台支持、内核可定制等[1]。本文基于嵌入式Linux设计了一套双路图像的采集系统,并经过合适的进程通信方式将两路图像结合起来,最后利用套接口传输到远程计算机上,直观地显示处理结果。本系统目前作为实验室的低空飞行平台下火灾检测项目的组成部分,已取得较好的试验效果。
1 系统搭建
1.1 硬件组成
根据系统目标要求,本系统硬件部分包括CM-T3530核心板、USB彩色摄像头、红外摄像头、USB图像采集卡和远程计算机等。本系统采用的是Compulab公司的CM-T3530嵌入式核心板,它功耗低、体积小、支持Linux操作系统,内置的WiFi接口实现了工业标准的无线网络连接,进而方便了实验和多用户操作。系统中采用SBT35作为该核心板的底板,在无需外接电路的情况下,已经内置了USB主从控制接口可以直接连接USB设备。
由于Linux内核包含UVC(USB Video Class)模块及USB设备驱动,同时USB端口具有即插即用、使用方便的优点,因此本系统的彩色摄像头选用普通的USB彩色摄像头即可,这里选用的是罗技的USB网络摄像头Pro9000[2]。在无人机平台下进行火灾监测时,火灾过程中产生的烟雾和火焰等火灾参量会发射红外线,所以应该选用合适的红外摄像机将这些火灾参量记录下来,为后续的火焰识别等工作打下良好的基础。本系统选用的红外摄像头为FLIR公司的一款长波非制冷系列红外摄像机Photo320,除了可满足以上应用外,其体积小和重量轻的特点也很适合作为无人机平台下的机载摄像头。该摄像机输出信号为复合视频信号(端子为AV端子),故需采用USB图像采集卡将该模拟信号转变为数字信号以让嵌入式微处理器做进一步处理。为了和Photo320摄像机相连,图像采集卡的输入端子应该有AV端子,显然其输出端口为USB端口和SB-T35的USB端口相连。结合以上要求选用Mine Vcap2800,该图像采集卡包含AV端子和S端子视频输入,1路USB输出,可将采集到的模拟图像信号实时地转换为数字信号。
图1即为系统硬件组成,本视频系统的主要工作(采集、通信、传输)都在核心板CM-T3530上完成,处理后的视频流通过WiFi网络即可传送给远程计算机。图2为本系统的基本框架,这里将CM-T3530上的彩色图像和红外图像程序分别记为Color_image和Infra_image,将PC机上的彩色图像和红外图像的显示程序分别记为Color_show和Infra_show。
1.2 软件配置
硬件搭建完成后,就要进行软件环境的配置。由于采用嵌入式Linux来作为CM-T3530的操作系统,故首先应得到适合的内核镜像、模块和文件系统以搭建基本的软件环境。CM-T3530 支持的内核版本为 Linux-2.6.32,首先应采用其默认配置文件cm_t35_defconfig对Linux内核进行初步配置,该文件可节省许多工作量。但是根据系统要求,需要正确识别视频设备,并可利用V4L2(Video for Linux Two)驱动进行图像采集等,故应在默认配置的基础上进行一些其他的配置[3]。
Linux的内核配置选项可以有两种方式被编译,即以静态的方式直接编译进内核或者以模块的方式动态加载。当针对特定的硬件平台时,由于其内核镜像的大小可能是有限制的,应有所选择地将部分驱动编译成模块,对该系统比较重要的模块做以下说明:
1)V4L2的上层videodev模块可以注册1个主设备号为81的字符设备,它结合次设备号确定了1个具体的设备文件,然后调用V4L2的各种应用函数即可对设备文件进行操作。
2)该系统USB接口的摄像头要求内核必须加载uvcvideo模块(USB Video Class Driver),只有该模块被加载才可以对具体的摄像头设备文件进行视频采集。由于模块间具有依赖关系,因此加载模块时需注意其先后顺序。
3)针对系统选用的视频采集卡的芯片组成,应选取相应编解码芯片的驱动。例如本系统的USB图像采集卡用到EMPIA公司的EM2860解码芯片,故应在内核选项Device Drivers选取“Empia EM28xx USB video capture support”,否则该采集卡将不能被正确识别运用。
4)为了使底板SB-T35的USB口、MTD设备等基本接口正常使用,内核可以将相应的驱动以静态加载的方式进行编译。
配置完内核之后,可利用交叉编译工具链来编译内核,进而得到相应的内核镜像和模块。结合默认的文件系统,即可将新的内核镜像成功地安装到核心板上,设置正确的启动参数即可启动进入新的嵌入式操作系统,接下来就可以交叉编译相应的程序以达到采集和传输图像的目的。
2 系统实现与测试
2.1 图像采集
V4L2是Linux操作系统中专门供影音图像开发的应用编程接口,它为视频设备提供了内核驱动[4-6]。在Linux系统中,视频设备同其他设备一样有其相应的设备文件,其名称一般是在/dev/video*。由于编译内核时已经将所有相关选项编译进来,故可以在/dev下发现/dev/video0和/dev/video1,它们是分别用来标识USB彩色摄像头和USB图像采集卡(即红外摄像头)。此时便可以根据V4L2的采集流程对这两个设备文件进行操作,流程图如图3所示,以下简要说明相关的函数和数据结构(以/dev/video0例)。
图3 图像采集流程图
1)打开设备文件,调用fd=open("/dev/video0",O_RDWR)可以返回文件描述符,在后面程序中通过使用此文件描述符对设备进行操作。
2)系统调用ioctl(fd,VIDIOC_QUERYCAP,& cap)查询视频设备的属性,如能否进行视频采集、能否对设备进行读写操作等。
3)系统调用ioctl(fd,VIDIOC_S_FMT,& fmt)设置视频图像格式和帧格式,将结构体fmt的内容写入到设备文件的初始化中。
4)在V4L2下截取图像有2种方法:mmap内存映射方式和直接读取设备方式。使用mmap映射方式不需要任何数据拷贝,效率高,为此采用mmap内存映射方式。首先系统调用VIDIOC_REQBUFS向设备驱动申请帧缓存,一般帧缓冲数目不超过5。然后程序调用calloc向用户空间申请相同数目的缓存,为驱动空间和用户空间缓存间的映射做好准备。
5)调用mmap(NULL,buffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,buffer.m.offset)完成上一步的映射工作。
6)调用(ioctl(fd,VIDIOC_QBUF,&buf)将用户空间申请到的缓存全部入队列,以便存放采集到的数据,然后调用ioctl(fd,VIDIOC_STREAMON,&type)开始图像采集。
7)调用(ioctl(fd,VIDIOC_DQBUF,&buf)取得已采集数据的缓存,此时得到的是原始采集数据。
8)如需循环采集图像,则将已经采集到数据的缓存重新入队列尾,以重新利用申请到的缓存。最后需要关闭视频设备,解除内存映射关系。
2.2 双路图像进程间通信
运用图像采集程序Color_image和Infra_image可以在CM-T3530分别获得同一位置的红外图像和彩色图像,两种图像各有可取之处。例如在火灾初步预警中可以利用红外摄像头连续图像中包含的亮度信息的变化获取热点的坐标,而彩色图像则具有更好的可视效果,但无法检测图像中的热点。如果将红外摄像头采集检测热点进程与彩色摄像头采集图像进程之间运用合适方式进行通信,就可以在CM-T3530上得到包含热点信息的彩色图像。
Linux下常用的进程通信手段是从UNIX平台上的进程通信手段继承而来的,目前有管道、消息队列、共享内存和信号量等几种手段。本系统采用的是系统V共享内存,它首先把所有共享数据放在共享内存区域(IPC shared memory region),然后需要访问数据的进程在自己的地址空间新增一块内存区域以映射共享内存区域,从而也就可以读写共享数据。
在双路图像进程中,需要首先分别调用shmget()来创建同一块共享内存,然后调用shmat()将共享内存区对象映射到调用进程的地址空间;此时红外图像进程向该共享内存中写入热点坐标,彩色图像进程从该共享内存中读出坐标值并在图像信息以圆标识,即实现了进程间的实时通信。具体实现为首先在Color_image和Infra_image中分别利用语句
创建同一块共享内存,并且分别利用语句
将共享内存区映射到各自进程的地址空间。然后在进程Infra_image通过赋值语句*shmptr_x=X和*shmptr_y=Y将其检测到的热点坐标(X,Y)写入到共享内存中,此时区域shmptr_x和shmptr_y的值即为热点坐标。而进程Color_image利用赋值语句a=*shmptr_x和b=*shmptr_y取得热点坐标(a,b)。
然后在两进程中均运用cvCircle函数在热点的范围处用圆标识,接下来就是两路图像的传输。
2.3 图像传输
以上图像的采集、进程间的通信都是在CM-T3530核心板上完成的,此时得到的两路图像信息可通过核心板内置的WiFi接口传到远程计算机上显示。Socket接口作为一种文件描述符其实就是一种特殊的I/O,首先通过类似于打开文件的函数调用可以得到一个整型的Socket描述符,随后的建立连接、传输数据等操作都是通过该整型描述符来进行的。运用Socket接口传输信息时,需要首先确定网络传输协议,比较常用的有TCP和UDP,这里运用UDP协议。
CM-T3530作为客户机端,向PC发送图像信息;PC作为服务器端,接收核心板发送的图像信息并显示出图像。以彩色图像的传输为例,CM-T3530上的Color_image首先创建一个基于UDP协议的套接字,它不需要和服务器建立连接,但是在发送图像数据时需指明服务器即PC的IP地址,这样就可以将图像数据发送过去。而PC上Color_show进程也要首先建立一个基于UDP协议的套接字,然后将该套接字和PC的IP綁定在一起以接收图像信息,最后调用Cvshowimage函数显示刚刚接收的一帧图像。其程序流程图及函数调用如图4所示。
图4 Socket传输流程图
2.4 系统测试
测试利用ioctl(fd,VIDIOC_S_FMT,& fmt)函数将两路图像的像素值设为160×120,利用cvCircle函数将两路图像中的热点用圆标出。测试时在CM-T3530的终端里运行Color_image和Infra_image两个程序,在PC的终端里运行Color_show和Infra_show程序以接收并显示图像,最后同时截取PC上两路图像的其中一帧,如图5所示。
图5中左边图像为红外图像,它准确地检测出图像中装有热水的杯子并用圆将热点标出;同时红外图像将检测出的热点位置信息通过进程间通信传递给彩色图像即图5中右边图像,这样就可以通过清晰的彩色图像准备地判断出拍摄场景中热点的位置。另外在程序中可利用函数gettimeofday(&tpstart,NULL)来获得采集传输若干帧图像时所用到的时间,从而可进一步得知两路图像的延迟时间和传输帧率。本次测试中PC上图像较真实场景的延迟时间为200 ms,即当热点发生移动时,200 ms后会在PC上显示出来,此时传输速度达到28 f/s。
如果改变图像的像素值,则图像的延迟时间和传输速度都会受到影响。这是因为V4L2采集图像时采用V4L2_PIX_FMT_YUYV 格式(YUV4∶2∶2),也即每 4 byte代表2个像素。所以当图像的像素值增大时,每帧图像所占用的字节数也会增大,则利用Socket传输一帧图像时所需要的传输次数会相应增大,导致延迟时间变大,传输速度也会变小。表1反映了改变双路图像的像素值时延迟时间和传输速度的变化,可以根据这些测试来选取合适的像素值,以获得合适的图像清晰程度和较好的画面实时性。
表1 传输效果测试
3 结束语
本文提出了基于CM-T3530核心板和Linux操作系统的嵌入式双路图像的采集与传输方案。系统采用Linux自带的V4L2视频编程接口,由于它不依赖于硬件所以可移植性较强,只需在宿主机上进行交叉编译即可移植到目标板上进行图像的采集传输等。可以根据系统的搭建目的对两路图像分别进行图像处理,并利用进程通信将两者优势结合,此系统可广泛应用于嵌入式图像处理领域。本文详细说明了该系统的搭建过程并对系统进行反复测试,可根据测试结果进一步对其优化,以达到更好的效果。
[1]华清远见嵌入式培训中心.嵌入式Linux系统开发[M].北京:人民邮电出版社,2009.
[2]张雷,温秀红.基于USB接口的视频图像采集系统设计[J].电视技术,2004,28(2):60-61.
[3]林文森,李钟慎,洪健.基于ARM嵌入式图像处理系统设计与实现[J].福州大学学报:自然科学版,2008(9):13-16.
[4]陈亮.基于Video4Linux2的图像采集程序设计[J].微计算机信息,2009(7):65-67.
[5]宋凯,严丽平,甘岚.嵌入式图像处理系统的设计与实现[J].计算机工程与设计,2009,30(19):4368-4370.
[6]STEVENS W R,RAGO S A.UNIX 环境高级编程[M].2版.尤晋元,张亚英,戚正伟,译.北京:人民邮电出版社,2006.