您的当前位置:首页正文

车牌字符定位与分割系统算法设计与实现设计报告

来源:好兔宠物网


电子科技大学 通信与信息工程 学院

课 程 设 计 报 告

(实验)课程名称

车牌字符定位与分割系统算法设计与实现

电子科技大学教务处制表

电 子 科 技 大 学

设 计 报 告

学生姓名: 桂荣华 学 号: 2011019040015分工: 算法设计和编程 学生姓名: 王玉峰 学 号: 2011019040014分工: 测试车牌库 学生姓名: 李 靖 学 号: 2011019040013 分工: 撰写报告 设计时间:第 3 周 至 第 12 周 设计地点: 科B116 指导教师: 徐 进 一、 设计项目名称

车牌字符定位与分割系统算法设计与实现 二、 设计学时

32

三、 设计正文

1. 车牌识别技术的国内外现状

自1988年提出车牌识别(License Plate Recognition,LPR)技术以来,人们己经对其进行了广泛的研究,其主要途径就是对车牌的图像进行分析,自动提取车牌信息,确定汽车牌号。在车牌识别过程中,也出现了很多的技术方法,但由于外界环境光线变化、光路中有灰尘、季节环境等变化及车牌本身比较模糊等条件的影响,使得LPR系统一直是一个有解但一直不能解决得很好的问题,而且许多方法都需要大量的数值计算,并没有考虑到实时处理的环境。

车牌定位是车牌识别的第一步,车牌定位正确与否直接影响到车牌识别的后续工作,故车牌定位尤为关键。车牌字符分割是对已经定位好的(对于某些倾斜车牌还要进行倾斜校正)车牌进行处理,分割出表示车牌编号的每个字符。最后对分割出的字符进行识别输出车牌编号,完成车牌识别。

1.1 常见车牌定位技术的研究

车牌定位方法可以分为两类:基于灰度图像的车牌定位方法和基于彩色图像的车牌定位方法。在这两类方法的基础上又可以利用边缘检测、数学形态学、颜色特征提取和神经网络等方法定位车牌 1.1.1 基于灰度图像的车牌定位方法

基于灰度图像的车牌定位方法主要有:

(1)通过车牌的纹理特征定位车牌。对车牌图像水平扫描,统计车牌图像各行灰度变化的次数,通过和设定的灰度变化的次数的阈值比较,来确定车牌的位置。该方法在背景和车牌的纹理特征相似时,不能有效的定位车牌。

(2)利用 BP 神经网络定位车牌图像。该方法的主要内容是:采集部分车牌图像样本,归一化后通过神经网络对其训练。当 BP 神经网络收敛时,可得到一个对牌照敏感的神经网络。利用训练好的 BP 神经网络从整个图像中定位出车牌的区域。在图像背景复杂、车辆种类繁多以及在不同光照条件等情况下,通过该方法仍然能够准确定位车牌。该方法的主要缺点是:神经网络在学习过程中容易陷入局部最优,且在权系初值设置不恰当时会导致学习算法的收敛速度过慢。

(3)基于形态学的车牌定位算法。该方法主要包含两部分: 定位和识别。依据车牌字符的特征确定形态学基本结构元的大小和结构。然后通过在二值图像上使用开操作和闭操作来将不含有车牌信息的候选区域滤除并最终得到车牌图像。该法的主要缺点是:在不同条件下会得到不同外观特征的车牌图像,不利于确定形态学的基本结构元。 1.1.2 基于彩色图像的车牌定位方法

利用灰度图像定位车牌的算法虽然能够减少计算量,但是跟彩色图像相比,灰度图像损失了很多的视觉信息。所以彩色图像比灰度图像更有利于车牌定位,而且能够在复杂背景、不同光照条件等情况下准确定位车牌。

当前基于彩色图像的定位方法有:

(1)把 RGB 彩色空间转换到其它的彩色空间。比如:把 RGB 彩色模型转换到 HSV 模型,然后对彩色模型距离和相似度进行计算,得到车牌的候选区域,再利用车牌的纹理和几何特征从候选区域中找到最终的车牌区域。该方法的缺点是对车身和车牌颜色相近的车辆定位效果不好。

(2)利用彩色边缘定位车牌图像。通过彩色边缘检测算子得到彩色车牌图像的二值边缘图像,结合车牌图像所具有的固有特征,就可以从二值边缘图像中确定车牌的位置。

以上方法根据车牌的颜色特征能够在复杂的背景条件下准确定位车牌,具有较好的鲁棒性。但是由于彩色模型都是在三维空间上,导致算法运算量较大,从而直接影响到了车牌系统的实时性。

1.2 常见的车牌倾斜校正算法研究

1.2.1 Hough 变换

Hough 变换的基本思想是点——线的对偶性。图像变换前在图像空间,变换后在参数空间。对于图像空间中的任一点(𝑥,𝑦),利用变换𝜌=𝑥𝑐𝑜𝑠𝜃+𝑦𝑠𝑖𝑛𝜃转换到参数空间的点(𝜌,𝜃),图像空间中的任一点对应𝜌−𝜃空间中的一条正弦曲线,如图 1.1 所示。通过对车牌图像中的每个像素点在一定角度范围内进行 Hough 变换,统计出 Hough 变换后的相同的结果最多的个数对应的角度,即为车牌的倾斜角度。该方法抗噪性能较好,但是所需要的计算量相当之大,对于实时应用,需要特定的芯片来专门进行 Hough 变换,并且对于无车牌边框的图像的效果不理想。

图1.1

1.2.2 Radon 变换

平面上的函数𝑓(𝑥,𝑦)在任意角度𝜃直线上的投影定义为𝑓沿垂直该线方向上的线积分,(𝑥′,𝑦′)为(𝑥,𝑦)转过𝜃角度后的坐标,如图1.2所示。

图1.2

则 𝑓(𝑥,𝑦)的 Radon 变换公式如下:

Radon 变换检测倾斜角度的原理是:对倾斜的车牌图像在一定的倾

