图2 系统软件框图
在视频采集与处理模块中,首先要按照要求在linux2.4.19内核中加入V4L (video for linux) 的支持项,然后在usb总线驱动中就会出现一些camera的选项,里面就有ov511(支持网眼3000)和stv680(支持MDC-30L数码相机)的驱动支持。
V4L定义了在linux下进行图像采集的接口函数。主要有设备的open、close、read、write、ioctrl、mmap等对设备的操作方法,并通过结构体video_device_ stv680_template在内核中进行登记,方便在用户状态下进行设备的各种操作。可以以虚拟内存映射方式获取图像数据,主要是调用mmap内存映射函数stv680_mmap,其定义如下:
static int stv680_mmap (struct video_device *dev, const char *adr, unsigned long size)
在该函数中,利用系统调用remap_page_range,将物理地址pos对应的虚拟页面地址page映射到用户空间中去,从而实现了图像数据从驱动到应用程序的转移。对硬件底层的操作,集中在stv680_ioctl函数中,通过系统调用ioctrl对设备进行控制,其中包括:VIDIOCGCAP、VIDIOCSYNC等控制方式,对摄像头进行配置、同步等操作。这些控制方式都符合V4L的控制规范,可以将一般的图像采集程序不经过改动移植到这个驱动上来。
对采集上来的每一帧图像数据我们采用JPEG压缩。在实际应用中,JPEG压缩使用Arm_linux下的libjpeg库模块,该模块采用以离散余弦变换(Discrete Cosine Transform,DCT)为基础的有损压缩算法,在压缩比为25:1的情况下,压缩后还原得到的图像与原始图像相比较,非图像专家难于找出它们之间的区别。经过交叉编译后,将编译生成的库文件libjpeg.so拷贝到了sitsang板的文件系统中,从而使sitsang板支持jpeg压缩格式的图形。代码实现部分的主要流程如下:
设置压缩信息结构体struct jpeg_compress_struct cjpeg,其中保存着图像原始信息和压缩信息。其中图像大小320x240,深度为3,颜色类型为RGB.
设置图像压缩品质:jpeg_set_defaults(&cjpeg) jpeg_set_quality(&cjpeg, quality, TRUE);
设置图像压缩方法:cjpeg.dct_method = JDCT_FASTEST(使用快速离散dct变换)
开始压缩:
jpeg_start_compress(&cjpeg, TRUE);
……
jpeg_write_scanlines(&cjpeg, row_ptr, 1);
……
完成压缩:jpeg_finish_compress(&cjpeg); jpeg_destroy_compress(&cjpeg)
在图像的处理上,本文设计了简单并且行之有效的图像比较判断程序,来判断图像是否发生变化,并且只有当图像发生变换以后,系统才会自动将现场情况上报给监控主机。比较函数cmp_blks设定一个图像发生变化的极限c_limit,然后将一帧图像分割成12*12个图像块(block),对每一个block,将像素之差与c_limit进行比较,如果大于c_limit,则认为该块图像发生了变化,否则没有变化。在野外无人值守的监控环境中,根据实验和经验进行设定c_limit的值,能够合理的利用网络带宽进行传输并减少系统负担。经过概算法确定的视频变化块信息可以用于以后图像跟踪的扩展功能。
3 系统的测试与结论
通过现场安装测试,每个监视终端可以同时支持4台视频采集终端的连接与数据传输,服务器可以同时支持多达100台视频采集终端的数据转发,长时间运行效果很好。经过图像预处理、判断和压缩后,传输的数据量小,节省了网络传输带宽,适合无线网络传输。