徐弘扬
(合肥工业大学 计算机与信息学院,安徽 合肥 230009)
摘要:系统以三星处理器S3C6410为硬件平台,Linux操作系统为软件平台,利用OpenCV视觉算法库和交叉编译环境,在ARM平台上进行图像处理与车牌识别,并完成了SD卡模块、网络模块和图像采集模块的驱动开发。针对在ARM平台上处理数字图像数据量大、耗时长的情况,提出了多线程处理模式和中断线程化方法,极大地提高了系统的实时性。
关键词:嵌入式Linux;OpenCV;车牌识别;多线程;中断线程化
0引言
与基于X86平台的传统图像处理系统相比,嵌入式系统具有专用性强、处理速度快、软硬件可裁剪等优点[1]。本文基于ARM平台和OpenCV视觉算法库,采用多线程处理模式和中断线程化方法,实现对车牌图像的快速处理与识别。
1系统总体设计
本系统主要由S3C6410处理器、图像采集模块、红外对射模块、SD卡模块和网络通信模块组成。总体结构框图如图1所示。
红外对射模块检测等待区是否有车辆,如有车辆停放,发送信号给处理器,并启动摄像头采集图像[2];SD卡模块用于存放车牌字符的模板库,处理器识别出车牌号并与SD卡中的字符模板进行匹配;网络通信模块将车辆图像信息直接上传给服务器。
2Linux平台搭建
2.1OpenCV移植
考虑到图像处理算法设计难度大、开发周期长、代码效率低等问题,本系统在Linux开发环境下,调用成熟高效的OpenCV函数库,利用交叉编译,生成在目标机上可运行的代码。
(1)安装OpenCV依赖库
OpenCV依赖于libpng、libjpeg、libstdcpp、libpthread等库,而这些库又依赖于其他一些库文件,所有需依赖的库都要编译安装。
(2)配置OpenCV
进入OpenCV根目录,运行./config,对OpenCV进行配置:--host=arm-linux指定交叉编译为ARM平台;--enablestatic表示生成静态库。
2.2-Uboot移植
Bootloader是系统上电/复位后,内核启动程序之前的一小段代码,其功能是初始化硬件设备,并将操作系统内核装载到RAM中运行。U-boot作为一个主流、通用的Bootloader,被成功移植到包括PowerPC、ARM、X86、MIPS等多种体系结构的处理器上。
2.2.1网卡驱动移植
系统采用DM9000网卡控制器进行网络通信,所以需要在板级配置文件My6410.h中屏蔽掉原有的cs8900配置,并添加对DM9000的支持。
要使挂接在BANK1上的DM9000正常工作,需要配置SROM控制器相关的寄存器。在板级初始化文件My6410.c中,添加DM9000初始化函数dm9000_init(),并修改寄存器SROM_BCn相应位值。
#define DM9000_Tacs0x2/*2clk
#define DM9000_Tcos0x1/*0clk
#define DM9000_Tacc0x1/*2clk
#define DM9000_Tcoh0x0/*0clk
#define DM9000_Tcah0x2/*2clk
#define DM9000_Tacp0x2/*2clk
#define DM9000_PMC0x0/*1data
2.2.2SD卡驱动移植
U-boot中并没有实现针对S3C6410 SD/MMC控制器的驱动程序,需要自行添加代码,实现SD卡的初始化、命令处理、块设备读等操作。
驱动文件sd_driver.c中,函数sd_init()实现SD卡初始化,它首先对SD/MMC主控制器时钟、中断等进行初始化,然后通过主控制器向SD卡发送命令,命令操作通过函数sd_cmd()实现。SD卡读操作函数sd_read用于从SD卡中将源地址从src开始,大小为size的数据读取到dst指定的地址中。sd_read函数原型为:
sd_read(src,dst,blkcnt *sd_block_size)
2.2.3USB驱动移植
本系统采用USB接口的图像采集模块,为使该模块正常工作,需要移植USB驱动。U-boot中已经实现了较完整的主机OHCI驱动,但没有USB设备驱动的代码,所以需要添加这部分代码。
在板级配置文件My6410.h中进行相应配置,使U-boot支持USB设备驱动、USB主机驱动及命令和USB存储设备,并在include/s3c6410.h中完善对S3C6410 USB OTG控制器寄存器的定义。
3车辆图像处理
对于摄像头采集的车辆图像处理主要分为3个步骤:车牌定位、字符分割和字符识别。其中,车牌定位是整个处理过程的基础,其定位的准确与否直接影响到车牌的字符分割和识别效果。图2给出车牌定位的一般流程。
从OpenCV函数库角度来说,调用cvCvtColor函数对彩色图像进行灰度化处理;利用Soble算子对图像进行垂直方向的边缘检测;再对图像进行阈值分割,取合适的阈值,将图像转换为二值图像;为了消除图像噪声,还要对其进行滤波操作,本系统采用的是形态学滤波方法,先使用闭运算操作再使用开运算操作,两种运算都包含腐蚀与膨胀;形态学运算后得到少部分矩形区域,即为车牌的候选区域,可以使用cvFindContours函数来实现轮廓检测,然后根据我国车牌长宽比的特征,即44:14,定位车牌区域。
车牌区域提取出来后,要将车牌字符分割,由于可能存在车牌倾斜的情况,导致字符分割与识别不准确,因此要先使用Hough算法[3]对车牌进行倾斜校正,然后将车牌字符在垂直方向上投影,字符之间的间隙会在投影上产生低谷,从而实现字符分割。分割完成后,对各个字符进行识别,采用基于模板匹配的ORC算法,将字符尺寸缩放至与SD卡中存储的模板大小一致并匹配,得出最佳的匹配结果。
4系统实时性改进
本系统采用三星S3C6410处理器,该CPU基于ARM1176JZF-S内核,由8级流水线组成,主频可达522 MHz,最高可达667 MHz,但由于在ARM平台上处理数字图像数据量大、过程复杂的特点,系统实时性还有待提高。
4.1多线程处理
线程是进程的一个实体,是CPU调度和分配的基本单元,它不拥有系统资源,但可与同一进程中的其他线程共享该进程的所有资源。本系统采用多线程处理方法,主程序中创建4个线程,分别用于图像采集、图像解压、灰度化和网络通信。图像采集线程从图像传感器中读取图像信息,图像解压线程利用libjpeg库将读取到的JPEG图像转换为BMP图像,灰度化线程对得到的BMP图像进行灰度化处理,网络通信线程用于将读取到的图像发送给服务器。为此,还要创建两个FIFO,用于线程间的资源共享,第一个FIFO用来存放图像采集线程读取到的图像信息,可被图像解压线程和网络通信线程共享;第二个FIFO用来存放解压后的图像数据,用于灰度化线程的处理。这4个线程并发执行,大大提高了CPU的利用率和处理速度,便于实时控制。
得到灰度化图像之后,还需对图像进行进一步处理,如果按照“边缘检测—二值化—形态学滤波”的步骤执行,则耗时太长,不利于提高系统实时性。这里开启3个线程,分别用于边缘检测、二值化和形态学滤波。由于这3个线程执行过程中有依赖关系,因此还要创建两个FIFO,分别用于存放边缘检测后的图像数据和二值化后的图像数据。改进后的车牌定位流程图如图3所示。
4.2中断线程化
在Linux标准内核中,中断是最高优先级的执行单元,当中断触发时,内核必须立即响应中断并执行响应的中断处理程序,且不会被其他任何程序打断,这会导致实时任务得不到及时处理,如果系统IO负载严重,中断会非常频繁,实时任务很难有机会运行[4]。本系统采用中断线程化方式,为中断创建线程,中断作为内核线程被赋予相应的优先级,该优先级可以低于对实时性要求更高的任务,确保实时任务被优先快速执行,提高系统实时性[5]。
具体实现方法为:在内核初始化函数init()中调用init_hardirqs()函数,为相应中断创建一个内核线程,并分配优先级。本系统中主要有3种中断:SD卡传输中断、网络传输中断和OTG中断。
创建中断线程函数:desc->thread = kthread_create(do_irqd,desc,“IRQ %d”,irq),irq为相应中断的中断号。
当中断发生时,系统调用do_IRQ()函数,处理与架构相关的部分,然后调用_do_IRQ()函数判断中断描述符的状态字段是否包含SA_NODELAY标志,若包含则该中断已被线程化,唤醒相应的中断处理线程;反之则调用handle_IRQ_event()函数直接转入中断服务程序处理。
5结论
本系统基于Linux软件平台和ARM硬件平台,利用OpenCV视觉算法库,在嵌入式系统上实现车牌识别。该系统与基于X86平台的系统相比,实现了系统专用性、便携性等特点;与基于DSP平台的系统相比,大大降低了成本。针对ARM平台处理数字图像系统实时性不足问题,提出多线程处理和中断线程化方法,极大地提高了系统的实时性。实验结果表明,采用这种方法,从采集图像到完成识别所用时间大大减少,系统执行效率极大提高,完全能够满足实时处理数字图像的需求。
参考文献
[1] 田红鹏,焦鑫. 基于嵌入式Linux和OpenCV的车牌定位方法[J]. 计算机工程与设计,2014,35(11):39083911.
[2] 郭建,孙青,黄霞. 基于图像引导的自动导引小车系统设计[J]. 测控技术,2012,31(7):3841.
[3] MUKHOPADHYAY P,CHAUDHURI B B. A survey of Hough transform[J].Pattern Recognition,2015,48(3):9931010.
[4] 孙首昌,韩红芳,孟煜. 嵌入式Linux实时技术改进与实现[J]. 微计算机信息,2007,23(122):6768.
[5] 单承刚. 嵌入式Linux下的实时性增强方案[J]. 电子技术应用,2010,36(7):137139.