斜角度范围内进行Radon 变换,统计在每个角度投影后所得到的投影值为0的数目,并取数目最多所在的角度为车牌的倾斜角度。和 Hough 变换相比,Radon 变换能够快速检测到车牌的倾斜角度,而且占用的内存资源少,但是对于无边框的车牌图像,Radon 变换同样效果不理想。 1.2.3 旋转投影变换法

先对车牌图像旋转,然后对旋转后的车牌图像进行投影,把每次旋转投影的最大值作为本次的投影值。综合比较每次旋转的投影值,取最大的投影值对应的角度为倾斜角度。旋转投影变换法包括水平方向和垂直方向的投影。对于水平倾斜校正,在一定角度范围内进行水平投影,取水平投影最大值对应的

角度为水平倾斜角。对于垂直倾斜校正,先取得水平校正后的车牌图像,然后在一定角度范围内进行垂直投影,取垂直投影最大值对应的角度为垂直倾斜角。该方法的主要缺点是:需要对车牌图像进行多次旋转,计算量较大。

1.3 常见车牌字符分割算法研究

车牌字符分割就是对已经定位出的车牌区域内的车牌字符进行分割,从而获取车牌上的字符,是车牌字符识别的前提和准备。车牌字符分割的好坏,直接影响到识别效果的好坏。在车牌识别系统中,由于车牌污染、背景复杂、光照不均匀、车牌发生倾斜、边框影响以及间隔符等因素影响,很难找到一种普遍使用的分割方法。

1.3.1 基于投影的车牌分割算法

首先是对车牌区域进行投影,然后利用投影后的波峰、波谷的特性进行分割车牌字符。这种算法设计简单,执行快,便于设计和操作。该算法的缺点是,由于利用车牌的波峰、波谷信息,这就使得算法对车牌的质量要求较高,不能很好的解决字符黏贴和汉字不连通的问题。 1.3.2 基于模板匹配的字符分割算法

基于模板匹配的字符分割算法的原理是,首先设计出一个字符间隔宽度的模板和一个字符宽度的模板,然后让已设计的模板在定位出的车牌区域中移动,求取字符间隔宽度模板内的像素值之和与字符宽度模板内的像素值之和的比值,通过比值与所设定的极小值的比较来确定分割点的位置。模板匹配算法的优点是可以较好的解决字符粘连和汉字的不连通问题,执行速度也很快,受车牌图像的背景干扰小。缺点是,这种算法逻辑设计相对复杂,循环扫描执行功能较多,执行受到车牌左右边框影响较大,对左右边界的分割有待改进,并且不适合两行字符的车牌,具有局限性。 1.3.3 基于聚类分析法的字符分割算法

基于聚类分析法的字符分割算法,其核心思想是利用聚类分析理论实现对车牌字符的分割,实现同类字符的相关性尽量大、不同类字符的相关性尽量小,从而获得内在的规律。该法实现的步骤是,首先根据车牌字符的先验知识,在预处理后的车牌图像上预设7个类心。设置类心可以采取程序提示给定坐标值的方法,也可以采取给予固定坐标值的方法。可以用255表示白色点,即

车牌上的字符,用0表示黑色点,即车牌背景。然后自下向上对车牌图像进行逐行扫描,每当扫描到一个白色像素时,都要与上述每个类已获取的每个(白色)像素比较距离,找出与该像素距离最近的已获得类的像素点,且认为这两个像素属于同一类,即认为这两个像素点属于同一字符。这种算法较好的解决了字符不连通的问题,但执行起来程序逻辑复杂,执行时间相对较慢。

车牌字符分割的算法较多,常见的还有基于小波变换的车牌字符分割算法、基于连通域标记的车牌字符分割算法、基于神经网络的车牌字符分割算法等,也有学者提出将几种分割方法相结合的分割算法,这些字符分割算法针对特定的车牌都取得了不错的分割效果。

2. 本设计解决的问题

本设计拟解决在日间拍摄的我国普通小型车号牌即蓝底白字车牌的识别,且将拍摄角度倾斜,车牌污染(如掉色,关照不均等)以及拍摄背景的干扰考虑进来,力求达到较好的车牌定位和精确的字符分割。本设计测试对象为分辨率2560*1920的RGB图像,优点是清晰度较高,缺点是图像中的车牌场景拍摄角度变化大、拍摄距离远近不一、背景复杂并且干扰车辆多。

3. 本设计所采用车牌定位和分割算法思想

3.1 基于HSI彩色模型的车牌定位算法

为了更准确定位出复杂背景中各种倾斜角度的车牌,本文采用了基于彩色图像模型的车牌定位算法。算法基本思想:首先将输入的RGB图像转换为HSI分量图像,其中H为色调,S为饱和度,I为光照强度,然后筛选出色调和饱和度与车牌色彩相近的区域作为定位候选区域R。取出候选区域R的灰度图进行二值化,经过一系列形态学开闭运算,去噪声、融孔洞等,最后结合车牌字符区域垂直边缘丰富、车牌应为矩形等先验知识对候选区域R进行筛选,最终定位出车牌区域。

对于蓝色车身和蓝色车牌相近而导致的定位失败问题,本文先检测出蓝色车,提取该车的蓝色区域B和白色区域W,对B进行去噪、融孔洞等处理,然后对B进行大尺度膨胀,将膨胀后的B与W作逻辑与运算,即B & W,这一与操作可以提取出车牌字符区域,同时又去掉车牌周围的大片蓝色干扰,再对B&W进行大尺度膨胀得到候选区域R,膨胀后的效果应为B&W的字符区

域都连成一片,最后对R进行筛选。

影响本算法效果和适应性的关键在于一系列开闭运算算子的选取。由于这些算子均选用矩形算子,并且尺寸均是由统计结果或者图片本身的尺寸所决定,故本算法具有一定的适应性。对于大部分非蓝色车来说,提取出来的蓝色区域基本上只有车牌和一些小的干扰区域,而少部分蓝色车可以通过白色字符区域膨胀来定位,这使算法的准确性大大提高。关于如何检测出蓝色车可以通过蓝色区域占图像总面积的大小来判决,即使车辆旁边有蓝色物体,而车辆本身非蓝色而导致将车辆误判为蓝色区域也无所谓,因为该处理蓝色车的方法对非蓝色车同样适用。

