赞
踩
随着智慧交通的发展,对机动车监管的需要,车牌识别技术成为现代智慧交通系统中不可或缺的一部分,在日常生活中应用十分 广泛。本文章研究分析了该技术实现各个部分所使用的相关算法,选取了识别准确率高并且效率较高的算法,利用MATLAB软件实现车牌识别系统软件部分设计,设计使用了Gui界面。通过对系统识别效率的测试表明,该系统可以有效地识别蓝底白字机动车车牌,为车牌识别技术的进一步发展献出一份力量。
在本文中,该系统使用静态图像作为识别目标,并使用图像处理工具、数学形态学知识和人工智能算法来自动识别车牌。系统基本上描述了软件部分,识别步骤的顺序包括原始图像的输入、图像的预处理、车牌定位、切割和识别组成。
识别系统流程如图1所示:
首先需要对采集的视频流文件进行逐帧分解,截取到车牌区域图像,随后向机动车识别系统输入截取的车牌图像,将截取的静态图像作为识别目标。为显示出供选择图片的对话框调用uigetfile函数,待选择图像后获取图像信息调用imread函数,如图2所示。工作区图像如图3所示。
实现代码如下:
- [文件名filename ,路径名 pathname ] = uigetfile ( '*.jpg','读取图片' ) ;
-
- if isequal(filename,0)
-
- msgbox('没有图片')
-
- else
-
- 路径文件Pathfile = 全文件fullfile (路径名pathname ,文件名 filename ) ;
-
- T=imread(pathfile);
-
- end
图2 截取的车牌原图像:
图3 工作区图像:
2.图像预处理
摄像机拍摄车牌图像时往往都处于复杂的环境中,图像受环境、天气、车牌干净程度等一系列影响,图像预处理是将读取的原始图像进行降噪、腐蚀、膨胀等一系列程序对图像进行处理,为得到一个尽可能清晰的图像,去除影响系统读取的噪点,因此需对图像进行预处理。
这一步调用rgb2gray函数对车牌原图像进行灰度化处理,使得原始图像读取速度加快、占用空间减小、提升系统运行效率。调用imshow和imhist函数来输出灰度化图像与灰度直方图,如图3 所示。
调用函数代码如下:
- I1=rgb2gray(I);
- figure(2),subplot(1,2,1),imshow(I1);title('灰度图');
- figure(2),subplot(1,2,2),imhist(I1);title('灰度图直方图');
图3 灰度图与灰度图直方图:
在本文中,在对各种算法进行比较和测试之后,根据实验结果,最终选择了Sobel算子进行边缘检测。利用Sobel算子方法具有平滑噪声的作用,对于去除噪声对图像的影响具有相当好的效果,可以更好的突出图像边缘轮廓。尽管Sobel运算符可以提供更好的检测结果,但检测到的边缘较粗,可能会出现错误的边缘,这可能会导致后续识别出现错误。这里调用edge函数之后输入阈值调用Sobel算子对车牌原图像进行二值化和边缘检测,如图4所示。
调用代码如下:
- I2=edge(I1,'sobel',0.15,'both');
- figure(3),imshow(I2);title('算子边缘检测');
- se=[1;1;1];
图4 算子边缘检测:
Sobel算子的实现步骤主要可以分为三个步骤:
1.通过运算Gx与Gy与模板每行之间的乘积。
2.每行和每列将两个3 * 3矩阵的卷积相乘,然后在3 * 3模板运算后将它们相加得到Gx和Gy。
3.求得Gx^2+Gy^2的平方根。
图像腐蚀是基于数学形态学的概念下所实现的,腐蚀运算主要用于消除图像中不需要的杂乱部分。为了尽量的获到清晰的车牌的边缘信息,消除其他地区的边缘信息,需要采取数学形态学中的腐蚀运算操作对图像进行处理,尽可能保存车牌边缘信息,消除其他微小部分边缘信息。图像腐蚀操作调用imerode函数,如图5所示。
调用函数代码如下:
- I3=imerode(I2,se);
- figure(4),imshow(I3);title('腐蚀后图像');
- se=strel('rectangle',[25,25]);
图5腐蚀后图像:
经过腐蚀处理后的图像仍然会有一部分的需要的边缘信息被消除,此时为了填补这些需要的边缘信息,解决边缘参差不齐的现象,我们要对图像进行膨胀处理。但是经过膨胀以后会再次出现多余的边缘,此时还需要再次进行腐蚀运算。所以这里采用图像闭运算,图像闭运算是图像先膨胀运算,再腐蚀运算,填补小缝隙,消除间隙连接边缘,可以定位出车牌区域大致位置。对车牌原图像进行闭运算处理需要调用imclose函数。车牌图像常常存在很多噪点信息,为了去除和抑制这些噪点,所以还需对图像进行平滑操作,如图6所示。
调用函数代码如下:
- I4=imclose(I3,se);
- figure(5),imshow(I4);title('平滑图像的轮廓');
图6 闭运算平滑处理图像:
经过图像闭运算处理后,可以看出已经可以定位车牌大致位置图像,但是还有一小部分干扰图像没有完全消除,但是车牌部分的图像已经大致连在一起,形成一个整块。车牌部分占据了大部分的地方,而其他干扰部分的图像都是比较小的图像。因此,根据车牌原始图像面积我们在这里可以确定设置一个阈值,如果图像的面积小于阈值设置的面积则移除该图像。对原图像进行移除面积小于2000的小图像操作调用bwareaopen函数,如图7所示。
调用函数代码如下:
- I5=bwareaopen(I4,2000);
- figure(6),imshow(I5);title('从图像中移除小面积图像');
- [y,x,z]=size(I5);
- myI=double(I5);
图7 移除小面积图像:
3.车牌定位
但是车牌图像经过处理后可能会腐蚀一部分车牌图像,不能直接进行车牌定位。
3.1车牌初定位
首先需要对车牌图像大致区域进行切分,消除掉非车牌部分图像。得到大致车牌图像时,先经过数学形态学操作进行定位处理,提取到车牌高度、宽度信息后,与我国现行的机动车车牌照标准进行比较,以此来确定车牌区域。在这里,测量和标记区域的区域我们需要调用regionprops函数,来提取到车牌图像的区域,并将其与我国现行车牌的高度比和宽度比进行比较,从而首先确定车牌区域大致范围。
依据我国现行机动车车牌牌照的标准,蓝底白字车牌牌照宽度为440mm,高度为140mm。宽度与高度之比为140mm/440mm,大约为0.32。车牌号上字符间距也有明确要求,车牌号上每个字符的宽度为45mm,每个字符间相隔12mm,并且字符的上,下侧都有相等的间隙,以使它们不会被牌照挡住。如图8所示。
调用函数代码如下:
- 图img_reg = regionprops(bw_img, 'area', 'boundingbox');
-
- areas = [img_reg.Area];
-
- rects = cat(2, img_reg.BoundingBox);
图8车牌初步定位:
在本文中,我们将选择一种投影分割方法来实现车牌和非车牌图像的分割,并使用车牌的水平和垂直位置来确定车牌的确切位置。首先要做的是根据水平进行一阶微分计算,水平放置车牌并突出显示灰度频繁变化的区域。计算出差异后的图像灰度水平累积并水平投影,水平方向定位完后使用垂直定位来进行纵向定位,使用与水平投影相同的方法在纵向上重新定位车牌,并在车牌的纵向上使用一阶差分运算,然后纵向上累加,再基于垂直方向投影。如图9所示。
实现代码如下:
- Blue_y=zeros(y,1); %Y方向车牌区域确定
-
- for i=1:y
-
- for j=1:x
-
- if(myI(i,j,1)==1)
-
- Blue_y(i,1)= Blue_y(i,1)+1; %蓝色像素点统计
-
- end
-
- end
-
- end
-
- [temp MaxY]=max(Blue_y);
-
- PY1=MaxY;
-
- while ((Blue_y(PY1,1)>=5)&&(PY1>1))
-
- PY1=PY1-1;
-
- end
-
- PY2=MaxY;
-
- while ((Blue_y(PY2,1)>=5)&&(PY2<y))
-
- PY2=PY2+1;
-
- end
-
- IY=I(PY1:PY2,:,:);
-
-
-
- Blue_x=zeros(1,x); %X方向车牌区域确定
-
- for j=1:x
-
- for i=PY1:PY2
-
- if(myI(i,j,1)==1)
-
- Blue_x(1,j)= Blue_x(1,j)+1;
-
- end
-
- end
-
- end
-
-
-
- PX1=1;
-
- while ((Blue_x(1,PX1)<3)&&(PX1<x))
-
- PX1=PX1+1;
-
- end
-
- PX2=x;
-
- while ((Blue_x(1,PX2)<3)&&(PX2>PX1))
-
- PX2=PX2-1;
-
- end
图9车牌精确定位:
在截取车牌图像时,可能由于车牌拍摄角度、车牌悬挂位置、车牌牌照倾斜角度等问题,往往会导致拍摄的车牌图像会有一定程度上的倾斜变形模糊现象发生。如果直接对倾斜得到车牌图像进行定位后,车牌图像也是倾斜的,这种情况可能会降低车牌识别准确性,如果倾斜角度过大,则可能无法识别车牌图像。在本文中,我们选择了Radon变换法,一般情况下Radon变换要比Hough变换校正更为准确并且更为美观,校正后的图像如图10所示。
Radon变化基本语法如下:
- R = radon(I)
-
- R = radon(I,theta)
-
- [R,xp] = radon(___)
-
图10 车牌校正:
4.字符分割
本文选择基于投影分割的分割算法,原理是对车牌像素的投影,第一步是对车牌图像从左到右进行扫描,然后垂直投影每列,最后从左到右扫描山谷的位置,以确定左右边界。在确定每个字符的边界之后,根据字符边界将每个字符划分,以获得每个字符的图像。扫描图像如图11所示。
转存失败重新上传取消转存失败重新上传取消转存失败重新上传取消转存失败重新上传取消
图11 扫描图像:
这里调用rgb2gray函数对车牌原图像进行灰度化处理,使得原始图像读取速度加快、占用空间减小、提升系统运行效率。如图12所示。
代码实现如下:
- imwrite(dw,'dw.jpg');
-
- q=imread('dw.jpg');
-
- w=rgb2gray(q); %灰度化处理
-
- imwrite(w,'1.车牌灰度图像.jpg');
-
图12 车牌灰度化处理:
4.2 二值化处理
为了统一图像并减少图像数据量需要对图像进行二值化处理。处理有利于图像处理速度的加快和目标图像轮廓的增强。如图13所示。
代码实现如下:
- g_max=double(max(max(w)));
-
- g_min=double(min(min(w)));
-
- T=round(g_max-(g_max-g_min)/3); % T为二值化的阈值
-
- [~,~]=size(w);
-
- e=(double(w)>=T); % e:二值图像
-
- imwrite(d,'2.车牌二值化图像.jpg');
图13 二值化处理:
均值滤波处理消除了图像中的尖锐噪声,实现了图像抗混叠和调制等功能,并实现了降噪效果。但是容易使图像变得模糊,不能提供良好的图像信息。如图14所示。
实现代码如下:
- h=fspecial('average',3); % 均值滤波处理
-
- e=im2bw(round(filter2(h,e)));
-
- imwrite(d,'4.均值滤波后.jpg');
图14 均值滤波处理:
4.4膨胀、腐蚀处理
利用数学形态学知识中的腐蚀、膨胀操作来消除噪声、填充车牌和字符边缘细节。膨胀处理缺陷,腐蚀处理毛刺,在不改变车牌形状的前期下,把车牌毛刺边缘问题处理,把字体和字符缺陷信息弥补完整。如图15所示。
实现代码如下:
- if bwarea(e)/m/n>=0.365
-
- e=imerode(e,se); %腐蚀运算
-
- elseif bwarea(e)/m/n<=0.235
-
- e=imdilate(d,se); %膨胀运算
-
- end
-
- imwrite(e,'5.膨胀、腐蚀处理后.jpg');
-
- figure(8),subplot(3,2,5),imshow(e),title('(5)膨胀、腐蚀处理后图像')
图15 膨胀、腐蚀处理:
4.5 字符分割
本文选择一种用于字符分割的投影分割算法,调用代码qiege.m代码来对图像实施1值像素扫描操作,以此来进行初步分割。
首先对分割出来的第一个区域进行判断,如果分割出来的区域宽度大于整个图像宽度的1/6.5,则认定这个区域包含两个字符,需要再次进行分割。
如果分割图像的宽度小于10个像素,则将左侧区域视为干扰区域,并对该区域进行裁剪。
如果分割部分与上述判断相符,则该区域被认定为是第一个字符的区域,记为imwrite(zifu1,’1.jpg’),以此类推,由左向右,直到最后一个字符分割完毕。
基于投影法的分割算法原理较为简单,系统处理速度也快,但是也存在一定的缺点,如对字符的粘连、边框的处理、车牌上的干扰元素处理的不到位。另外,如果分割左右汉字,很容易将左右汉字错误地分为两个字符,因此在分割之前需要对汉字的边界进行严格的判断。切割后图像如图16所示。
实现代码如下:
- function e=qiege(d)
-
- [m,n]=size(d);
-
- top=1;bottom=m;left=1;right=n;
-
- while sum(d(top,:))==0 && top<=m
-
- top=top+1;
-
- end
-
- while sum(d(bottom,:))==0 && bottom>=1
-
- bottom=bottom-1;
-
- end
-
- while sum(d(:,left))==0 && left<=n
-
- left=left+1;
-
- end
-
- while sum(d(:,right))==0 && right>=1
-
- right=right-1;
-
- end
-
- dd=right-left;
-
- hh=bottom-top;
-
- e=imcrop(d,[left top dd hh]);
图16 分割出的单个字符图像:
在切出所有车牌字符以方便进行识别字符之后,对切出的字符进行图像归一化处理并归一化为40 * 20像素图像。如图17所示。
实现代码如下:
- % 归一化大小为 40*20
- word1=imresize(word1,[40 20]);
- word2=imresize(word2,[40 20]);
- word3=imresize(word3,[40 20]);
- word4=imresize(word4,[40 20]);
- word5=imresize(word5,[40 20]);
- word6=imresize(word6,[40 20]);
- word7=imresize(word7,[40 20]);
- subplot(5,7,15),imshow(word1),title('1');
- subplot(5,7,16),imshow(word2),title('2');
- subplot(5,7,17),imshow(word3),title('3')
- subplot(5,7,18),imshow(word4),title('4');
- subplot(5,7,19),imshow(word5),title('5');
- subplot(5,7,20),imshow(word6),title('6');
- subplot(5,7,21),imshow(word7),title('7');
- imwrite(word1,'1.jpg');
- imwrite(word2,'2.jpg');
- imwrite(word3,'3.jpg');
- imwrite(word4,'4.jpg');
- imwrite(word5,'5.jpg');
- imwrite(word6,'6.jpg');
- imwrite(word7,'7.jpg');
图17 归一化后的单个字符图像:
经过对车牌各个字符切割成单个图像以后,就剩下最后一个步骤对这些图像进行识别。在本文中,我们选择一种模式匹配方法来识别车牌字符。首先,我们需要创建一个符号的二值化图像的样本库,然后在剪切后将所有符号与每个符号的二值化图像相减,得到的1值像素最少的图像即为之别结果。调用具有不同序列号的样本库进行车牌汉字识别和字母数字识别。如图18所示。
实现代码如下:
- for I=1:7 %I为待识别的字符位
-
- ii=int2str(I); %整形数据转化为字符串类型
-
- t=imread([ii,'.jpg']);
-
- MBK=imresize(t,[40 20],'nearest'); %缩放处理
-
- if l==1 %车牌号第一位为汉字识别,使用37-53号样本库
-
- kmin=37;
-
- kmax=53;
-
- elseif l==2 %车牌号第二位为 A~Z 大写字母识别,使用11-36号样本库
-
- kmin=11;
-
- kmax=36;
-
- else l>=3; %车牌号第三位及以后是字母和数字识别,使用1-36号样本库
-
- kmin=1;
-
- kmax=36;
-
- end
-
- for k2=kmin:kmax
-
- fname=strcat('样本库\',liccode(k2),'.bmp');
-
- YBK = imread(fname); %调用样本库图像文件
-
- for i=1:40
-
- for j=1:20
-
- 图片JPG(i,j)=模板库MBK(i,j) - 样本库YBK(i,j);
-
- end
-
- End
图18车牌识别结果:
6.展望
本文虽然实现了对大部分车牌的识别,建立了车牌识别系统,但是对于某些情况下的车牌识别效率还有待提升,如车牌污损、天气情况恶劣、车牌倾斜角度大、车牌图像拍摄模糊等一系列状况考虑不够周全。希望对这几种状况可以开发出新的算法进行处理,提升识别效率。本文中描述的系统只能识别在蓝色背景上带有白色字符的车牌图像,而无法识别其他类型的车牌,例如黄色背景上的白色字符,绿色背景上的白色字符以及警用车牌。所以该系统还有待提升,未来可以添加多个类型牌照的识别。
7.学习与交流
如果文中有何不足之处还请大家多多指教,学习与交流可以发送邮件到: qq1067348722@163.com 或者加微信进行学习与交流。文中只展现关键源代码仅供参考,如需全部代码可以私信(有偿)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。