车牌识别

随着21世纪经济全球化的到来,高速度、高效率的生活节奏,使车辆普及成为必然的趋势,交通管理自动化越来越成为鱼待解决的问题。现代智能交通系统中,车辆牌照识别技术是计算机视觉与模式识别技术在交通领域应用的重要研究课题之一,是实现交通能够管理智能化的重要环节,其任务是分析、处理汽车图像,自动识别汽车牌号。LPR系统可以广泛应用于电子收费、出入控制、公路流量监控、失窃车辆查询和停车场车辆管理等需要车牌认证的场合;尤其在高速公路收费系统中,实现不停车收费提高公路系统的运行效率,系统更具有不可替代的作用

关于车牌定位系统的研究,国内外学者已经作了大量的工作,但实际效果并不是很理想,比如车牌图像的倾斜、车牌表面的污秽和磨损、光线的干扰等都是影响定位准确度的潜在因素。为此,近年来不少学者针对车牌本身的特点、车辆拍摄的不良现象及背景复杂状况,先后提出了许多有针对性的定位方法,使车牌定位在技术和方法上都有了很大的改善。然而现代化交通系统不断提高的快节奏,将对车牌定位的准确率和实时性提出更高的要求。因而进一步加深车牌定位的研究是非常有必要的。

车牌字符识别是在车牌准确定位的基础上,对车牌上的汉字、字母、数字进行有效确认的过程,其中汉字识别是一个难点,许多国外的系统也往往是因为汉字难识别而无法打入中国市场,因而探寻好的方法解决字符的识别也是至关重要的。目前已有的方法很多,但其效果与实际的要求相差的很远,难以适应现代化交通系统的高速度、快节奏的要求。因而对字符识别的进一步研究也同样具有紧迫性和必要性。车牌定位与识别方法,总体来说是图像处理技术与车牌本身特点的有机结合,当然也包括模式识别、神经网络、数学形态学、小波分析、模糊理论等知识的有效运用。一个车牌定位与识别系统基本包括:图像预处理、车牌搜索、车牌定位、车牌校正、车牌字符切分和字符识别结果的输出。本课题在对汽车图像进行细致分析的基础上,主要从实用的角度来研究车牌定位与识别的算法问题。

1.2 国内外研究现状

    从20世纪90年代初(1988年),国外的研究人员就已经开始了对(车牌识别系统)LPR系统的研究,其主要途径就是对车牌的图像进行分析,自动提取车牌信息,确定汽车牌号。在车牌识别过程中,虽然运用了很多的技术方法,但由于外界环境光线变化、光路中有灰尘、季节环境变化及车牌本身比较模糊等条件的影响,使得LPR系统一直得不到很好的应用,而且很多的方法都需要大量的数值计算,没有考虑到实时处理的要求。为了解决图像恶化的问题,目前国内外的研究机构或公司企业采取的办法是采用主动红外照明摄像或使用特殊的传感器来提高图像的质量,继而提高识别率,这样做的同时也造成了系统的投资成本过大,应用领域变小,不适合普通的推广。从20世纪90年代初,国外的研究人员就已经开始了对汽车牌照识别的研究。以色列Hi-Tech公司的See/Car System系列,香港Asia VisionTechnology公司的VECON产品,新加坡Optasia公司的VLPRS系列都是比较成熟的产品。其中VECON和VLPRS产品主要适合于香港和新加坡的车牌,Hi-Tech公司的See/CarSystem有多种变形的产品来分别适应某一个国家的车牌。See/Car Chinese系统可以对中国大陆的车牌进行识别,但都存在很大的缺陷,而且不能识别车牌中的汉字,另外日本、加拿大、德国、意大利、英国等各个西方发达国家都有适合本国车牌的识别系统。各个国家的产品虽然不同,但基本上都是基于车辆探测器的系统,设备投资巨大。国内在90年代也开始了车牌识别的研究。目前比较成熟的产品有中科院自动化研究所汉王公司的“汉王眼”,亚洲视觉科技有限公司、深圳吉通电子有限公司、中国信息产业部下属的中智交通电子有限公司等也有自己的产品,另外西安交通大学的图像处理和识别研究室、上海交通大学的计算机科学和工程系、清华大学人工智能国家重点实验室、浙江大学的自动化系等也做过类似的研究。通常处理时为了提高系统的识别率,都采用了一些硬件的探测器和其他的辅助设备[1]。

  从LPR系统的主要关键技术(车牌定位、车牌字符分割、车牌字符识别)而言,关于车牌定位的研究,国外起步比较早,现有比较好的牌照定位方法主要有J.Barros等提出的基于水平搜寻的定位方法R.Parisi等提出的基于DFT变换的频域分析方法;J.Bulas-Crue等人提出的基于扫描行的车牌提取方法。上述方法,尽管在一定的条件下能够分割出车牌,但车牌识别系统大多是利用摄像机室外拍摄汽车图像,存在许多客观的干扰,如天气、背景、车牌磨损、图像倾斜等因素,因此定位并不十分理想。90年代以来,由于交通现代化发展的需要,我国也开始对车牌定位进行了深入研究,并取得了一定的成就[18]。

