系统硬件的微处理器采用三星公司的S3C2440A处理器,该处理器内含一个ARM920T内核,标准工作频率为400 MHz,内嵌丰富的外围设备,片外扩展64 MB的Nandflash(型号:K9F1208D0A)和2片32 MB的SDRAM(型号为HY57V561620);摄像头采用基于ZC301器件的奥尼S888,采用CMOS感光器件,48万像素,最大分辨率为800×600,需要单独安装驱动程序。GPRS模块采用华为公司的GTM900双频段GSM/GPRS无线模块,它支持标准的AT命令及增强AT命令,内嵌TCP/IP协议,工作频段为800 MHz/900 MHz/1 800 MHz/850 MHz/1 900 MHz。本系统采用RS232串口与S3C2440相连,SIM卡电压为3 V。
底层软件由BootLoader(vivi)、嵌入式Linux内核(版本为2.6.17)、设备驱动程序、文件系统组成。在内核配置中,需要添加对视频设备编程接口的支持,配置菜单路径选择Device Drivers->Multimedia device->Video for linux。
应用软件主要包括数据采集、运动检测和图像传输三部分。
2 应用软件设计
2.1 基本流程
应用软件的核心模块包括图像采集模块、运动检测模块和GPRS无线数据传输模块。首先图像采集模块用USB摄像头采集分辨率为320×240的图像,然后运动检测模块采用改进的帧差法对采集到的图像进行运动检测。如果运动检测模块检测出监控区域内有运动物体,则将有物体运动的图像添加到图像发送队列,并唤醒GPRS数据传输线程,将队列中的图像发送至监控中心。当图像发送队列中的图像全部被发送出去后,GPRS数据传输线程将置于休眠状态。
2.2 Video4Linux的图像采集
Video4Linux是Linux中关于视频设备的内核驱动,它为针对视频设备(常见的电视捕获卡及USB口的摄像头)的应用程序编程提供一系列接口函数,同时也提供无线电通信和文字电视广播解码和垂直消隐的数据接口[2]。本文主要针对USB摄像头设备文件/dev/video0进行图像采集方面的程序设计。下面介绍主要步骤及部分代码:
(1)打开视频设备
int fd; //为视频设备的文件描述符
fd=(open(“dev/video0”,O_RDWR));
if(fd<0){ //打开失败
printf(“No Camera found!n”);
exit(-1);
}
(2)读取设备信息
ioctl函数将摄像头的信息存放到结构videocap中,摄像头信息主要包含名称、类型、通道数、图像宽度、图像高度等。
struct video_capability videocap;
if(ioctl (fd,VIDIOCGCAP,&videocap) == -1){
printf(″Couldn′t get videodevice capability″);
exit(-1);
}
(3)更改设备当前设置
设置图像帧的属性,将需要设置的属性保存在结构体videopict中,主要包含图像亮度、色彩、对比度、调色板参数等。
if (ioctl (fd,VIDIOCSPICT,&videopict) < 0){
printf(″Couldnt set videopict params with VIDIOCSPICT″);
exit(-1);
}
(4)图像采集
图像采集主要有2种方式:read()直接读取和mmap()内存映射。本系统采用mmap()内存映射方式。
vmmap.height=240;
vmmap.width=320;
vmmap.format=vd-> VIDEO_PALETTE_JPEG;
ioctl (vd->fd,VIDIOCMCAPTURE,&(vd->vmmap);
ioctl (vd->fd,VIDIOCSYNC,0);
pFramebuffer=(unsigned char*) mmap(0,vd->videombuf.size,
PROT_READ | PROT_WRITE,MAP_SHARED,vd->fd,0);
第一个ioctl()设置了采集的图像大小为320×240,图像格式为JPEG;第二个ioctl()设置为单帧采集,再用mmap()函数将图像数据映射到pFramebuffer指针所指的内存中。
2.3 运动检测
采集到监控图像之后,就可进行运动检测了。视频图像处理中,运动目标检测方法主要有背景差分法、帧差法和光流法。本系统采用帧差法。其原理是:当监控区域内有物体运动时,在采集的图像帧中,对应区域的像素值会发生明显变化,这时只需将两帧差分,得到两帧图像亮度差的绝对值。如果绝对值比所设定的阈值大,则区域内存在运动物体;反之,则不存在运动物体。用公式表达如下[3]: