岳枫力,马 静
(四川工商学院电子信息工程学院,四川 成都 611745)
随着电子信息技术的不断发展,车牌识别系统不断被运用与交通管理系统中。但由于传统的车牌识别系统存在成本高、难以推广等问题,导致其运用困难,为了解决这些问题,迫切需要依靠FPGA 优秀的并行处理能力和丰富的硬件资源,有效提高系统的执行效率,降低系统成本以便于广泛运用。
传统由于FPGA 可编程性和并行执行效率,以往通常被用于特定功能电路的实现。但随着新的技术要求出现,FPGA 已不再局限于传统的接口、信号处理等方面。
本次设计采用的核心处理芯片为ZYNQ-7000 系列的xc7z020clg400-2,该ZYNQ 芯片内部由PS+PL 构成;PS 部分由ARM 的A9 双核构成,PL 部分为FPGA逻辑电路。通过芯片内部架构可知:PL 与PS 通过EMIO、DMA、32b GP AXI Port、HP AXI Port 等接口实现数据交互,PS 部分与外围电路交互则通过GPIO或EMIO;需要注意的是,EMIO 不仅可以将PS 连接到PL 的硬件资源也可以将其直接连接到PL 的输出管脚。ZYNQ 系列的接口分为MIO 与EMIO,Xilinx 在Vivado中定义了每个MIO 管脚可以通过复用实现多种功能,但是具体实现什么功能则由外围硬件电路决定。本设计使用1Gb DDR3 内存空间,芯片为NT5CB256M16EPDI。
采用OV7725 摄像头进行车牌图像的拍摄,OV7725 是一种低电压的CMOS 器件,其提供一个单片VGA 摄像机和部分图像处理功能。OV7725 的感光阵列为640*480,最快能够实现60fps 采集,输出为RGB565 格式。OV7725 的功能和配置均由其内部的寄存器实现,相关寄存器由主机通过SCCB 对作为从机的OV7725 进行配置。OV7725 内部集成了部分图像处理的功能,包括自动曝光控制、自动增益控制和自动白平衡等。
SCCB 即串行摄像机控制总线协议通道。SCCB 有两线模式和三线模式,本设计中只对一个从机进行配置,故选择两线模式,该模式由一根串行时钟线和一根双向数据线构成。
在图像捕获阶段,本设计要求能够实现对车牌图像的拍摄、保存;同时为了方便图像的捕获,摄像头所捕获的实时画面应当显示在屏幕上,起到摄像头监视器的作用。
由于摄像头和屏幕之间数据传输存在速率差,因此采用VDMA IP 核进行数据缓冲防止出现画面撕裂。VDMA 可以方便的提供双缓冲和多缓冲机制。
本次设计采用Dynamic Genlock 模式,在此模式下VDMA 有多个缓存帧,主机和从机按顺序写或读缓存帧,当从机操作某一缓存帧时,主机会跳过该帧而写操作其他帧,从而实现让图像数据缓冲的IP 核。DMA 数据接口可以分为读、写通道,用户可以通过写通道将AXI-Stream 类型的数据流写入DDR3,通过读通道可以从DDR3 读取数据,并以AXI-Stream 类型输出。
由OV7725 摄像头采集得到的图像数据通过AXIStream to video in IP 核转化成为AXI-Stream 格式数据,并传输给VDMA IP 核,同时rgb2lcd ip 核通过AXI-Stream to Video Out IP 核通过AXI-Stream通道从VDMA 读取图像并转换为RGB 格式数据输出并显示。
视频流数据经过 Video in to AXI4-Stream IP 核转换成 AXI4-Stream IP 格式数据流, 然后通过 VDMA 的写通道转成 AXI4 Memory Map 格式,并最终写入 DDR 内存中。VDMA 从 DDR3 中读取的视频或图像数据传输给 AXI4-Stream to Video Out IP 核。AXI4-Stream to Video Out IP 核在 VTC IP 核的控制下,把 AXI4-Stream 格式的数据转换成视频输出的数据格式(如 RGB888),并将输出的视频数据流连接至 rgb2lcd IP 核的输入端(rgb2lcd)。rgb2lcd IP 核实现了获取 LCD 屏的 ID 功能和以及将 LCD 屏的引脚封装到总线接口上,以方便将LCD引脚引出至顶层模块端口上。
本设计采用PS 控制VDMA IP 核以实现图像的拍摄,当按键按下后,作为从机的PS 端暂停VDMA 从机读操作,并从当前读操作执行的缓存帧中拷贝当前的图像数据以实现拍照功能。当拷贝完成后,恢复读操作。本次设计中,所有存储空间均在DDR3 空间内划分。其中,DDR 地址0x1100000 为捕获图片的缓存地址, 0x01000000 以下的地址用作PS、PL 程序执行所占用地址。
由于本设计采用OV7725 摄像头,其拍摄输出图像为上下镜像的图片,在进行下一步处理前需要对其进行镜像处理使图像回正。
(1)灰度处理
灰度是指黑白图像中的颜色深度,范围一般0-255,白色为255,黑色为0。使用灰度对彩色图像进行处理,可以得到高质量黑白图,与彩色图像相对比,灰度图像由于其不含有色相其细节度往往高于RGB 图片。在本次设计中采用移位法得到Gray 值,将原来的RGB 中的三个通道的值统一用Gray 替换,将RGB 888 图像转换为灰度图像。
(2)OTSU 算法
OTSU 算法又称“大津法”,这是一种用于确定二值化图像分割阈值的算法,利用此算法可以实现对二值化最佳阈值的自适应计算,经此算法计算得到的二值化阈值可以在一定程度上排除环境、镜头畸变带来的影响[1]。
其实现步骤为:首先对完成灰度处理的图像的每个像素进行遍历,统计每个灰度级的素数数量,并计算其所占总像素的比例。再进行灰度级的遍历,计算其中前景和背景部分的灰度均值,将其带入类间方差公式得到类间方差最大值并得到对应的灰度级,这里得到的灰度级即为阈值。
依照此阈值对灰度处理后的图像进行遍历操作,当RGB 通道中任意值大于阈值乘0.9,则对其进行填充0xffffff,否则对其填充0x000000。这里乘0.9 是为了进一步调整图像的阈值,从而排除由于OV7725是鱼眼镜头而产生畸变导致亮度变化而出现的误差。
(3)腐蚀膨胀
本设计中,对二值化后的图像去除周围边框后进行扫描,本设计中每一个像素的DDR 地址组成为:基底地址+长*宽*3,对每一个像素周围八个像素进行扫描即对(长-1)*宽*3、(长+1)*宽*3、(长-1)* (宽-1)*3、(长-1)* (宽+1)*3、(长+1)* (宽-1)*3、(长+1)* (宽+1)*3、长*(宽-1)*3、长*(宽+1)*3 八个像素进行扫描,每当任意一个像素值为0x000000,则对中心像素赋值为0x000000;同理膨胀算法对同样八个像素点进行扫描出现0xffffff 则为中心像素复制为0xffffff。需要注意的是,赋值和扫描应该在两个图像相同,不同基底地址的图片上分别进行。
(4)开运算和闭运算
开运算可以在保证基本形状和位置不变的前提下,除去孤立的点、毛刺、小桥,而膨胀腐蚀算法中的扫描的结构体大小将影响开运算的效果。闭运算可以在保证基本形状和位置不变的前提下除去图像中的小孔、弥合裂缝,同开运算一样,膨胀腐蚀算法中的扫描的结构体大小[2]将会影响闭运算效果。
本设计中采用开闭运算相结合的方式对图像进行处理,利用这种方式可以实现在保证图像形态不发生改变的前提下滤除尖刺、孤点等干扰。
(5)投影
对于完成定位的图像,在定位区间内,对其进行水平和垂直投影。由于本设计在二值化时将车牌的背景处理为黑色,字符处理为白色,且需要对字符进行定位处理,故在这里统计白色数量并生成直方图。在定位得到的区间内对图像进行行遍历和列遍历,当出现白色像素时计数器加1,最终得到每行白色像素数量的数组和每列白色像素数量的数组,这两个数组分别为二值化图像在水平方向和垂直方向上的投影。
(6)分割
对于完成投影后的图像,根据一定阈值可以对每个字符所在的位置进行大致定位。通过对水平投影的分割和垂直投影的分割的叠加,可以得到每个字符所处的区间,即得到每个字符的上下左右四个边框位置。
将每个字符图像复制转存到单独的DDR 空间,由于车牌的字符固定呈现矩形,为了方便缩放操作和识别处理,在这里对字符图像的宽度进行扩展,使之与字符长度一致,并填充黑色像素,使缩放前字符图像成正方形。
本设计中采用神经网络进行车牌字符的识别,其主要由:训练模型、识别、softmax 几个步骤组成。
本设计中采用全连接神经网络,该网络是使用矩阵乘法的三层神经网络,其输入层为28*28*1,即784*1 的矩阵,权重矩阵一为784*100 的矩阵,权重矩阵二为100*64 的矩阵。本设计中需要将该模型的权重参数即相关计算在FPGA 上实现。训练模型时,更新权重参数采用反向传播算法,反向传播算法又称为BP 算法[3],运算如式4.1-1:
ΔWj,k = α·Ek·Ok(1-Ok)·O djT(式4.1-1)
其中α 是学习效率,ΔWj,k 是权重的改变量,j 和k 是权重矩阵的行和列,Ek 是每一行的识别误差,Ok 为S 函数。
(1)模型建立
利用jupyter 平台及python 语言搭建训练模型,两个权重矩阵,分别为784*100 和100*64。
该模型是一个可以自由调节各层大小的简单三层神经网络训练模型,在该模型中,可以设定输入层、隐藏层、输出层的大小;可以设定学习率;该模型的学习机制为:模型对某一图案与第一层权重参数进行矩阵乘法运算、完成后再与第二层权重矩阵进行矩阵乘法运算,然后输出到输出层,即各种情况的可能性,由模型读取训练集中的结论判断正确与否,并将相应的权重改变依据反向传播算法传导到每个权重矩阵。至此完成了一次训练。
(2)训练模型
当进行训练的时候,函数会将训练集里存放的图像列表转置为矩阵数组,再将目标矩阵的列表也转置为矩阵数组。将图像矩阵与权重矩阵一进行矩阵乘法得到隐藏层。将隐藏层执行S 函数进行归一化,再将隐藏层与权重矩阵二进行矩阵乘法得到输出层。将输出层再次执行S 函数进行归一化,此时,函数会将输出层的结论与目标矩阵数组中的数据进行对比,得到误差值。利用BP 反向传到公式将误差传导回去以改变两层权重矩阵。
(3)测试模型
当进行识别操作时,模型会将输入的图像数据与两层权重矩阵进行矩阵乘法,同时分别利用S 函数进行归一化处理,最终得到每种情况的概率。通过对比即可得到输入图像数据所对应的索引值。
将训练的权重参数经过量化生成为coe 文件,创建ROM IP 核并导入。FPGA 每次从DDR 内读取一个像素的数据,参与运算。每个像素数据与第一权重矩阵的对应行相乘加,循环784 次得到一张图像与第一隐藏层的运算结果[4],将第一次的运算结果在与第二隐藏层进行类似的乘加运算得到最终输出权重,运算得到图像对应的概率。
图像识别部分在完成全连接计算的操作后,将图像数据存放于固定的寄存器,并拉高完成信号。识别系统在检测到完成信号拉高后,对全连接计算后得到的概率进行softmax 处理。所谓softmax,即对输出层输出的各种结果的概率进行对比,其中概率最大所对应的索引,即为本次识别的字符所对应的索引。将对应的结果保存,再将索引与分类类别进行映射,当系统完成所有字符处理后通过屏幕,利用PL 部分对识别结果进行显示。
通过拍摄车牌,可以看见成像出现模糊现象,这是由于摄像头焦距不对导致的,如图1 所示:
图1 屏幕显示画面
将OV7725 的镜头固定螺丝扭松,旋转调节OV7725 镜头到合适的焦距,使得画面清晰不模糊。
硬件环境测试通过后对拍摄功能进行测试,测试流程如下:程序上电,等待硬件初始化完成屏幕显示画面,按下图像捕获按键,等待串口打印完成拍摄信息,查看写入内存卡的图像信息,如图2 所示:
图2 写入内存卡信息打印
将存放于SD 卡中的BMP 格式图片去除查看,由于OV7725 摄像头CMOS 与电路结构所导致OV7725 成像为镜像,如图3 所示,对其进行镜像处理,使其变为正向。
图3 内存卡保存的BMP 图片
完成打印后需要对图像进行灰度及二值化处理,由于OV7725 为鱼眼镜头,会导致成像出现畸变,对灰度处理后的图像直接进行二值化处会导致图像的背景噪声干扰二值化,而影响图像定位,如图4 所示:
图4 灰度处理图片
可以看见直接进行二值化处理,即使通过腐蚀膨胀也会很容易干扰定位,如图5 所示,可以看见在车牌以外的地方即箭头指向处存在黑色区块:
图5 直接二值化后存在黑色像素块干扰
通过OTSU 算法,寻找合适的二值化处理阈值,利用OTSU 得到的阈值进行二值化处理可以看到干扰基本没有了,如图6 所示:
图6 利用OTSU 算法后二值化
通过对黑色像素的定位可以实现车牌的基本定位,如图7 所示:
图7 车牌定位
利用水平投影和垂直投影对字符进行分割,其投影图如图8 所示:
图8 水平投影
字符分割结果如下,可以看见基本实现字符的分割处理,如图9 所示:
图9 水平分割
FPGA 由于其本身的并行运算机制和其丰富的硬件资源,配合新兴技术往往可以在很多传统领域发挥出全新的作用。在本次设计的车牌识别领域,利用新兴技术及算法可以实现车牌识别系统的小型化,易于迭代、成本低、易于推广、算法便于更新。