国内在20世纪90年代开始对车辆牌照识别系统进行了相关的研究,上海交通大学戚飞虎提出了基于彩色分割的牌照识别方法;华中科技大学黄心汗提出了基于模板匹配和神经网络的牌照识别方法[8];西安交通大学的郑南宁等人提出了多层次纹理分析的牌照识别方法[1]。另外,清华大学的研究所也对车辆牌照识别系统进行了非常有价值的研究。牌照识别技术的研究促进了适合我国车辆牌照产品的问世,国内的牌照识别产品相继问世并且投入了使用。其中亚洲视觉生产的VECON-VIS车辆牌照识别系统、成都西图科技有限公司生产的CIAS-T2003车牌识别稽查系统、上海高德威公司的汽车牌照识别系统以及北京汉王公司的嵌入式一体化车牌辨识仪等产品牌照识别率都达到了95%以上。但是,由于车辆牌照识别受环境光线的影响比较大,识别的效果在不同的光照背景下面识别率会有所不同,因此在车辆牌照定位和识别的算法优化方面还有大量的工作要做。

车牌自动识别的过程主要分成三个步骤:车牌定位、字符分割、字符识别。目前这三

方面的研究情况大致如下:

·车牌定位

 (1)直接法:利用车牌的特征来提取车牌的方法。常用的特征有:车牌的边缘特性、投影特性、形状特性以及颜色特性等。

(2)人工神经网络方法:首先采用训练样本进行神经网络的训练,从而得到一个队牌照敏感的人工神经网络,然后利用训练好的神经网络检测汽车图像,定位车牌。

(3)数学形态学的方法:使用一定的结构元素,利用数学形态学中的开运算和闭运算来对图像进行处理,得到多个车牌可能区域,然后再处理后的图像中用过区域判别法在图像的多个车牌可能区域中找到车牌的正确的位置。

(4)基于颜色和纹理的定位方法:该算法采用基于适合颜色图像向实行比较的HSI颜色模式,首先在颜色空间进行距离和相似度计算;然后对输入图像进行颜色分割,只有满足车牌颜色特征的区域,才进入下一步的处理;最后在利用纹理和结构特征对分割出来的颜色区域进行分析和进一步判别,并确定车牌区域。

(5)基于分形盒子维的方法:由于车牌内的字符笔画几乎是随机分布,但又有明显的笔画特征,因此可以采用分形维数来对其进行分析从而达到分割车牌的目的。

·字符分割

主要有基于车牌字符特征的投影法和基于聚类分析的车牌字符分割方法以及气泡法等。投影法首先计算牌照字符的垂直投影,利用投影直方图得到一个阑值,根据它再结合车牌字符固定宽度、间距的比例关系等先验知识来分割字符。基于聚类分析的车牌字符分割方法按照属于同一个字符的像素构成了一个连通域的原则,在结合牌照的先验知识来进行字符分割。气泡法是一种适用于二值图像的区域增长法。他把一幅图像分成许多小区域,这些初始的区域可能是小的领域甚至是单个像素。在每个区域中,对经过适当定义能反映一个物体内成员隶属程度的性质(度量)进行计算。首先给每个区域一组参数来反映这些区域分别属于哪个物体,接下来对相邻区域的所有边界进行考查,相邻区域的平均度量之间的差异是计算边界强度的一个尺度,经过反复迭代,每一步都重新计算被扩大区域的物体成员的隶属关系,并消除若边界时,区域合并的过程结束。气泡着色法采用并行处理的方式将图像分割成多个连续的区域,可去掉噪声块,该方法不受车牌倾斜的影响,不需要车牌的先验知识,但是当同一字符的笔画出现间隔时,一个字符往往被分成两个着色区域。因此,气泡法只能对含有全连通域字符的车牌进行有效的分割。

·字符识别

车牌上的字符主要有汉字、英文大写字母以及数字。目的,字符识别的主流技术有:统计决策法、句法结构方法、人工智能方法和人工神经元网络法、模版匹配法等。

统计决策法:这类识别技术的理论比较完善,方法也很多,通常也很有效,现已形成了一个完整的体系。在字符识别中每个字符的特征不是一维,而是一个m维的特征向量X;指定的每类标准板也不一定是一个,可能是一批;判别输入文字属于哪一类时,也不是只把它的特征向量和字典内标准的特征向量逐一进行比较,完全相同才能分类识别,而是根据某种判别准则(尺度),当两者相似到一定程度而且彼此又能区分时就可以分类识别。

句法结构方法:句法模式识别也称为结构模式识别。在许多情况下,对于较复杂的对象仅用一些数值特征己不能充分地对其进行描述,这时可采用句法识别技术。句法识别技术将对象分解为若干个基本单元,这些基本单元称为基元,用这些基元以及他们的结构关系可以描述对象,基元以及他们的结构关系可以用一个字符串或一个图来表示,然后运用形式语言理论进行句法分析,根据其是否符合某类的文法而决定其类别。

