GUI框架源码: https://download.csdn.net/download/weixin_44748303/12682333
一、设计原理及设计方案
1.系统简述
一个完整的车牌识别系统闭应包括车辆检测、图像采集、图像预处理、车牌定位、字符分割、字符识别等单元。当车辆到达触发图像采集单元时,系统采集当前的视频图像。车辆识别单元对图像进行处理,定位出牌照位置,再将车牌中的字符分割出来进行识别,然后组成车牌号码输出。车牌识别系统原理如图l所示。
(1)图像预处理:对汽车图像进行图像转换、图像增强和边缘检测等。
(2)车牌定位:从预处理后的汽车图像中分割出车牌图像。即在一幅车辆图像中找到车牌所在的位置。
(3)字符分割:对车牌图像进行几何校正、去噪、二值化以及字符分割以从车牌图像中分离出组成车牌号码的单个字符图像
(4)字符识别:对分割出来的字符进行预处理(二值化、归一化),然后分析提取,对分割出的字符图像进行识别给出文本形式的车牌号码。
为了用于牌照的分割和牌照字符的识别,原始图象应具有适当的亮度,较大的对比度和清晰可辩的牌照图象。但由于该系统的摄像部分工作于开放的户外环境,加之车辆牌照的整洁度、自然光照条件、拍摄时摄像机与牌照的矩离和角度以及车辆行驶速度等因素的影响,牌照图象可能出现模糊、歪斜和缺损等严重缺陷,因此需要对原始图象进行识别前的预处理。
牌照的定位和分割是牌照识别系统的关键技术之一,其主要目的是在经图象预处理后的原始灰度图象中确定牌照的具体位置,并将包含牌照字符的一块子图象从整个图象中分割出来,供字符识别子系统识别之用,分割的准确与否直接关系到整个牌照字符识别系统的识别率。
由于拍摄时的光照条件、牌照的整洁程度的影响,和摄像机的焦距调整、镜头的光学畸变所产生的噪声都会不同程度地造成牌照字符的边界模糊、细节不清、笔划断开或粗细不均,加上牌照上的污斑等缺陷,致使字符提取困难,进而影响字符识别的准确性。因此,需要对字符在识别之前再进行一次针对性的处理。
车牌识别的最终目的就是对车牌上的文字进行识别。识别方法目前主要有基于模板匹配算法和基于人工神经网络算法。
2.图像预处理
2.1灰度变换
输入的彩色图像包含大量颜色信息,会占用较多的存储空间,且处理时也会降低系统的执行速度,因此对图像进行识别等处理时.常将彩色图像转换为灰度图像,以加快处理速度。可对图像进行灰度化处理、提取背景图像、增强处理、图像二值化,边缘检测、滤波等处理。然后采用robert算子进行边缘检测,再用imopen和imclose对所得二值图像作开、闭操作进行滤波。
彩色图像分为R、G、B三个分量,分别显示出红、绿、蓝等各种颜色,灰度化就是使彩色的R、G、B 分量相等的过程。灰度值大的像素点比较亮(像素值最大为255,为白色) ,反之比较暗(像素值最小为 0,是黑色) 。
图像灰度化的算法主要有以下 3 种:
1)最大值法:使转化后R、G、B的值等于转化前 3 个值中最大的一个,即:R=G=B=max(R,G,B),这种方法转换的灰度图亮度很高。
2)平均值法:使转化后R、G、B的值为转化前R、G、B的平均值 R=G=B=(R+G+B)/3 这种方法产生的灰度图像比较柔和。
3)加权平均值法:按照一定的权值,对R、G、B的值加权平均,即: R=G=B=( R+ G+ B)/3,其中 、 、 分别为 R、G、B 的权值。 、 、 取不同的值,将形成不同的灰度图像。由于人眼对绿色最为敏感,红色次之,对蓝色的敏感性最低,因此使 > > 将得到较易识别的灰度图像。一般情况下,当 =0.299、 =0.587、 =0.114时,得到的灰度图像效果最好。
2.2边缘提取
数字图像的边缘检测是图像分割、目标区域的识别、区域形状提取等图像分析领域十分重要的基础。边缘是图像的重要特征,图像理解和分析的第一步往往就是边缘检测。目前,边缘检测已成为计算机视觉研究领域最活跃的课题之一,在工程应用中占有十分重要的地位。车牌的一个重要特征就是在该区域存在大量的边缘信息,所以边缘检测对于我们进行车牌识别来说也是相当重要的。
边缘是以图像的局部特征不连续的形式出现的,也就是指图像局部亮度变化最显著的部分,如灰度值的突变、颜色的突变、纹理结构的突变等,同时边缘也是不同区域的分界处。图像边缘有方向和幅度两个特性,通常沿边缘的走向灰度变化平缓,垂直于边缘走向灰度变化剧烈。由于边缘是图像上灰度变化最剧烈的地方,传统的边缘检测就利用这个特点,通过计算图像中像素的梯度值来确定边缘点。
常用的图像边缘提取算子有Roberts算子、sobel算子、Prewitt算子、Laplacian算子等,它们的模板分别如下:
(1)Roberts梯度算子:
(2)Sobel算子:
(3)Prewitc算子:
(4)Laplacian算子:
3.车牌定位
自然环境下,汽车图像背景复杂,光照不均匀,在自然背景中准确地确定牌照区域是整个图像识别过程中的关键。首先对采集到的图像进行大范围相关搜索,找到符合汽车牌照特征的若干区域作为候选区,然后对这些侯选区域做进一步分析、评判,最后选定一个最佳区域作为牌照区域。将其从图像中分割嘲出来,同时要考虑车牌倾斜问题。算法流程如下:
(1)对二值图像进行区域提取。计算并比较区域特征参数,提取车牌区域。进行闭运算,可使得水平相邻的边缘连接成为连通区域;进行开运算可使得车牌区域与其它背景区域分开,成为独立的连通域。
(2)计算包含所标记区域的最小宽和高。并根据先前知识,提取并显示更接近的车牌二子值图。
(3)通过计算车牌旋转角度解决车牌倾斜问题。由于车牌倾斜导致投影效果峰谷不明显,需车牌矫正处理,采取线性拟合方法,计算出车牌上边或下边图像值为1的点拟合直线与水平X轴的夹角。
4.字符分割
完成牌照区域的定位后,再将牌照区域分割为单个字符,可采用垂直投影法。由于字符在垂直方向上的投影必然在字符间或字符内的间隙处取得局部最小值.并且该位置应满足牌照的字符书写格式、字符、尺寸限制等条件。利用垂直投影法实现复杂环境下汽车图像中的字符分割效果较好。
通过分析计算字符的水平投影和垂直投影,可获得车牌字符高度、字符顶行与尾行、字符宽度、每个字符的中心位置,以方便提取分割字符。然后计算车牌垂直投影,去掉车牌垂直边框,获取车牌及字符平均宽度。最后计算车牌每个字符的中心位置和最大字符宽度,提取分割字符,其算法流程如图3所示。
图3车牌分割的MATLAB算法流程
此处采用的方法为寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割。算法如下:
5.字符识别
字符识别方法主要有基于模板匹配算法和基于人工神经网络算法。基于模板匹配算法是首先将分割后的字符二值化,并将其尺寸缩放为字符数据库中模板的大小,然后与所有模板进行匹配,最后选取最佳匹配作为结果。建立数字库对该方法在车牌识别过程中很重要,数字库准确才能保证检测出的数据正确。基于人工神经元网络的算法有两种,一种是先对特征提取待识别字符,然后用所获得的特征训练神经网络分配器;另一种是直接将待处理图像输入网络由网络自动实现特征提取直至识别结果。模板匹配实现简单,当字符较规整时,对字符图像的缺损、污迹干扰适应力强且识别率高。因此,这里将模板匹配作为车牌字符识别的主要方法。
模板匹配是图象识别方法中最具代表性的基本方法之一,它是将从待识别的图象或图象区域f(i,j)中提取的若干特征量与模板T(i,j)相应的特征量逐个进行比较,计算它们之间规格化的互相关量,其中互相关量最大的一个就表示期间相似程度最高,可将图象归于相应的类。也可以计算图象与模板特征量之间的距离,用最小距离法判定所属类。然而,通常情况下用于匹配的图象各自的成像条件存在差异,产生较大的噪声干扰,或图象经预处理和规格化处理后,使得图象的灰度或像素点的位置发生改变。在实际设计模板的时候,是根据各区域形状固有的特点,突出各类似区域之间的差别,并将容易由处理过程引起的噪声和位移等因素都考虑进去,按照一些基于图象不变特性所设计的特征量来构建模板,就可以避免上述问题。
二. 设计的步骤和结果
-
获取图像
[fn,pn,fi]=uigetfile(’*.bmp’,‘选择图片’);
Scolor=imread([pn fn]);
-
图像灰度化
Sgray = rgb2gray(Scolor);%rgb2gray转换成灰度图
-
图像增强
s=strel(‘disk’,13);%strei函数13
Bgray=imopen(Sgray,s);%打开sgray s图像
Egray=imsubtract(Sgray,Bgray);%两幅图相减
-
边缘提取
图像中车辆牌照是具有比较显著特征的一块图象区域,这此特征表现在:近似水平的矩形区域;其中字符串都是按水平方向排列的;在整体图象中的位置较为固定。正是由于牌照图象的这些特点,再经过适当的图象变换,它在整幅中可以明显地呈现出其边缘。边缘提取是较经典的算法,此处边缘的提取采用的是Roberts算子。
grd=edge(Egray,‘robert’,0.09,‘both’);
se=[1;1;1]; %线型结构元素
I3=imerode(grd,se); %腐蚀图像
-
开闭运算进行滤波
牌照图象经过了以上的处理后,牌照区域已经十分明显,而且其边缘得到了勾勒和加强。此时可进一步确定牌照在整幅图象中的准确位置。这里选用数学形态学的方法,基本思想是用具有一定形态的机构元素去量度和提取图像中的对应形状以达到对图像分析和识别的目的。数学形态学的应用可以简化图像数据,保持它们基本的形态特征,并除去不相干的结构。在本程序中用到了开闭两个基本运算,最后还用了bwareaopen来去除对象中不相干的小对象。
bg1=imclose(I3,strel(‘rectangle’,[8,18]));%取矩形框的闭运算即平滑8,18
bg3=imopen(bg1,strel(‘rectangle’,[8,14]));%取矩形框的开运算8,18
bg2=bwareaopen(bg3,700);%去除聚团灰度值小于700的部分
-
车牌初步定位
通过比较累计行像素灰度值和列像素灰度值确定车牌的真实位置。
[y,x,]=size(bg2);
I6=double(bg2);
%绘制行曲线图
Y1=zeros(y,1);%y行1列的零矩阵 累计行像素灰度值
for i=1:y
for j=1:x
if(I6(i,j,1)==1)
Y1(i,1)= Y1(i,1)+1;
end
end
end
[temp, MaxY]=max(Y1);
PY1=MaxY;
while ((Y1(PY1,1)>=50)&&(PY1>1))
PY1=PY1-7;
end
PY2=MaxY;
while ((Y1(PY2,1)>=50)&&(PY2<y))
PY2=PY2+7;
end
%绘制列曲线图
X1=zeros(1,x);% 累计列像素灰度值
for j=1:x
for i=PY1:PY2
if(I6(i,j,1)==1)
X1(1,j)= X1(1,j)+1;
end
end
end
PX1=1;
while ((X1(1,PX1)❤️)&&(PX1<x))
PX1=PX1+1;
end
PX2=x;
while ((X1(1,PX2)❤️)&&(PX2>PX1))
PX2=PX2-1;
end
DW=Scolor(PY1:PY2,PX1:PX2,:);%车牌定位后图像
-
进一步车牌定位
经过上述方法分割出来的车牌图像中存在目标物体、背景还有噪声,要想从图像中直接提取出目标物体,最常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群,即对图像二值化。然后通过行像素点的累计值去除顶端和底端不感兴趣的地方。
if isrgb(DW)
I1 = rgb2gray(DW); %将RGB图像转化为灰度图像
else I1=DW;
end
g_max=double(max(max(I1)));
g_min=double(min(min(I1)));
T=round(g_max-(g_max-g_min)/3); % T 为二值化的阈值
[m,n]=size(I1);% d:二值图像
imane_bw=im2bw(I1,T/256); %二值化车牌图像
[y1,x1,z1]=size(imane_bw);
I3=double(imane_bw);
TT=1;
%%%%%%%去除图像顶端和底端的不感兴趣区域%%%%%
Y1=zeros(y1,1);
for i=1:y1
for j=1:x1
if(I3(i,j,1)==1)
Y1(i,1)= Y1(i,1)+1 ;
end
end
end
Py1=1;Py0=1;
while ((Y1(Py0,1)<9)&&(Py0<y1))
Py0=Py0+1;
end
Py1=Py0;
while((Y1(Py1,1)>=9)&&(Py1<y1))
Py1=Py1+1;
end
I2=imane_bw(Py0:Py1,:????; %目标车牌区域
-
车牌字符分割
字符分割的算法很多,因为车牌字符间间隔较大,通常不会出现字符粘连情况,所以此处采用的方法为寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割。一般分割出来的字符要进行进一步的处理,以满足下一步字符识别的需要。但是对于车牌的识别,并不需要太多的处理就已经可以达到正确识别的目的。在此只进行了归一化处理,然后进行后期处理。
% 寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割
d=qiege(I2);
[m,n]=size(d);
k1=1;k2=1;s=sum(d);j=1;
while j~=n
while s(j)0
j=j+1;
end
k1=j;
while s(j)~=0 && j<=n-1
j=j+1;
end
k2=j-1;
if k2-k1>=round(n/6.5)
[val,num]=min(sum(d(:,[k1+5:k2-5])));
d(:,k1+num+5)=0; % 分割
end
end
% 再切割
d=qiege(d);
% 切割出 7 个字符
y1=10;y2=0.25;flag=0;word1=[];
while flag0
[m,n]=size(d);
left=1;wide=0;
while sum(d(:,wide+1))~=0
wide=wide+1;
end
if wide<y1 % 认为是左侧干扰
d(:,[1:wide])=0;
d=qiege(d);
else
temp=qiege(imcrop(d,[1 1 wide m]));
[m,n]=size(temp);
all=sum(sum(temp));
two_thirds=sum(sum(temp([round(m/3):2round(m/3)]????));
if two_thirds/all>y2
flag=1;word1=temp; % WORD 1
end
d(:,[1:wide])=0;d=qiege(d);
end
end
[word2,d]=getword(d);% 分割出第二个字符
[word3,d]=getword(d); % 分割出第三个字符
[word4,d]=getword(d); % 分割出第四个字符
[word5,d]=getword(d); % 分割出第五个字符
[word6,d]=getword(d); % 分割出第六个字符
[word7,d]=getword(d); % 分割出第七个字符
[m,n]=size(word1);
%归一化大小为2214
word1=imresize(word1,[22 14]);
……
word7=imresize(word7,[22 14]);
imwrite(word1,‘1.jpg’);
……
imwrite(word7,‘7.jpg’);
-
车牌字符识别
此处采用相减的方法来求得字符与模板中哪一个字符最相似,然后找到相似度最大的输出。汽车牌照的字符一般有七个,大部分车牌第一位是汉字,通常代表车辆所属省份,紧接其后的为字母与数字。车牌字符识别与一般文字识别在于它的字符数有限,汉字共约30多个,大写英文字母26个,数字10个。
首先取字符模板,接着依次取待识别字符与模板进行匹配,将其与模板字符相减,得到的非0值越少那么就越匹配。把每一幅相减后的图的非0值个数保存,即为识别出来的结果。
源程序:
liccode=char([‘0’:‘9’ ‘A’:‘Z’ ‘藏川甘赣贵桂黑沪吉济冀津晋京警兰辽领鲁蒙闽宁青琼陕使苏皖湘新学渝豫粤云浙’]); %建立自动识别字符代码表
tt=1;
l=1;
for I=1:7
ii=int2str(I);
t=imread([ii,’.jpg’]);
t=255-t;
level=graythresh(t);
t=im2bw(t,level);
SegBw2=imresize(t,[22 14],‘nearest’);
if tt1 %第一位汉字识别
kmin=37;
kmax=72;
t=~t;
SegBw2=imresize(t,[22 14],‘nearest’);
elseif tt2 %第二位 A~Z 字母识别
kmin=11;
kmax=36;
else %第三位以后是字母或数字识别
kmin=1;
kmax=36;
end
for k2=kmin:kmax
fname=strcat(‘code module\Sam’,liccode(k2),’.jpg’);
SamBw22 = imread(fname);
SamBw22 = rgb2gray(SamBw22);
SamBw2=imresize(SamBw22,[22 14],‘nearest’);
level=graythresh(SamBw2);
SamBw2=im2bw(SamBw2,level);
for i=1:22
for j=1:14
SubBw2(i,j)=SegBw2(i,j)-SamBw2(i,j);
end
end
% 以上相当于两幅图相减得到第三幅图
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(Error1MinError);
if tt1
findc=findc+36;
end
if tt2
findc=findc+10;
end
tt=tt+1;
res=liccode(findc);
shibiejieguo(1,l)=res;
l=l+1;
end
%%%getword子函数为:
function [word,result]=getword(d)
word=[];flag=0;y1=8;y2=0.5;
while flag0
[m,n]=size(d);
wide=0;
while sum(d(:,wide+1))~=0 && wide<=n-2
wide=wide+1;
end
temp=qiege(imcrop(d,[1 1 wide m]));
[m1,n1]=size(temp);
if wide<y1 && n1/m1>y2
d(:,[1:wide])=0;
if sum(sum(d))~=0
d=qiege(d); % 切割出最小范围
else word=[];flag=1;
end
else
word=qiege(imcrop(d,[1 1 wide m]));
d(:,[1:wide])=0;
if sum(sum(d))~=0;
d=qiege(d);flag=1;
else d=[];
end
end
end
result=d;
%%%qiege子函数为:
function e=qiege(d)
[m,n]=size(d);
top=1;bottom=m;left=1;right=n; % init
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]);
得出车牌检测结果为:陕A906L4
-
对话框显示及语音朗读
msgbox(shibiejieguo,‘识别结果’);
duchushengyin(shibiejieguo);
%%%%duchushengyin子函数为:
function shengyin=duchushengyin(shibiejieguo)
wavplay(wavread(‘audio\车牌检测.wav’),44000);
for i=1:7
if shibiejieguo(1,i)‘桂’
wavplay(wavread(‘audio\桂.wav’),44000);
elseif shibiejieguo(1,i)‘陕’
wavplay(wavread(‘audio\陕.wav’),44000);
……
elseif shibiejieguo(1,i)‘A’
wavplay(wavread(‘audio\A.wav’),44000);
……
elseif shibiejieguo(1,i)‘0’
wavplay(wavread(‘audio\0.wav’),44000);
……
elseif shibiejieguo(1,i)==‘9’
wavplay(wavread(‘audio\9.wav’),44000);
end
end
wavplay(wavread(‘audio\车牌检测完毕.wav’),44000);
11. 设计GUI界面
界面设计如下:
界面可显示车辆的原始图像,车牌定位图像,进一步定位的车牌区域,车牌字符分割后的结果以及车牌的识别结果。浏览文件按钮可在文件夹中选择要处理的图片,然后按下确认按钮,开始处理,按下结束后,所有图片及字符显示均清除。
|
请发表评论