3.2 基于Radon变换的车牌倾斜校正算法 3.2.1水平倾斜校正

为了提高Radon变换求水平倾斜角的准确性,车牌区域二值化后应该尽量保留车牌边框。根据定位算法不仅可以得到车牌区域灰度图,还可以得到车牌区域饱和度图,而部分车牌区域的灰度图二值化后会去掉边框,饱和度图二值化却能够完整保留框,故应二值化饱和度图然后进行Radon变换,求出最大投影值对应角度的余角即为倾斜角,然后将灰度二值图和饱和度二值图旋转该角度即可。

水平校正的问题在于:由于干扰的存在,Radon变化的最大值对应角度有时不是倾斜角,从而导致校正错误。这可以通过增加判断条件来提高准确率,比如该角度不仅应为Radon变换最大值对应的角度,并且该角度附近的角度Radon变换都比该角度处的Radon变换值小,否则对Radon变换次大值对应角度进行判断,直到选出正确角度为止。 3.2.2去除上下边框

由于车牌字符区域水平投影直方图会出现一段连续的、值比较大的区间,根据这一特点设定合适阈值即可确定字符区域的上下边界,从而去掉边框。

是否能够将上下边框去干净而又不会去掉字符区域的关键在于阈值的选取。同时由于某些车牌倾斜角度太大导致定位时其外接矩形会包括进大片干扰区域,而这些干扰即使在灰度图二值化之后也不能完全去掉,这就导致车牌外的区域也可能出现一段连续的、值比较大的区间,从而误判,而这可

以先通过饱和度二值图去一次边框,再通过灰度二值图再一次去边框来加以解决。

3.2.3垂直倾斜校正

对去掉上下边框后的灰度二值化图作Radon变换,求出每个角度Radon

变换的1阶导数绝对值的累加和,最大累加和对应角度即为垂直倾斜角,然后使用剪切变换进行垂直校正。

3.3 基于模板法和改进投影法的字符分割算法 我国车牌样式如下图3.1

图3.1

车牌中间有一个点作为分隔符,在点的左边有2个字符,省名+字母,而点的右边有5个字符,基本是字母和数字的组合。车牌字符的间距、宽度和高度等都用严格尺寸,这可以作为先验知识来辅助切割。

字符分割常见的问题有字符断裂,字符与字符粘连,字符与边框粘连等。比如省名中的“川”字本身就是断裂字,还有些字符本身沾污导致二值化后出现断裂等。

为了解决上述问题,在点的左边本设计采用模板法,点右边的字符采用改进后的投影法对车牌字符进行分割。算法关键如下(以“川”字为例): (1) 如何准确地识别出点,进而找出点所在的间隙区域。

(2) 一旦找出点所在的间隙,以该间隙的左边界为起点向右扫描垂直投影

值,求出第一个字母所在的位置,然后以该字母的左边界为起点,向左移动一个字符间歇的宽度即为“川”字的右边界,再向左移动一个字符宽度即为“川”字的左边界,此时点左边分割完毕。

可以看出,左边分割的很重要的前提就是要准确地估计出字符宽度wide,这可以通过对所有字符的垂直投影值来进行估计,而字符间隙宽

度可以通过wide计算出来。

(3) 对点右边的字符进行垂直投影,求出投影之大于0.1*wide的连续区间

的起始位置和宽度。

(4) 对宽度明显大于wide的区间进行判定,若判定出该区间由n个字符粘

连而形成,然后根据车牌字符宽度wide和字符间距将该区间分割成n个区间。

(5) 找出间隔小于0.1*wide的区间,这往往是二值化或阈值选取不当造成

字符小型断裂造成,应将此类区间合并。

(6) 找出区间宽度小于0.1*wide的区间,这往往是由长条形干扰或者噪声

造成的投影区间,应将此类区间清除。

(7) 找出区间宽度小于0.8*wide的区间,如果在该区间相邻区间宽度也小

于0.8*wide,并且两个区间间距不大、合并后的宽度与wide相差不远,这说明两个区间为同一个字符断裂成的两部分,那么将这两个区间合并。

(8) 经过一系列的切分、合并处理后的字符区间个数应该大于5,则从左到

右取5个字符区间即为点右边的字符区间。

此分割算法关键就是各种判别粘连和断裂的阈值选取,这要求对wide估计的精度很高。实验表明分割算法适应性强,并且不受车牌垂直边框的影响,抗字符粘连和断裂的性能好。

4. 算法详细描述

4.1 车牌定位算法(伪代码,以某蓝色车为例)

(1) 读入图片P如图4.1,将RGB分量转换为HSI分量,得到H、S、I分

量图,三个分量矩阵大小都为m×n。

(2) 提取与车牌颜色相近的蓝色区域F矩阵如图4.2:

F=Hb & Sb