人工智能方法:人工智能是研究如何使机器具有人脑功能的理论和方法,模式识别从本质上讲就是如何根据对象的特征进行类别的判断,因此,人工智能方法就是将人工智能中有关学习、知识表示、推理等技术用于模式识别,并由此对车牌字符进行识别。

人工神经元网络法:人工神经元网络是由大量简单的基本单元相互连接而成的非线性动态系统。每个神经元的结构和功能都比较简单,但由其组成的系统却可能非常复杂,它具有人脑的某些特性,能用于联想、识别和决策。神经元具有非线性映射的能力,他们之间通过权系数相连接。这种大规模并行结构具有很高的计算速度,完全不同于传统机器。模式识别中往往存在噪声干扰或输入模式的部分损失,而人工神经原网络将信息分布存储与连接的权系数中,使网络具有很高的容错性和鲁棒性,另外,人工神经元网络的自组织才自适应学习功能,大大放松了传统识别方法所需的约束条件,使其对某些识别问题显示出了极大的优越性。因此人们正在深入探讨人工神经元网络用于模式识别的潜力。

模版匹配法:模版匹配法又分为简单模版匹配法、外围轮廓匹配法、穿线法以及基于距离的模版匹配算法。简单模版匹配法不经过粗分类直接进行模版与字符图像的逐点匹配,匹配时选择海明距离。外围轮廓匹配法采用外围轮廓描述数组,记录字符边框上各点到达框内字符的最短距离。识别时将待识别字符的这一数组与预先得到的模版的外围轮廓描述数组比较,两者差别由欧氏距离衡量。穿线法仍属于字符识别方法中的模板匹配一类,但涉及了字符拓扑结构方面的信息,其基本思想是用一组或几组与水平成0度、30度、45度或60度的平行线贯穿字符。提取字符与水平线的交点信息作为识别依据。基于Huasdo心距离的模板匹配算法将字符图像的边缘点作为特征点,记录这些点所在位置的同时,还记录了每一个点8一邻域的情况,因此每一个边缘点有9个特征值,采用基于Huads。

3.1 车牌区域提取

要正确识别车牌上的数字,首先取决于车辆牌照能否正确从车辆图像中提取,而车辆牌照能否正确从车辆图像中提取则是自动识别的前提,所以图像提取需要极高的正确性。这里从汽车图像中提取牌照区域—牌照坐标,以供下一步识别牌照数字字符用。显示了具体一辆车辆图片的牌照提取过程。其中用到了大量的数字图像处理算法,包括图像的彩色图到灰度图的变换,灰度拉伸,纹理特征提取,去噪,滤波等等。

3.2 车牌定位处理

    牌照定位的预处理只要是对采集的车辆图像进行灰度化和去除噪声的处理,以使车辆图像尤其是牌照区域质量改善,同时保留和增强原有车牌中纹理和颜色信息,去除可能影响牌照区域纹理和颜色信息的噪声,为牌照定位提供方便。

STEP1:灰度图变换

    灰度图(GrayScale)是指只包含亮度信息,不包含色彩信息的图像,通常分成0~255共256个级别,0表示最暗(全黑),255表示最亮(全白)。由于256级灰度比较简单,若是彩色图像,其颜色种类较多,不利于图像处理,因此一般将彩色图像转换为灰度图进行处理。

灰度值==0.299R+0.587G+0.114B

    其实现代码如下所示:

Scolor = imread('car/1.jpg');%imread函数读取图像文件

Sgray = rgb2gray(Scolor);%rgb2gray转换成灰度图

figure,imshow(Scolor),title('原始彩色图像');

figure,imshow(Sgray),title('原始黑白图像');

效果如下所示:

车牌识别_第1张图片车牌识别_第2张图片

图3-1 灰度值处理的前后效果

 

STEP2:背景增强

    通过这个步骤,主要是将背景和图片中的事物形成更加鲜明的对比有利于后期的处理,其实现代码如下所示:

s=strel('disk',13);%strei函数

Bgray=imopen(Sgray,s);%打开sgray s图像

figure,imshow(Bgray);title('背景图像');%输出背景图像

%用原始图像与背景图像作减法,增强图像

Egray=imsubtract(Sgray,Bgray);%两幅图相减

figure,imshow(Egray);title('增强黑白图像');%输出黑白图像

其仿真效果如下所示:

车牌识别_第3张图片

图3-2 背景增强效果

STEP3:图像二值化

图像的二值化处理就是将图像上的像素点的灰度值设置为0255,也就是讲整个图像呈现出明显的黑白效果。

  将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。

  所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。

图像二值化是数字图像处理技术中一项基本的技术,在许多应用场合都要求首先对输入的灰度图像进行二值化。二值图像相对于真彩色图像和256色灰度图像处理量较小,视觉效果强,图像处理的算法也相对比较简单。二值化就是用一个阈值把灰度图像的灰度值分为两类,灰度值低于阈值的归为一类,高于阈值的归为另外一类。通常情况下,根据实际的情况一类赋值为0(黑色),另外一类赋值为255(白色)

    对图像进行二值化处理的关键是阈值的选择与确定,不同的阈值对于一幅图像进行处理会产生不同的二值化处理结果。二值化阈值设置过小容易产生噪声;阈值设置过大会降低分辨率,使非噪声信号被视为噪声而滤掉。根据不同的图像处理的要求,设置的阈值也不一样,要根据图像本身的特点以及实际的处理要求决定。目前有很多种阈值选取方法,依阈值的应用范围可分为整体阈值法、局部阈值法和动态阈值法。整体阈值法是指在二值化过程中只使用一个阈值;局部阈值法则是由像素的灰度值和像素周围局部特性来确定二值化的阈值;动态阈值法的阈值确定不仅取决于该像素的灰度值及其周围像素的灰度值,而且与像素位置信息有关。一般来说,整体阈值法对质量较好的图像较为有效,而局部阈值法适用于较为复杂的图像。二值化一般有以下常用的方法:

 

    MATLAB代码如下所示:

fmax1=double(max(max(Egray)));%egray的最大值并输出双精度型

fmin1=double(min(min(Egray)));%egray的最小值并输出双精度型

level=(fmax1-(fmax1-fmin1)/3)/255;%获得最佳阈值

bw22=im2bw(Egray,level);%转换图像为二进制图像

bw2=double(bw22);

其处理效果如下所示:

车牌识别_第4张图片

3-3 图像二值化处理效果

STEP4:滤波

    车辆图像由于噪声的影响,存在一些孤立点,俗称椒盐噪声,在进行牌照图像处理中要考虑抑制或者去除这种椒盐噪声。中值滤波是一种非线性滤波技术。它是基于图像的这样一种特性:噪声往往以孤立的点的形式出现,这些点对应的像素数很少,而图像则是由像素数较多、面积较大的小块构成。在一定条件下,可以克服线形滤波器所带来的图像细节模糊,而且对滤波脉冲干扰及图像的扫描噪声最为有效。但是对一些细节多,特别是点、线和尖顶多的图像不宜采用中值滤波的方法。

车牌识别_第5张图片  ->  车牌识别_第6张图片

这个过程实现代码如下所示:

%Step4 对得到二值图像作开闭操作进行滤波

figure,imshow(bw2);title('图像二值化');%得到二值图像

grd=edge(bw2,'canny')%用canny算子识别强度图像中的边界

figure,imshow(grd);title('图像边缘提取');%输出图像边缘

bg1=imclose(grd,strel('rectangle',[5,19]));%取矩形框的闭运算

figure,imshow(bg1);title('图像闭运算[5,19]');%输出闭运算的图像

bg3=imopen(bg1,strel('rectangle',[5,19]));%取矩形框的开运算

figure,imshow(bg3);title('图像开运算[5,19]');%输出开运算的图像

bg2=imopen(bg3,strel('rectangle',[19,1]));%取矩形框的开运算

figure,imshow(bg2);title('图像开运算[19,1]');%输出开运算的图像

其最后的效果如下所示:

车牌识别_第7张图片 车牌识别_第8张图片 车牌识别_第9张图片

图3-4 图像滤波后的效果

STEP5:车牌区域的最终提取

    从车辆图像中正确分割出牌照区域是牌照识别中最为关键的步骤之一。如果牌照定位的效果不好,后面的数字以及文字字符的分割和识别根本不可能完成。如果定位的效果足够好,后面的分割和识别工作就相对容易了。牌照定位率是牌照识别的一项重要指标,它直接关系到整个系统的成败。目前,人们提出的车辆牌照定位的方法很多,主要分成两大类:一是利用图像的灰度信息,参考的是牌照区域的文字信息比较丰富,造成牌照区域的纹理变化比较有规律,利用牌照区域的纹理变化检测出几个候选牌照区域,然后去除伪牌照区域,得到真实的牌照区域;另一类是利用梯度信息,先对图像信息进行边缘检测,再对边缘图像进行形态学运算,直到寻找到车牌区域,完成牌照的粗定位,然后用其它的算法实现牌照的精确定位。还有的一些方法主要是基于彩色车辆图像进行处理的,因为彩色图像的颜色信息比较丰富,牌照区域的颜色信息更加丰富,利用牌照区域丰富的颜色信息定位牌照区域。

   常用的牌照定位方法,如基于边缘检测的牌照定位方法、基于小波算法的牌照定位、基于神经网络的车辆牌照定位方法等等。边缘检测的效果比较理想,但是通常情况下有些车辆的牌照边缘不是很明显,这样的检测效果就要大打折扣,而且由于车辆中还有诸多的类似于矩形的区域,例如车前头灯部位,如何去除这些伪车牌区域难度也比较大[11]。基于小波算法和神经网络的车牌定位方法,应用数学领域最新的研究成果,对车辆牌照进行定位,但是由于车辆图像本身的极大变化性,上述方法的处理效果,对于某些车辆图像质量比较好,车牌特征比较明显的图像效果较好,而对于其它质量和牌照特征不好的车辆图像定位的效果就可能不是很好,甚至定位不出来。总之,这些定位的方法,各有优缺点,定位的效果也不同,它们大多对于某一特定的环境和光线以及特定的某一类车牌效果比较好,而环境和光线变化了,识别的效果就不是很理想了。  

本文根据车牌底色等有关的先验知识,采用彩色像素点统计的方法分割出合理的车牌区域。下面以蓝底白字车牌区域为例说明彩色像素点统计底分割方法。CCD摄像头拍摄的图像一般为RGB彩色图像,确定车牌底色(蓝色)RGB对应的各自灰度范围,然后行方向统计在此颜色范围内的像素点数量,设定合理的闕值,确定车牌在行方向的合理区域。然后,在分割出的行区域内,统计列方向蓝色像素点的数量。

    本文我们主要将通过二值得到的图像区域作分析,然后在图像区域中获得车牌的位置,并在原始的位置做车牌的显示,从而获得车牌的实际位置。

 [L,num] = bwlabel(bg2,8);%标注二进制图像中已连接的部分

Feastats = imfeature(L,'basic');%计算图像区域的特征尺寸

Area=[Feastats.Area];%区域面积

BoundingBox=[Feastats.BoundingBox];%[x y width height]车牌的框架大小

RGB = label2rgb(L, 'spring', 'k', 'shuffle'); %标志图像向RGB图像转换

figure,imshow(RGB);title('图像彩色标记');%输出框架的彩色图像

lx=0;

for l=1:num

    width=BoundingBox((l-1)*4+3);%框架宽度的计算

    hight=BoundingBox((l-1)*4+4);%框架高度的计算

    if (width>98 & width<160 & hight>25 & hight<50)%框架的宽度和高度的范围

        lx=lx+1;

        Getok(lx)=l;

    end

end

for k= 1:lx

    l=Getok(k);   

    startcol=BoundingBox((l-1)*4+1)-2;%开始列

    startrow=BoundingBox((l-1)*4+2)-2;%开始行

    width=BoundingBox((l-1)*4+3)+8;%车牌宽

    hight=BoundingBox((l-1)*4+4)+2;%车牌高

    rato=width/hight;%计算车牌长宽比

    if rato>2 & rato<4  

        break;

    end

end

车牌提取效果如下所示:

车牌识别_第10张图片

图3-5 对不同区域进行彩色标记

搜索最大的区域,其效果如下所示:

车牌识别_第11张图片

图3-6 提取车牌

3.3 车牌校正处理

    牌照底色与字符颜色分黄底黑字、白底红字、蓝底白字、黑底白字四种,转换为256色灰度图象以后,黄底黑字、白底红字两种属于明底暗字类型,蓝底白字、黑底白字两种属于暗底明字类型。根据上面的二值化方法,将大于阈值的灰度级范围变换为255,小于阈值的灰度级范围变换为0。这样处理以后,对于明底暗字的车牌,因为底色明亮,其像素的灰度值偏大,而字符像素对应的灰度值偏小,所以二值化后的图像底色为白色,而字符颜色为黑色,即白底黑字;对于明底暗字的车牌来讲恰恰相反。为了后续处理的方便,需要将二值图像统一。

    为了便于处理,设定二值化后的牌照为白底黑字,这样子对于黄底黑字和白底红字的牌照来讲,不需要另外进行反色处理,对于蓝底白字和黑底白字牌照在二值化后,要进行反色处理。为此,需要首先区分牌照属于明底暗字还是暗底明字。理想的牌照区域中字符所占的像素数相对于背景所占的像素数要少,通过观察大概是3:7。可以通过对于二值化后的图像统计其中的黑白像素的比值来确定对应的牌照区域字符与背景的颜色。假定根据数学期望法二值化后的图像为白底黑字,统计处理过后的黑白像素的个数。设定黑白像素的比值为2:3,大于3:7的比值即可。计算处理过后图像黑白个数的比值,当大于2:3时,则说明黑色像素居多,可能的图像为黑底白字,则对图象进行反色处理;相反,则认为是白底黑字,不需要进行反色的处理。

    某些车牌由于摄像机拍摄角度的原因,存在一定的角度倾斜,为了正确的分割和识别字符,必须进行牌照的校正,使牌照从正面看基本上是一个长方形。因为字符分布在牌照的中央位置,字符与上下边界之间各存在一个空隙,对于上面处理过后的二值图像,该空隙对应的白色区域,可以通过对牌照进行水平投影,这样子那两个空隙对应的白色区域在投影图中就存在两个谷底。但是,倾斜的牌照这样的谷底就不存在或者不明显,为此首先找到牌照的倾斜角度,然后旋转该图像。有学者提出了一种基于水平投影的自适应方法确定牌照的倾斜角度。该方法从车牌左侧以水平方向为起点,以3度角为步长(一般的倾斜角度在正负15度之内),分别沿着顺时针和逆时针方向向右侧投影。每投影一次,统计投影图中每行黑色像素的个数,然后从统计结果中选择相邻三行黑色像素数之间变化梯度最大值,此次扫描的角度作为该次投影后所求的牌照偏移的角度。这样,每变换一次,即可得—到一个梯度值,直到循环到顺时针15度和逆时针15度为止,这样得到11个梯度值,在这11个梯度值中找到最大值,作为该值所进行的扫描角度的实际偏移值。