1,0.55≤H≤0.75其中Hb={ ,Hb为m×n的0-1矩阵

0 , else

Sb={

1,S≥0.3 0, else

,Sb为m×n的0-1矩阵

(3) 定义结构算子全1矩阵:

S1=[1]i×j ,其中i=1/1600*sqr,j=1/80*sqr , sqr=√m2+n2,膨胀算子 S2=[1]i×j ,其中i=1/1600*sqr,j=1/160*sqr , sqr=√m2+n2,水平去噪算子 S3=[1]i×j ,其中i=1/160*sqr,j=1/1600*sqr , sqr=√m2+n2,垂直去噪算子 S4=[1]i×j ,其中i=3,j=3, 最小去噪算子

先使用S1膨胀F,再依次使用S2、S3对F进行腐蚀膨胀,完成水平去噪和垂直去噪得到F3如图4.3。

(4) if F3中非零值面积占F3总面积的比例>0.03,则判定该车为蓝色车,

跳转到(5),否则跳转到(7)。

(5) 提取字符区域F4=F3 & Sw 如图4.4,其中Sw= (S<=0.2)&( I>=0.2) ,

Sw为m×n的0-1矩阵,代表白色区域,包含字符所在的白色。

图4.1 蓝色车图

图4.2 提取该车蓝色区域F

图4.3 对蓝色区域F进行膨胀 和去噪处理后的F3

图4.4 提取车牌字符区域F4

(6) 对F4进行水平投影,根据投影直方图(如图4.5)估计出车牌高度h和车牌上下边界,然后清除上下边界以外的区域。定义膨胀算子S5=[1]i×j ,其中i=2,j=h, 使用S5对F4进行膨胀如图4.6,并将F4赋值给F3,即F3=F4。

250

2001501005000200400600800100012001400160018002000

图4.5 字符区域F4水平投影直方图

图4.6字符区域F4膨胀图

(7) 对F3进行连通区域标记,得到标记后的矩阵L和连通区域数num,同时求出P的灰度图Pg。

(8)for i=1:num

取出第i块连通区域外接矩形的灰度图pg

对pg进行ostu二值化得到二值图P2 使用S4对P2进行腐蚀膨胀完成去噪 提取P2垂直边缘sp,对sp中的1值求和 将求和结果作为第i块连通区域特征值u(i)

如果该连通区域外接矩形长宽比<1.2,则u(i)=0 end

(9)选出特征值最大的连通区域作为车牌区域,并且输出车牌区域灰度

图yg、色调图yh、饱和度图ys和亮度图yi 如图4.7

(a).灰度图 (b).色调图

(c).饱和度图

图4.7 车牌区域图

(d).亮度图

4.2 车牌倾斜校正算法(伪代码,以另外一张倾斜严重的车牌为例) 根据车牌定位的输出可以得到灰度图yg、色调图yh、饱和度图ys和亮度图yi。yg和ys如图4.8。

(1) 对yg和ys进行ostu二值化,并用3*3的全1矩阵去噪,得到Pg和

Ps,如图4.9。

(2) 对饱和度图Ps进行水平校正步骤如下(参见函数shuipingjiaozheng.m文件)

使用canny对Ps提取边缘得到边缘图bw;

对bw作0-180度的Radon变换,求出每个角度的最大变换值

作为该角度的radon变换特征值R(θ),如图4.10;

求出最大特征值max(R(θ))对应的角度θ0,若R(θ0−10) 和

R(θ0+10)都小于R(θ0),则90-θ0则为倾斜角,否则选取次大特征值进行判断,直到选出θ0。

(3) 将Pg和Ps都旋转90-θ0,得到Pgz和Psz完成水平校正如图4.11。

图4.8

120图4.9

1008060

40200020406080100120140160180200

4.3.去上下边框

图4.10 图4.11 校正完成图

由图4.11可知,饱和度图二值化之后车牌外面的干扰明显少于灰度图,因此可以先用饱和度图Psz水平投影,以最大投影值的1/4为阈值,选取大于该阈值的最长连续区间的左边界作为车牌上边界,右边界作为车牌下边界,如图4.12,然后清除Pgz上下边界外的区域,然后对Pgz作水平投影,同样求出上下边界,再次清除上下边界以外的区域,得到去边框后的Pgz如图4.13。

300250200150100500020406080100120140160180200

图4.12 水平投影直方图

图4.13 去上下边框后的图Pgz

4.4.垂直倾斜校正

(1) 对Pgz进行-30 ~ 30 度的Radon变换

(2)对每个角度的Radon变换结果分别求1阶导数绝对值的累加和 (3)具有最大累加和的角度即为垂直倾斜角beta

(4)根据beta进行affine变换(参见chuizhijiaozheng.m文件)完成垂直校正

输出校正图像J 如图4.14。

图4.14 垂直校正图J

4.5字符分割算法

(1)对J做垂直投影,求出投影值大于0的区间宽度w。J的行数为字符高度

hei,剔除w中大于hei的值,求w中最大的三个值的平均值作为字符宽度的估计值wide,若wide<0.25*hei,表明估计不当,则取w中最大值作为字符宽度估计值wide。

(2)对于(1)中得到的投影值大于0的区间宽度w,找出区间宽度在0.05*wide

和0.33*wide之间的区间,若该区间内的图像的高度也在0.05*wide和0.33*wide之间,并且该区间位于[2*wide, len-5*wide]之间,len为J的列数,则该区间为白点所对应的垂直投影区间,然后清除该区间内的图像即去掉白点,如果不存在这样的区间,表示白点在二值化的过程中已经被去掉。

(3)对去掉白点后的J再次进行水平投影,选取投影值为0并且在[wide,len-

5*wide]之间的最长区间作为白点所在区间,以该区间左边界为起点,向左扫描投影值,先求出大于0.1*wide的第一个区间作为第二个字符所在区间,可求出第二个字符宽度为A。该区间左边界lb-12/45*wide则为第一个字符的右边界,lb-12/45*wide-1.1*A则为第一个字符的左边界,至此左切割完毕。

(4)对白点所在区间右边界以右的图像J的所有列进行垂直投影,得到大于

0.1*wide的区间宽度w和区间起始位置。

(5)去粘连:找出区间宽度大于1.1*wide的区间进行如下判断

If 该区间宽度<1.5*wide,则为字符与右边框粘连,以wide为

模板,去掉超出wide的部分

Else if 该区间宽度<2.5*wide,则为2个字符粘连,则根据wide

将区间切分为两个字符对应的区间

Else if 该区间宽度<4*wide,则为3个字符粘连,则根据wide

将区间切分为3个字符对应的区间

Else 表明至少有4个字符粘连,无法切分(因为误差变大,切

分没有意义)

(6) 去小型断裂:将(5)处理后的区间中区间间隔小于0.1*wide的区间合并 (7)去条形干扰和噪声:将(6)处理后的区间中区间宽度小于0.1*wide的区

间清除

(8)去大型断裂:(7)处理后的区间中若有两个相邻的区间宽度同时小于

0.8*wide,合并后区间宽度在0.8*wide和1.2*wide之间,并且合并后投影非零值宽度占总宽度的比例不小于0.7,则将该两个区间合并 (9)从左到右依次取出5个区间作为点右边切割的结果,连同左切割结果一

起输出作为字符分割的最终结果,分割效果如图4.15。

图4.15 垂直校正图J

四、 实验结果

本次设计选取了114张拍摄角度、拍摄距离各不相同的车辆图片, 依次对本文的定位算法、水平倾斜校正算法、去上下边框算法、垂直倾斜校正算法和字符分割算法进行测试,结果如下。

1. 车牌定位算法测试

114张测试图 数量 比例 定位成功 114 100% 定位失败 0 0 定位不完整 0 0 注:定位不完整指只定位出车牌的一部分

2. 水平倾斜校正算法测试

114张测试图 数量 比例 校正成功 113 99.12% 校正失败 1 0.88% 失败原因:失败车牌边框弯曲呈弧形,导致倾斜角算错。

3. 去上下边框算法测试

114张测试图 数量 比例 恰好去掉边框 112 98.25% 边框未去干净 1 0.875% 字符被去掉一部分 1 0.875% 原因分析:有一张边框未去干净是因为字符和边框实在粘连太紧,但是并没有影响后续字符分割;另一张字符被去掉一部分的图是因为该图水平倾斜校正不成功导致的,但是最后还是将其分割出来了。

4. 垂直校正算法测试

114张测试图 数量 比例 校正成功 114 100% 校正失败 0 0

5. 字符分割算法测试

114张测试图 数量 比例 分割成功 111 97.4% 分割失败 2 1.75% 分割不完美 1 0.85% 原因分析:第一张分割失败是由于定位出来的图像二值化失败导致切割失败;第二张分割失败则是由照片本身只拍摄了一半的车牌,与算法无关;而分割不完美还是由于那张倾斜车牌图水平校正不成功导致的。

二值化失败,但是倾斜校正仍然成功

车牌本身只拍摄了一半,与算法无关

水平校正不成功,导正去边框时字符被削掉,分

割不完美。 五、 设计结论

由于影响车牌识别的因素多种多样,因此很难找到一种万能的算法适应各种环境。每种算法都有其优缺点,单独采取某种算法很难取得好的效果,此时应该结合多种算法,取长补短提升识别率。

本设计定位算法采用HIS彩色模型提取候选区域,灵活使用形态学中开闭运算,使用垂直边缘来定位车牌区域,这对大部分非蓝色车的定位准确率接近100%,再检测出蓝色车,对蓝色车使用白色字符区域进行膨胀得到候选区域,这有效地解决了蓝色车身的干扰,大大提升蓝色车车牌的定位率,使总定位成功率接近100%。然后采用Radon变换进行水平倾斜校正和垂直倾斜校正,并分别使用灰度图和饱和度图进行二次去边框,最后字符分割算法结合了模板匹配和投影法,并对现有投影法进行改进,在投影上作一系列切分合并操作,大大提升了字符分割的成功率。正是各种方法的综合才带来最后良好的分割效果,每一步都必须做到最好,最后的结果才能最好。

六、 设计心得

1. 2. 3.

算法的阈值最好是根据统计结果来确定,这样算法的适应性才能更强。 单独采用某一种算法效果不好时,可以结合多种算法试试。

在吸收别人优秀成果之后自己更容易创造出更好的东西,交流能激发新的想法。 4.

车牌识别分为几步,前面每一步的效果都会影响后续字符切分的成功率, 只有每一步都做到最好才能保证最终结果好。

七、 参考文献

[1] 申继龙.车牌定位和倾斜校正的关键技术研究[D].南京邮电大

学.2013:1-51.

[2] 郭亚,王水波.基于灰度图像的车牌定位算法研究与实现[J].现代电子

技术, 2008(2):137-139.

[3] 杨海廷.基于纹理特征的车牌识别系统的研究与实现[D].电子科技大

学.2005:1-77.

[4] 王梅,王国宏.利用伴生与互补颜色特征的车牌定位新方法[J].计算机

工程与应用,2007,43(1):206-211.

[5] 郑成勇.一种RGB颜色空间中的车牌定位新方法[J].中国图像图形学报,

2010,15(11):1623-1628.

[6] 凌佳宁.车牌定位与车牌字符识别算法的研究与实现[D].电子科技大

学.2012:1-69.

[7] 徐勤燕.复杂背景中基于纹理和颜色的车牌定位研究[D].东华大

学.2013:1-54.

[8] 陈昌涛.基于彩色和黑白纹理分析的车牌定位方法[D].重庆大

学.2008:1-54.

[9] 刘同焰.车牌识别系统的相关算法研究与实现[D].华南理工大

学.2012:1-70.

[10] 黄山.车牌识别技术的研究和实现[D].四川大学.2005:1-164. [11] 王传丽.车牌识别关键技术研究[D].山东理工大学.2012:1-84.

[12] 贡丽霞,白艳萍.Radon变换在倾斜车牌图像校正中的应用[J].测试技术

学报,2009,23(5):452-456.

[13] 贾晓丹,李文举,王海姣.一中新的基于Radon变换的车牌倾斜校正方法

[D].辽宁师范大学计算机与信息技术学院.

[14] 吴一全,丁坚.投影点坐标方差最小化车牌垂直倾斜校正[J].应用科学

学报,2009,27(2):177-181.

[15] 潘中杰,谭洪舟.模板匹配法和垂直投影法相结合的一种新的车牌字符

分割方法[J].自动化与信息工程,2007(2):13-34.

八、程序代码

主函数ReadFileAll.m

% read all files(*.bmp,*.jpeg,*.jpg) from a dir %

%function [FileNum] = ReadFileAll('E:\\车牌识别\\') clear all;close all

filetype = char('*.bmp', '*.JPEG', '*.jpg'); filedir = 'E:\\车牌识别\\'; for ii = 1:size(filetype,1)

filedirpath = [filedir filetype(ii,:)]; dirs=dir(filedirpath); if size(dirs,1) > 0

for jj = 1:size(dirs,1) %figure(1);

filename = dirs(jj).name;

im = imread([filedir filename]); %imshow(im);

%title('The Original License Plate Image.');

%figure(10); %(mod(jj,3)+10-1); imw = 200; imh = 40; imwc = 30; imhc = 40;

[LPLocim, LPLocbw,pg,ps,ext] = LicPlateLoc(im, imw, imh); if ext==1

disp(name)

disp('cant be located') continue end

[LPSegim, LPSegbw] = LicPlateSeg(pg,ps, imwc, imhc); figure(jj)

subplot(221);imshow(LPLocim); title('The Located License Plate Image.');

subplot(223);imshow(LPLocbw); title('The Located License Plate Binary Image.');

subplot(222);imshow(LPSegim); title('The Segmented License Plate Image.');

subplot(224);imshow(LPSegbw); title('The Segmented License Plate Binary Image.');

disp(['The Processed Results of Number ' num2str(jj) ' Image']); %pause; disp('...'); end end end

定位函数LicPlateLoc

function [LPLocim, LPLocbw,pg,ps,ext] = LicPlateLoc(image, imw, imh)%不包含倾斜度校正

% image:输入的待定位的车牌图像; % imw:定位后输出车牌图像的宽度; % imh:定位后输出车牌图像的高度;

% LPLocim:定位后输出的彩色车牌区域图像;

% LPLocbw:定位后输出的二值化车牌区域图像(字符为白色1,背景为黑色0);

%imh=100; %imw=500;

%image=imread('pic114.jpg'); P=image;%读图

Phsi=rgb2hsi(P);% RGB 转 HSI H=Phsi(:,:,1); S=Phsi(:,:,2); I=Phsi(:,:,3); [m,n]=size(H); Hb=zeros(m,n); Sb=zeros(m,n);

Hb(H<=0.75 & H>=0.55)=1;%蓝色调区域

Sb(S>=0.3)=1;%色饱和度与车牌蓝色相近的区域 F=Hb & Sb;%车牌候选区域 Sw=zeros(m,n);

Sw(S<=0.2& I>=0.2)=1;%白色区域 sqr=sqrt(m^2+n^2);

%%%%以上阈值基本固定

S1=ones(round(1/1600*sqr),round(1/80*sqr));%膨胀算子

S2=ones(round(1/1600*sqr),round(1/160*sqr));S3=ones(round(1/160*sqr),round(1/1600*sqr));%水平和垂直去噪算子

S4=ones(3,3);%最小去噪算子 F1=imdilate(F,S1);%膨胀

F2=imdilate(imerode(F1,S2),S2);%水平去噪 F3=imdilate(imerode(F2,S3),S3);%垂直去噪

if sum(sum(F))/(m*n)>0.03%如果车身为蓝色则根据车牌字符定位 F4=F3&Sw;%提取字符区域

noise=ones(floor(1/800*sqr),floor(1/800*sqr));%噪声算子 F4=imdilate(imerode(F4,noise),noise);%去小噪点 prj_h=sum(F4,2)';%行投影

maxprj=find(prj_h==max(prj_h));%行投影最大值所在位置 maxprj=maxprj(1);%如果有多个最大值则取第一个 avg=sum(prj_h)/sum((prj_h>0));%求阈值

[st,ed]=qiulianxu(prj_h,ceil(avg),0);%求大于阈值连续区间的起始和结束位置

k=sum(st<=maxprj);%行投影最大的区间就是字符所在的行(字符的行投影最大)

hz=ed(k)-st(k);%求字符高度

F4([1:st(k)-ceil(0.5*hz)],:)=0;%去掉非字符区域,0.5*hz为保持冗余 F4([ed(k)+ceil(0.5*hz):end],:)=0;

Ft=imdilate(F4,ones(2,hz)) & F3;%膨胀导致车牌字符区糊成一片,并与F3相与去掉干扰区域

Ft2=imdilate(imerode(Ft,S2),S2);%水平去噪 Ft3=imdilate(imerode(Ft2,S3),S3);%垂直去噪 F3=Ft3; end

[L,num]=bwlabel(F3);%标记 Pg=rgb2gray(P);%灰度图 u=[];%灰度变化值

for i=1:num%对每一块候选区进行检验 [II,JJ,KK]=find(L==i); x1=min(II); x2=max(II); y1=min(JJ); y2=max(JJ); w=y2-y1; h=x2-x1;

if w/h<1.2 %若宽高比小于1.2 或大于5 则淘汰该区域,即u=0 u(i)=0; continue; end

pg=Pg([x1:x2],[y1:y2]);%取出候选区

P2=im2bw(pg,graythresh(pg));%ostu二值化 P2=imdilate(imerode(P2,S4),S4);%去噪

sp=abs(P2(:,2:end)-P2(:,1:end-1));%提取垂直边缘 u(i)=sum(sum(sp));%灰度变化值之和 end

No=find(u==max(u));%灰度变化最大的为候选区 ext=0;

if isempty(No) ext=1;

return end

No=No(1);%若有多个则取第一个 [II,JJ,KK]=find(L==No); x1=min(II); x2=max(II); y1=min(JJ); y2=max(JJ);

pg=Pg([x1:x2],[y1:y2]); ph=H([x1:x2],[y1:y2]); ps=S([x1:x2],[y1:y2]);

LPLocim=imresize(image([x1:x2],[y1:y2],:),[imh,imw]);%取彩色图像 LPLocbw=imresize(im2bw(pg,graythresh(pg)),[imh,imw]);%灰度图二值化 %subplot(1,2,1),imshow(LPLocim); %subplot(1,2,2),imshow(LPLocbw); end

字符分割函数LicPlateSeg

% 车牌定位图像的分割图像

function [LPSegim, LPSegbw] = LicPlateSeg(pg,ps, imwc, imhc) % LPLocim:定位后输出的彩色车牌区域图像;

% LPLocbw:定位后输出的二值化车牌区域图像(字符为白色1,背景为黑色0);

% imwc:分割后输出字符图像宽度; % imhc:分割后输出字符图像高度;

% LPSegim:分割后输出的彩色车牌分割字符图像;

% LPSegbw:分割后输出的二值化车牌分割字符图像(字符为白色1,背景为黑色0);

Pg=im2bw(pg,graythresh(pg));

Ps=im2bw(ps,graythresh(ps));%饱和度图二值化

Pg=imdilate(imerode(Pg,ones(3,3)),ones(3,3));%饱和度图去噪 Ps=imdilate(imerode(Ps,ones(3,3)),ones(3,3));%饱和度图去噪 [Psz,alfa]=shuipingjiaozheng(Ps);%饱和度图水平校正 Pgz=imrotate(Pg,alfa,'bilinear','crop');%灰度图水平校正

[st,ed]=qubiankuang(Psz);%对饱和度图求上下边框,阈值为50,输出上界st和下界ed

Pgz(1:st,:)=0;Pgz(ed:end,:)=0;%清除上下边框

Pgz=imerode(Pgz,ones(2,2));%腐蚀灰度图尽量去掉边框和字符的粘连

[st,ed]=qubiankuang(Pgz);%对灰度图求上下边框,阈值为40,输出上界和下界

Pgz=imdilate(Pgz,ones(2,2));%膨胀灰度图

Pgz(ed+1:end,:)=[];Pgz(1:st-1,:)=[];%进一步清除上下边框

[J,beta]=chuizhijiaozheng(Pgz);%垂直校正,输出校正图像J和垂直倾角beta

[J,lb,rb]=qukongbai(J);%去掉二值图像左右两边的零区域 prj_v=sum(J);%垂直投影

[head,tail]=qiulianxu(prj_v,2,0);%求连续大于阈值的区域的起始点和结束点,阈值为2,此阈值防止噪声,但是影响不大

[hei,len]=size(J);%求车牌高度和字符长度 w=tail-head;%求连续大于阈值的区域的宽度

[wide,flag]=guji(w(2:end-1),hei); %输入区域宽度w和字符高度hei,输出字符宽度估计值,并返回是否能够进行估计的标志flag

if flag==2 | flag==3 LPSegim = J; LPSegbw = J; return end

J=qubaidian(J,w,head,tail,wide);%输入图像J,连续区域宽度向量w及起始位置head、结束位置tail,字符宽度估计值,输出去掉白点后的图像J

%subplot(2,1,1),imshow(Pg) %subplot(2,1,2),imshow(J) %%%前面已改

prj_v=sum(J);%重求垂直投影

[head,tail]=qiulianxu(prj_v,1,1);%求连续小于阈值的区域的起始点和结束点,阈值为0,此阈值影响空白区的宽度

w=tail-head;

[W,II]=sort(w,'descend');

blk=[];%blk为白点所在区域编号

for k=II(1:5)%根据连续零值最宽求白点所在区域编号 if head(k)>=1*wide & tail(k)<=len-5*wide blk=k; break; end end

if isempty(blk)

LPSegim = J; LPSegbw = J; return end

%blk为起始点向左搜索,切割出两个字符

[L1,R1,ext1]=zuoqiege(J,head(blk),wide,0.1*wide);%输入J,切割起点begin,字符宽度,阈值M,输入左边两个字符起始位置L和结束位置R

%blk为起始点向左搜索,切割出5个字符 [L2,R2,ext2]=youqiege(J,tail(blk),wide,0.1*wide);

if ext1==1 | ext2==1 LPSegim = J; LPSegbw = J; return end

L=[L1,L2]; R=[R1,R2]; W=R-L;

maxwide=max(W)+10; LPSegbw=[]; for k=1:length(L)

zifu=J(:,L(k):R(k)); wide=R(k)-L(k)+1;

vector=zeros(hei,maxwide);%字符容器,将所有字符放进此容器 vector(:,[floor(maxwide/2)-floor(wide/2):floor(maxwide/2)-floor(wide/2)+wide-1])=zifu;%填充字符间隙,防止字符变形

zifu=imresize(vector,[imhc,imwc]);%统一尺寸 LPSegbw=[LPSegbw,ones(imhc,10),zifu]; end

LPSegim = LPSegbw; LPSegbw = LPSegbw; end

%%%%%%%%%%%%定位函数和字符分割调用的小函数

function [imbw,alfa]=shuipingjiaozheng(imbw)%imbw为输入的二值化图 %imbw=Ps

bw=edge(imbw,'canny'); theta=1:180;

[R,xp]=radon(bw,theta);%radon变换 maxR=max(R);

[Rt,I]=sort(maxR,'descend'); for i=1:180

if abs(90-I(i))<=60 & maxR(I(i)-10)imbw=imrotate(imbw,alfa,'bilinear','crop');%旋转

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [st,ed]=qubiankuang(Pz) %Pz=Psz

frame=sum(Pz,2)';

thresh=round(max(frame)*0.25); flag=zeros(size(frame)); flag(frame>thresh)=1; flag=[0,flag,0];

pos=flag(2:end)-flag(1:end-1); head=find(pos==1); tail=find(pos==-1); wid=tail-head;

No=find(wid==max(wid)); st=head(No); ed=tail(No);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [J,beta]=chuizhijiaozheng(imbw)%输入二值图像,输出垂直校正图像和垂直倾角

%imbw=Pgz theta=[-30:30];

[R,xp]=radon(imbw,theta);

Rd=abs(R(2:end,:)-R(1:end-1,:)); D=sum(Rd);

beta=theta(D>=max(D));

tform = maketform('affine',[1 0 0; tan(-beta*pi/180) 1 0; 0 0 1]); J = imtransform(imbw,tform); End

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [st,ed]=qiulianxu(x,M,condition) if condition==0 xx=[0,x,0];

flag=zeros(size(xx)); flag(xx>=M)=1; else

xx=[M+1,x,M+1]; flag=zeros(size(xx)); flag(xx<=M)=1; end

pos=flag(2:end)-flag(1:end-1); st=find(pos==1); ed=find(pos==-1)-1; end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [wide,flag]=guji(w,hei) %输入区域宽度w和字符高度hei,输出字符宽度估计值,并返回是否能够进行估计的标志flag

maxwide=max(w); w(w>hei)=0;

w=sort(w,'descend'); if length(w)>=5

wide=round(sum(w(1:3))/3); if wide<0.25*hei wide=max(w); end flag=1; else

if maxwide>hei%表示车牌字符和边框粘连或边框去不掉 flag=2;

wide=floor(hei/2); else

flag=3;

wide=max(w); end end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [imbw,lb,rb]=qukongbai(imbw) [m,n]=size(imbw); j=1;

lb=0;%初始化左边界 rb=0;%初始化右边界

prj_v=sum(imbw);%求垂直投影 while(jif prj_v(j)~=0 lb=j;

elseif prj_v(j)==0 && prj_v(j+1)~=0 lb=j+1; else end end if rb==0

if prj_v(n-j+1)~=0 rb=n-j+1;

elseif prj_v(n-j+1)==0 && prj_v(n-j)~=0 rb=n-j; else end end

j=j+1; end if rbimbw(:,rb:n)=[]; end if lb>1

imbw(:,1:lb)=[]; end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function J=qubaidian(J,w,head,tail,wide)%输入图像J,连续区域宽度向量w及起始位置head、结束位置tail,字符宽度估计值,输出去掉白点后的图像J

[m,n]=size(J); point=-1;

s=zeros(size(head));

for k=find(w<=0.33*wide & w>=0.05*wide); prj_h=sum(J(:,head(k):tail(k)),2); if length(find(prj_h>0))<0.33*wide && length(find(prj_h>0))>=0.05*wide

if head(k)>=2*wide & tail(k)<=n-5*wide s(k)=w(k); end end end

if max(s)>=2

point=find(s==max(s)); point=point(1); end

if point~=-1;

J(:,head(point)-ceil(0.1*wide):tail(point)+ceil(0.1*wide))=0; end end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [L,R,ext]=zuoqiege(J,begin,wide,M)%输入J,切割起点begin,字符宽度,阈值M,输入左边两个字符起始位置L和结束位置R

%begin=head(blk) %M=5 A=[]; ext=0;

prj_v=sum(J);

prj_v(prj_v<=M)=0;

prj_v(prj_v>M)=1; j=begin; cnt=0; st=0; ed=0;

prj_v(j)=0; while(j>1)

if (st & ed) ~=0 & prj_v(j)==0 & prj_v(j-1)==1 chuanR=j; break end

if prj_v(j)==0 & prj_v(j-1)==1 cnt=cnt+1; if cnt==1; st=j; end

elseif prj_v(j)==1 & prj_v(j-1)==1 cnt=cnt+1;

if cnt>1.2*wide ed=st-wide; A=wide;

chuanR=round(ed-12/45*wide); break; end

elseif prj_v(j)==1 & prj_v(j-1)==0 if cnt>0.5*wide ed=j-1; A=cnt; cnt=0; else

cnt=cnt+1; end

elseif (prj_v(j) | prj_v(j-1)) ==0 if cnt~=0

cnt=cnt+1; end else end j=j-1; end

if isempty(A) ext=1; L=[]; R=[];

return end

chuanL=chuanR-round(A*1.1); if chuanL<1 chuanL=1; end

L=[chuanL,ed]; R=[chuanR,st];

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [L,R,ext]=youqiege(J,begin,wide,M) %begin=tail(blk); %M=0.1*wide; prj_v=[sum(J),0]; prj_v(1:begin)=0;

pos=zeros(size(prj_v)); pos(prj_v>=M)=1;

pos=pos(2:end)-pos(1:end-1); headR=find(pos==1)+1; tailR=find(pos==-1); wR=tailR-headR;

K=find(wR>=1.1*wide); for j=K

if wR(j)<1.5*wide

tailR(j)=headR(j)+wide; elseif wR(j)<2.5*wide

newtail=headR(j)+wide; newhead=tailR(j)-wide; headR=[headR,newhead]; tailR=[tailR,tailR(j)]; tailR(j)=newtail; elseif wR(j)<4*wide

newtail=[headR(j)+wide,tailR(j)-wide-round(12/45*wide)]; newhead=[headR(j)+wide+round(12/45*wide),tailR(j)-wide]; headR=[headR,newhead];

tailR=[tailR,newtail(2),tailR(j)]; tailR(j)=newtail(1); else end end

headR=sort(headR); tailR=sort(tailR);

len=length(headR(1:end-1));

line(1:2:2*len-1)=headR(1:end-1);flag(1:2:2*len-1)=1; line(2:2:2*len)=tailR(1:end-1);flag(2:2:2*len)=-1; for k=1:2*len-1

if flag(k)==-1 & flag(k+1)==1 & line(k+1)-line(k)<0.1*wide flag(k)=0; flag(k+1)=0; end end

line(flag==0)=[]; flag(flag==0)=[]; for k=1:length(line)-1

if flag(k)==1 & flag(k+1)==-1 & line(k+1)-line(k)<0.1*wide flag(k)=0; flag(k+1)=0; end end

line(flag==0)=[]; flag(flag==0)=[];

headR=[line(1:2:end-1),headR(end)]; tailR=[line(2:2:end),tailR(end)]; wR=tailR-headR;

cut=find(wR(1:end-1)<0.8*wide); if length(cut)>=2

for k=1:length(cut)-1

hbwide=tailR(cut(k+1))-headR(cut(k));

if cut(k)+1==cut(k+1) & hbwide>=0.8*wide & hbwide<=1.2*wide & (wR(cut(k))+wR(cut(k+1)))/hbwide>0.7

tailR(cut(k))=tailR(cut(k+1)); headR(cut(k+1))=-1; tailR(cut(k+1))=-1; end end end

headR(headR==-1)=[]; tailR(tailR==-1)=[]; if length(headR)<5 ext=1; L=[]; R=[]; else

ext=0;

L=headR(1:5); R=tailR(1:5); end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function hsi = rgb2hsi(rgb) rgb=im2double(rgb); r=rgb(:,:,1); g=rgb(:,:,2); b=rgb(:,:,3);

%Implement the conversion equations num = 0.5*((r-g)+(r-b));

den = sqrt((r-g).^2+(r-b).*(g-b)); theta=acos(num./(den+eps));

H=theta;

H(b>g)=2*pi-H(b>g); H=H/(2*pi);

num=min(min(r,g),b); den = r+g+b;

den(den==0)=eps; S=1-3.*num./den; H(S==0)=0; I=(r+g+b)/3;

%combin all three results into an hsi image hsi = cat(3,H,S,I);

因篇幅问题不能全部显示,请点此查看更多更全内容