%Step6 计算车牌水平投影,并对水平投影进行峰谷分析

histcol1=sum(sbw1);      %计算垂直投影

histrow=sum(sbw1');      %计算水平投影

figure,subplot(2,1,1),bar(histcol1);title('垂直投影(含边框)');%输出垂直投影

subplot(2,1,2),bar(histrow);     title('水平投影(含边框)');%输出水平投影

figure,subplot(2,1,1),bar(histrow);     title('水平投影(含边框)');%输出水平投影

subplot(2,1,2),imshow(sbw1);title('车牌二值子图');%输出二值图

%对水平投影进行峰谷分析

meanrow=mean(histrow);%求水平投影的平均值

minrow=min(histrow);%求水平投影的最小值

levelrow=(meanrow+minrow)/2;%求水平投影的平均值

count1=0;

l=1;

for k=1:hight

    if histrow(k)<=levelrow                            

        count1=count1+1;                               

    else

        if count1>=1

            markrow(l)=k;%上升点

            markrow1(l)=count1;%谷宽度(下降点至下一个上升点)

            l=l+1;

        end

        count1=0;

    end

end

markrow2=diff(markrow);%峰距离(上升点至下一个上升点)

[m1,n1]=size(markrow2);

n1=n1+1;

markrow(l)=hight;

markrow1(l)=count1;

markrow2(n1)=markrow(l)-markrow(l-1);

l=0;

for k=1:n1

    markrow3(k)=markrow(k+1)-markrow1(k+1);%下降点

    markrow4(k)=markrow3(k)-markrow(k);%峰宽度(上升点至下降点)

    markrow5(k)=markrow3(k)-double(uint16(markrow4(k)/2));%峰中心位置

end

%Step7 计算车牌旋转角度

%(1)在上升点至下降点找第一个为1的点

[m2,n2]=size(sbw1);%sbw1的图像大小

[m1,n1]=size(markrow4);%markrow4的大小

maxw=max(markrow4);%最大宽度为字符

if markrow4(1) ~= maxw%检测上边

    ysite=1;

    k1=1;

    for l=1:n2

    for k=1:markrow3(ysite)%从顶边至第一个峰下降点扫描

        if sbw1(k,l)==1

            xdata(k1)=l;

            ydata(k1)=k;

            k1=k1+1;

            break;

        end

    end

    end

else  %检测下边

    ysite=n1;

    if markrow4(n1) ==0

        if markrow4(n1-1) ==maxw

           ysite= 0; %无下边

       else

           ysite= n1-1;

       end

    end

    if ysite ~=0

        k1=1;

        for l=1:n2

            k=m2;

            while k>=markrow(ysite) %从底边至最后一个峰的上升点扫描

                if sbw1(k,l)==1

                    xdata(k1)=l;

                    ydata(k1)=k;

                    k1=k1+1;

                    break;

                end

                k=k-1;

            end

        end

    end

end      

%(2)线性拟合,计算与x夹角

fresult = fit(xdata',ydata','poly1');   %poly1    Y = p1*x+p2

p1=fresult.p1;

angle=atan(fresult.p1)*180/pi; %弧度换为度,360/2pi,  pi=3.14

%(3)旋转车牌图象

subcol = imrotate(subcol1,angle,'bilinear','crop'); %旋转车牌图象

sbw = imrotate(sbw1,angle,'bilinear','crop');%旋转图像

figure,subplot(2,1,1),imshow(subcol);title('车牌灰度子图');%输出车牌旋转后的灰度图像标题显示车牌灰度子图

subplot(2,1,2),imshow(sbw);title('');%输出车牌旋转后的灰度图像

title(['车牌旋转角: ',num2str(angle),'度'] ,'Color','r');%显示车牌的旋转角度

其仿真效果如下所示:

车牌识别_第12张图片

图3-8 校正以后的图像

3.4 去除边框

    实际的牌照是以边框包围着牌照区域的字符,进行字符分割和识别需要将边框去除。分析水平分割和垂直分割后的牌照区域图像,为了突出牌照区域的字符,无论是字符的上下边框还是左右边框离实际的字符都有相当的距离,表现在图像上就是在字符和边框之间出现相当的白色间隙区域,这样就把边框和实际的字符分割出来了,而且相差比较大。利用上述两点对图像进行水平投影可以除去上下边框,进行垂直投影可以除去左右边框。

以下是针对上面的图像去除其左右边界的算法:首先,对含有左右边框的图像进行垂直投影,统计各列的像素个数,这样子在投影图象中,就会出现左右边框和7个字符的垂直投影图,字符投影宽度比左右边框要大很多,而且左右边框分布在字符的两边。设置行扫描线对投影图象进行行扫描,设定垂直投影的字符宽度阈值T,给一个阈值范围T±δ,判断检测到的字符(包括边框)投影的宽度是否在此范围内,一般情况下,边框的宽度远远小于此阈值,比较容易去除。

其实现代码如下所示:

%Step8 旋转车牌后重新计算车牌水平投影,去掉车牌水平边框,获取字符高度

histcol1=sum(sbw); %计算垂直投影

histrow=sum(sbw'); %计算水平投影

figure,subplot(2,1,1),bar(histcol1);title('垂直投影(旋转后)');

subplot(2,1,2),bar(histrow);     title('水平投影(旋转后)');

figure,subplot(2,1,1),bar(histrow);     title('水平投影(旋转后)');

subplot(2,1,2),imshow(sbw);title('车牌二值子图(旋转后)');

%去水平(上下)边框,获取字符高度

maxhight=max(markrow2);

findc=find(markrow2==maxhight);

rowtop=markrow(findc);

rowbot=markrow(findc+1)-markrow1(findc+1);

sbw2=sbw(rowtop:rowbot,:);  %子图为(rowbot-rowtop+1)行

maxhight=rowbot-rowtop+1;   %字符高度(rowbot-rowtop+1)

%Step9 计算车牌垂直投影,去掉车牌垂直边框,获取车牌及字符平均宽度

histcol=sum(sbw2);  %计算垂直投影

figure,subplot(2,1,1),bar(histcol);title('垂直投影(去水平边框后)');%输出车牌的垂直投影图像

subplot(2,1,2),imshow(sbw2); %输出垂直投影图像

title(['车牌字符高度: ',int2str(maxhight)],'Color','r');%输出车牌字符高度

%对垂直投影进行峰谷分析

meancol=mean(histcol);%求垂直投影的平均值

mincol=min(histcol);%求垂直投影的平均值

levelcol=(meancol+mincol)/4;%求垂直投影的1/4

count1=0;

l=1;

for k=1:width

    if histcol(k)<=levelcol

        count1=count1+1;

    else

        if count1>=1

            markcol(l)=k; %字符上升点

            markcol1(l)=count1; %谷宽度(下降点至下一个上升点)

            l=l+1;

        end

        count1=0;

    end

end

markcol2=diff(markcol);%字符距离(上升点至下一个上升点)

[m1,n1]=size(markcol2);

n1=n1+1;

markcol(l)=width;

markcol1(l)=count1;

markcol2(n1)=markcol(l)-markcol(l-1);

其仿真结果如下所示:

车牌识别_第13张图片

图3-9 投影直方图

车牌识别_第14张图片

图3-10 水平投影后的效果

车牌识别_第15张图片

图3-11 垂直投影后的效果

    字符分割是将牌照中的单个字符分割出来,以供下一步神经网络识别用。

    字符分割算法是以垂直投影、字符间距尺寸测定、字符的长宽比、轮廓分析技术的组合为基础的。由于二值化的原因,可能产生粘连、断裂的字符。此时要根据牌照的大致宽度,结合各字符的轮廓,利用分割、合并的方法正确地分割字符。

    上面去除边框的算法以后,如上图所示,字符已经是比较清晰了。上面去除边框的算法稍加改变后即可以用于字符分割。考虑到牌照全部7个字符宽度大小一定,第二个与第三个字符之间的间距相对于其它字符的间距宽度要大一些,所以在扫描垂直投影图后将各个字符左右边界作为实际分割字符的边界点,最左和最右端点就取图像的左右边界。

车牌识别_第16张图片

图3-12 字母分割流程

其实现代码如下所示:

%Step10 计算车牌上每个字符中心位置,计算最大字符宽度maxwidth

l=0;

for k=1:n1

    markcol3(k)=markcol(k+1)-markcol1(k+1);%字符下降点

    markcol4(k)=markcol3(k)-markcol(k); %字符宽度(上升点至下降点)

    markcol5(k)=markcol3(k)-double(uint16(markcol4(k)/2));%字符中心位置

end

markcol6=diff(markcol5); %字符中心距离(字符中心点至下一个字符中心点)

maxs=max(markcol6); %查找最大值,即为第二字符与第三字符中心距离

findmax=find(markcol6==maxs);

markcol6(findmax)=0;

maxwidth=max(markcol6);%查找最大值,即为最大字符宽度

%Step11 提取分割字符,并变换为22行*14列标准子图

l=1;

[m2,n2]=size(subcol);

figure;

for k=findmax-1:findmax+5

        cleft=markcol5(k)-maxwidth/2;

        cright=markcol5(k)+maxwidth/2-2;

        if cleft<1

            cleft=1;

            cright=maxwidth;

        end

        if cright>n2

            cright=n2;

            cleft=n2-maxwidth;

        end

        SegGray=sbw(rowtop:rowbot,cleft:cright);

        SegBw1=sbw(rowtop:rowbot,cleft:cright);

        SegBw2 = imresize(SegBw1,[22 14]);%变换为22行*14列标准子图     

        subplot(2,n1,l),imshow(SegGray);

        if l==7

            title(['车牌字符宽度: ',int2str(maxwidth)],'Color','r');

        end

        subplot(2,n1,n1+l),imshow(SegBw2);              

        fname=strcat('data',int2str(k),'.jpg');

        imwrite(SegBw2,fname,'jpg')

        l=l+1;

end

其仿真结果如下所示:

图3-13 字母分割效果

3.6 数字识别

    车牌字符的识别是字符识别中的重要部分,实际上就是把图像中的车牌字符变为文本字符,以利于人的可视化和计算机进一步处理。车牌字符识别包括汉字、英文字母、数字的识别,上述的牌照字符分割和字符归一化处理为车牌字符识别提供了必要的准备。由于时间的关系,本论文只探讨了基于数字识别的神经网络识别方法,对于字母识别和汉字识别将不作讨论。

    对于牌照字符的识别来说,目前应用的比较多的是模板匹配和神经网络的方法。模板匹配是图像识别中最具代表性的基本方法之一,它是通过计算机图像与模板特征之间的距离,利用最小距离法来判断未知图像类型的。通常情况下,如果车牌字符分割精确,字符清洁规则,那么利用模板匹配的方法可以得到很高的识别率。但是,车牌存在倾斜,不整洁等特点,那么识别率会大大下降。神经网络方法是字符识别中较为健壮的方法,它可以容忍一定程度的噪声和字符倾斜,如果处理得当,识别率还是令人比较满意的。

    神经网络是从生物神经系统的信号传递而抽象发展成的一门学科。在神经网络中,最基本的单元是神经元。神经网络能够通过学习过程从外部环境中获取知识,并且它内部很多的神经元可以用来存储这些已经学到的知识。

    BP网络的学习算法如下:

    第一步,设置变量和参数,其中包括训练样本,权值矩阵,学习速率;

    第二步,初始化,给各个权值矩阵一个较小的随机非零向量;

    第三步,输入随即样本;

    第四步,对输入样本,前向计算BP网络每层神经元的输入信号和输出信号;

    第五步,由实际输出和期望输出求得误差,判断是否满足要求,若满足转第八步;不满足转第六步;     

    第六步,判断是否已经到了最大迭代次数,若到,转第八步,否则反向计算每层神经元的局部梯度;

    第七步,根据局部梯度修正各个矩阵的权值;

    第八步,判断是否学习完所有的样本,是则结束,否则转第三步。

    经过前面的字符分割和归一化处理后,牌照字符变成了一个个大小相同,排列整齐的字符。下面就要从被分割归一化处理完毕的字符中,提取最能体现这些字符特点的特征向量,将提取出训练样本中的特征向量代入BP网络之中就可以对网络进行训练,提取出待识别样本中的特征向量代入训练好的BP网络中,就可以对字符进行识别。特征向量的提取方法多种多样,由于汉字、字母以及数字的差异比较大,对于不同的字符可以采取不同的特征提取方法,进而生成基于汉字识别的神经网络识别器、基于字母识别的神经网络识别器和基于数字识别的神经网络识别器。

    其实现代码如下所示:

%Step12 将计算计算获取的字符图像与样本库进行匹配,自动识别出字符代码。

liccode=char(['0':'9' 'A':'Z' '粤桂海云贵川京津沪']); %建立自动识别字符代码表 

SubBw2=zeros(22,14);

l=1;

[m2,n2]=size(sbw);

for k=findmax-1:findmax+5

       cleft=markcol5(k)-maxwidth/2;

        cright=markcol5(k)+maxwidth/2-2;

        if cleft<1

            cleft=1;

            cright=maxwidth;

        end

        if cright>n2

            cright=n2;

            cleft=n2-maxwidth;

        end

        SegBw1=sbw(rowtop:rowbot,cleft:cright);

        SegBw2 = imresize(SegBw1,[22 14]);%变换为22行*14列标准子图     

        if l==1                 %第一位汉字识别

            kmin=37;

            kmax=45;

        elseif l==2             %第二位 A~Z 字母识别

            kmin=11;

            kmax=36;

        elseif l>=3 & l<=5      %第三、四位 0~9  A~Z字母和数字识别

            kmin=1;

            kmax=36;

        else                    %第五~七位 0~9 数字识别

            kmin=1;

            kmax=10;

        end

        for k2=kmin:kmax

            fname=strcat('Sam\Sam',liccode(k2),'.jpg');

            SamBw2 = imread(fname);          

            for  i=1:22

                for j=1:14

                    SubBw2(i,j)=SegBw2(i,j)-SamBw2(i,j);

                end

            end %SubBw2 = SamBw2-SegBw2;

            Dmax=0;

            for k1=1:22

                for l1=1:14

                    if ( SubBw2(k1,l1) > 0 | SubBw2(k1,l1) <0 )

                        Dmax=Dmax+1;

                    end

                end

            end

            Error(k2)=Dmax;

        end

        Error1=Error(kmin:kmax);%比较误差

        MinError=min(Error1);%取误差的最小值

        findc=find(Error1==MinError);%查找最小误差的图像

        RegCode(l*2-1)=liccode(findc(1)+kmin-1);

        RegCode(l*2)=' ';%输出最小误差图像

        l=l+1;

end

title (['识别车牌号码:', RegCode],'Color','r');

其最后的结果如下所示:

车牌识别_第17张图片

图3-14 最后的运行效果

我们在matlab的命令窗口可以看到已经被识别的车牌信息。

你可能感兴趣的:(MATLAB,板块2:图像-特征提取处理,车牌识别)