图像处理车牌识别系统设计实验报告资料.docx
《图像处理车牌识别系统设计实验报告资料.docx》由会员分享,可在线阅读,更多相关《图像处理车牌识别系统设计实验报告资料.docx(32页珍藏版)》请在冰豆网上搜索。
图像处理车牌识别系统设计实验报告资料
!
图像处理
、
班别:
11医学应用
(2)班
组长:
组员:
指导老师:
¥
一、摘要2
二、设计原理3
1、车牌的定位研究3
…
2、字符分割的研究3
3、字符识别的研究3
三、详细设计步骤3
1、车牌定位4
图像的预处理4
车牌定位7
2、字符分割10
对读入图像进行预处理操作11
"
图像校正12
去除水平方向上的边框13
去除垂直方向上的边框15
去除车牌上的圆点17
3、字符识别20
建立字符模板数据库20
对分割字符进行匹配22
4、系统界面的实现25
》
四、设计结果分析29
五、设计体会29
车牌识别系统的设计
一、摘要
车牌是一辆汽车独一无二的信息,因此,对车辆牌照的识别技术可以作为辨识一辆车最为有效的方法。
随着ITS(智能交通系统)的高速发展,对车牌识别技术的研究也随之发展。
从根本上讲,牌照识别应用了先进的图像处理,模式识别,人工智能技术来获取,处理,解释,记录拍照的图像。
目前,汽车牌照的自动识别技术已经得到了广泛应用。
汽车牌照自动识别整个处理过程分为预处理、边缘提取、车牌定位、字符分割、字符识别五大模块,其中字符识别过程主要由以下3个部分组成:
①正确地分割文字图像区域;②正确的分离单个文字;③正确识别单个字符。
用MATLAB软件编程来实现每一个部分,最后识别出汽车牌照。
在研究的同时对其中出现的问题进行了具体分析、处理。
2、设计原理
~
车牌自动识别是一项利用车辆的动态视频或静态图像进行车牌号码、车牌颜色自动识别的模式识别技术。
其核心包括车牌定位算法、车牌字符分割算法和字符识别算法等。
&
图1牌照识别系统原理图
主要研究内容如下:
)
1、车牌的定位研究。
先进行图像的预处理,包括RGB彩色图像的灰度化、图像灰度拉伸、图像边缘检测、灰度图的二值化等;车牌定位采用基于水平和垂直投影分布特征的方法。
2、字符分割的研究。
先对定位后的车牌图像进行预处理,然后按照车牌的先验信息,用区域增长算法来确定候选车牌的字符区域。
3、字符识别的研究。
对于提取出的单个字符,先进行归一化操作,再与给定的模板做对比,识别出字符。
三、详细设计步骤
1.车牌定位:
车辆牌照识别整个系统主要是由车牌定位和字符识别两部分组成,其中车牌定位又可以分为图像预处理及边缘提取模块和牌照的定位;
:
流程图:
图像的预处理
-
为了用于牌照的分割和牌照字符的识别,原始图象应具有适当的亮度,较大的对比度和清晰可辩的牌照图象。
但由于该系统的摄像部分工作于开放的户外环境,加之车辆牌照的整洁度、自然光照条件、拍摄时摄像机与牌照的矩离和角度以及车辆行驶速度等因素的影响,牌照图象可能出现模糊、歪斜和缺损等严重缺陷,因此需要对原始图象进行识别前的预处理。
(1)一般的车牌识别只对小对象进行移除,但是有时候因为拍照原因,即使对图像进行了很好的预处理,还是不能排除一些比较大的又和车牌比较相像的地方,例如图
(1)中,车后面的玻璃窗仅仅进行灰度处理和形态学处理,平滑处理是无法排除其对车牌定位的影响的,因此需要对大对象移除(移除大对象前需对图像进行统一化--压缩)。
图
(1)
实现的代码:
img=image;
I=img;
[x,y,z]=size(img);
@
ifx>2000||y>2000
img=img(1:
2:
end,1:
2:
end,:
);
[x,y,z]=size(img);
end
hsi=rgb2hsi(img);
fori=1:
x
forj=1:
y
if(hsi(i,j,1)<=&&hsi(i,j,1)>=&&hsi(i,j,2)>;%0.
$
hsi(i,j,2)=0;
hsi(i,j,3)=1;
;
else
hsi(i,j,2)=0;
hsi(i,j,3)=0;
end
end
]
end
origonImg=hsi2rgb(hsi);
rgbnew=origonImg;
(2)灰度校正:
由于牌照图象在拍摄时受到种种条件的限制和干扰,图象的灰度值往往与实际景物不完全匹配,这将直接影响到图象的后续处理。
如果造成这种影响的原因主要是由于被摄物体的远近不同,使得图象中央区域和边缘区域的灰度失衡,或是由于摄像头在扫描时各点的灵敏度有较大的差异而产生图象灰度失真,或是由于曝光不足而使得图像的灰度变化范围很窄。
这时就可以采用灰度校正的方法来处理,增强灰度的变化范围、丰富灰度层次,以达到增强图象的对比度和分辨率。
灰度校正图graynew=rgb2gray(rgbnew);
!
(3)边缘检测:
边缘是指图像局部亮度变化显著的部分,是图像风、纹理特征提取和形状特征提取等图像分析的重要基础。
所以在此我们要对图像进行边缘检测。
图象增强处理对图象牌照的可辩认度的改善和简化后续的牌照字符定位和分割的难度都是很有必要
实现代码:
origonImg=hsi2rgb(hsi);
rgbnew=origonImg;
graynew=rgb2gray(rgbnew);
graynew=imfill(graynew,'holes');
$
fori=1:
3
se1=[111;111;111];
graynew=imdilate(graynew,se1);
se=[1;1;1];
graynew=imerode(graynew,se);%腐蚀Imerode(X,SE).其中X是待处理的像,%SE是结构元素对象
graynew=getcenter(graynew);
graynew=double(graynew);
[rowcol]=size(graynew);
`
车牌定位
牌照的定位是在经图象预处理后的原始灰度图象中确定牌照的具体位置,并将包含牌照字符的一块子图象从整个图象中分割出来,供字符识别子系统识别之用。
图为定位出的车牌
实现代码:
车牌裁剪:
[rowcol]=size(graynew);
colArray=zeros(row,1);
!
fori=1:
row
forj=1:
col
if(graynew(i,j,1)==1)
colArray(i,1)=colArray(i,1)+1;
end
end
end
[maxcountmaxIndex]=max(colArray);
;
roughY=maxIndex;
while((colArray(roughY,1)>=5)&&(roughY>1))
roughY=roughY-1;
end
y1=roughY;
roughY=maxIndex;
while((colArray(roughY,1)>=5)&&(roughYroughY=roughY+1;
;
end
y2=roughY;
rowArray=zeros(1,col);
fori=1:
col
forj=y1:
y2
ifgraynew(j,i)==1
rowArray(1,i)=rowArray(1,i)+1;
end
'
end
end
[maxcountmaxIndex]=max(rowArray);
roughX=maxIndex;
while((rowArray(1,roughX)>=5)&&(roughX>1))
roughX=roughX-1;
end
x1=roughX;
}
roughX=maxIndex;
while((rowArray(1,roughX)>=5)&&(roughX
roughX=roughX+1;
end
x2=roughX;
dw=img(y1:
y2,x1:
x2,:
);
greenframe=drawframe(img,y1,y2,x1,x2);
imwrite(greenframe,'imgAfterLocation/');
|
imwrite(dw,'imgAfterLocation/');
2、字符分割:
传统的字符分割方法有投影法、模板匹配法、聚类分析法。
由于投影法比较准确、编程较简单,且易于实际操作,能满足在复杂环境下,所以我们采用的是投影法分割车牌字符。
车牌分割总流程图:
|
各部分代码实现和运行效果:
、对读入图像进行预处理操作
I=imread('imgAfterLocation/');%读取图像
I1=rgb2gray(I);%彩色图像转化为灰度图像
T=graythresh(I1);%找到灰度图像的阈值
[y,x,z]=size(I1);%计算I1各维的大小
$
Se=strel('disk',fix(y/45));%创建一个平坦的圆盘形结构元素
I2=imopen(I1,Se);%取圆盘形的开运算
subplot(2,2,3);%图一的第三幅图
imshow(I2),title('开运算后图像');
Se=strel('diamond',fix(y/140));%创建一个平坦的菱形结构元素
I3=imclose(I2,Se);%取菱形结构的闭运算
I4=double(I3);%变为双精度
(
图像校正
代码:
bw1=edge(I1,'sobel','horizontal');%用Sobel水平算子对图像边化
figure,imshow(bw1)
bw1=imcrop(bw1,[00500100]);%对图像进行剪切,保留图像的%一条直线,减小运算量
^
figure,imshow(bw1)
theta=0:
179;%定义theta角度范围
r=radon(bw1,theta);%对图像进行Radon变换
figure,imshow(r)
[m,n]=size(r);
c=90;
fori=1:
m
forj=1:
n
—
ifr(1,1)r(1,1)=r(i,j);
c=j;
end
end
end%检测Radon变换矩阵中的峰值所对应的列坐标
rot=90-c;%确定旋转角度
&
A=imrotate(I1,rot,'crop');%对图像进行旋转矫正
计算行方向的像素,用来去除行方向上的边框
代码:
计算行像素:
Y1=zeros(y,1);
fori=1:
y
forj=1:
x
,
if(I4(i,j,1)==1)
Y1(i,1)=Y1(i,1)+1;%计算I3第j列有几个一
end
end
end
figure
(2);
plot(Y1,0:
y-1),title('行方向像素点灰度值累计和'),xlabel('累计像素量'),ylabel('行');
—
去除行方向边框:
Py0=fix(y/2);
Py1=fix(y/2)+1;
while((Y1(Py0,1)>=30)&&(Py0>2))
Py0=Py0-1;%找到去除边框后上边的位置
end
while((Y1(Py1,1)>=30)&&(Py1Py1=Py1+1;%找到去除边框后下边的位置
)
end
Z1=I4(Py0:
Py1,:
:
);%将二值图像上下边框去除
figure(3);
imshow(Z1),title('将二值图像上下边框去除后图像');
计算列方向的像素,用来去除垂直方向上的边框
代码:
[y,x,z]=size(Z1);%计算此时图像的大小
!
计算列像素
X1=zeros(1,x);
forj=1:
x
fori=1:
y
if(Z1(i,j,1)==1)
X1(1,j)=X1(1,j)+1;%计算I3第j列有几个一
end
end
>
end
figure(4);
plot(0:
x-1,X1),title('列方向像素点灰度值累计和'),xlabel('列值'),ylabel('累计像素');
去除垂直边框
x1=fix(x/2)+1;
fori=1:
5
while(i~=5)
"
while((X1(1,x1)>=15)&&(x1x1=x1+1;%找到去除边框后右边的位置
end
i=i+1;
while((X1(1,x1)<15)&&(x1x1=x1+1;%从车牌中间开始寻找字符间隙,直到找到第四个间隙%为止,即找到去除边框后车牌右边的位置
end
end
#
end
x0=fix(x*45/440);%找到第一个字符的位置
fori=1:
2
while(i~=2)
while((X1(1,x0)>=5)&&(x0>2))
x0=x0-1;%从车牌的第一个字符开始寻找第一个字符间隙,找到%去除边框左边的位置
end
i=i+1;
^
while((X1(1,x0)<5)&&(x0>1)&&i~=2)
x0=x0-1;%找到去除边框后左边的位置
end
end
end
Z2=Z1(:
x0:
x1,:
);%将二值图像左右边框去除
figure(5);
imshow(Z2),title('将二值图像垂直边框去除后图像');
;
再次计算列方向的像素,用来去除车牌上的圆点
代码:
[y,x,z]=size(Z2);%计算此时图像的大小
X1=zeros(1,x);
forj=1:
x
fori=1:
y
\
if(Z2(i,j,1)==1)
X1(1,j)=X1(1,j)+1;%计算I3第j列有几个一
end
end
End
去除车牌中的圆点:
[y,x,z]=size(Z2);
Z2=double(Z2);
,
x1=fix(x*105/409);
x2=fix(x*128/409);
fori=1:
y
forj=x1:
x2
Z2(i,j)=0;
end
end
figure(6);
·
imshow(Z2),title('去除圆点后图像');
用投影法分割车牌,把分割出来的子图转成标准子图
代码:
用投影法分割
Px0=1;
:
Px1=1;
y=fix(x*90/409);
fori=1:
7
while((X1(1,Px0)<10)&&(Px0Px0=Px0+1;%找到待分割字符左边的位置
end
Px1=Px0;
a=1;
:
while(((X1(1,Px1)>=10)&&(Px1Px1=Px1+1;%找到待分割字符右边的位置
a=Px1-Px0;
end
Z3=Z2(:
Px0:
Px1,:
);%二值化图像分割后
figure(7);
subplot(1,7,i);
imshow(Z3);%将二值化图像分割后显示出来
]
变换为标准子图
Z4=imresize(Z3,[4020]);%将分割后的二值图变换为标准子图
figure
(1);
subplot(1,7,i);
imshow(Z4),title('标准子图');%将标准子图显示出来
Px0=Px1;
imwrite(Z4,strcat('imgAfterSplit/',num2str(i),'.jpg'));%把标准子图存到imagAfterSplit中
$
End
3、字符识别:
牌照字符识别:
字符识别方法目前主要有基于模板匹配算法和基于人工神经网络算法。
基于模板匹配算法首先将分割后的字符二值化,并将其尺寸大小缩放为字符数据库中模板的大小,然后与所有的模板进行匹配,最后选最佳匹配作为结果。
基于人工神经元网络的算法有两种:
一种是先对待识别字符进行特征提取,然后用所获得特征来训练神经网络分配器;另一种方法是直接把待处理图像输入网络,由网络自动实现特征提取直至识别出结果。
实际应用中,牌照识别系统的识别率与牌照质量和拍摄质量密切相关。
牌照质量会受到各种因素的影响,如生锈、污损、油漆剥落、字体褪色、牌照被遮挡、牌照倾斜、高亮反光、多牌照、假牌照等等;实际拍摄过程也会受到环境亮度、拍摄亮度、车辆速度等等因素的影响。
这些影响因素不同程度上降低了牌照识别的识别率,也正是牌照识别系统的困难和挑战所在。
为了提高识别率,除了不断的完善识别算法,还应该想办法克服各种光照条件,使采集到的图像最利于识别。
本系统字符识别方法采用基于模板匹配算法。
建立字符模板数据库
#
模板库的合理建造是字符识别准确的关键之一,所以在字符识别之前必须把模板库设置好。
汽车牌照的字符一般有7个,大部分车牌第一位是汉字,通常代表车辆所属省份,或是军种警别等有特定含义的字符简称;紧接其后的为字母与数字。
车牌字符识别与一般文字识别在于它的字符数有限,十个阿拉伯数字0~9,26个大写英文字母A~Z以及相关的车牌用汉字:
京、沪、苏、台、港、澳、甲、乙、丙、使、领、学、试、境、消、边、警等,以及新式军牌中的汉字南、兰、广、北、沈、济、空、海等;车牌颜色:
蓝、白、黑、黄等。
所以建立字符模板库也极为方便。
为了提高识别的准确率,本系统的为每个字符都建立一个模板库,并且可以动态添加字符到模板库,随着字符模板的增加,识别率也随之提高。
建立模板数据库时必须对这些图片进行统一处理,因为对前面处理分割后的车牌图像的测量得知单个字符的最佳宽高比是1:
2,所以将这些图片归一化为40×20大小;因为之后的字符识别考虑使用模板匹配算法进行字符识别,所以再将上面归一化后的模板图像的样本排列在一起构成40×20的矩阵样本。
以下分别是粤和A字符模板:
!
对分割字符进行匹配
程序代码(最终返回识别的车牌号):
function[CarNum]=recognition()
codes=char(['0':
'9''A':
'Z''京津沪渝吉辽鲁豫冀鄂湘晋青皖苏赣浙闽粤琼陕甘云川贵黑藏蒙桂新宁']);
%建立自动识别字符代码表;'京津沪渝吉辽鲁豫冀鄂湘晋青皖苏赣浙闽粤琼陕甘云川贵黑藏蒙桂新宁'
%编号:
0-9分别为1-10;A-Z分别为11-36;
%京津沪渝吉辽鲁豫冀鄂湘晋青皖苏
)
%赣浙闽粤琼陕甘云川贵黑藏蒙桂新宁
%37--67
SubBw2=zeros(40,20);
l=1;
forI=1:
7
ii=int2str(I);%将整型数据转换为字符串型数据
t=imread(['imgAfterSplit/',ii,'.jpg']);%依次读入七位车牌字符
SegBw2=imresize(t,[4020],'nearest');%对读入的字符进行缩放
~
SegBw2=im2bw(SegBw2);
ifI==1%第一位汉字识别
kmin=37;kmax=67;
elseifI==2%第二位A~Z字母识别
kmin=11;kmax=36;
else%第三位以后是字母或数字识别;即I>=3
kmin=1;kmax=36;
end
(
index=getFinalTemp(kmin,kmax,codes,SegBw2,I);
CarNum(l)=codes(index);
l=l+1;
end
%xlabel(['第三步:
识别结果为:
',CarNum],'Color','b');
程序代码(返回最终识别的单个字符index下标):
/
function[index]=getFinalTemp(minIndex,maxIndex,codes,SegBw2,numIndex)
ifnumIndex<3%后五位不能出现i、o字母;
fori=minIndex:
maxIndex
path=strcat('template/',codes(i));
%调用getFromLib遍历文件夹找出同一字符最佳的模板
maxSame=getFromLib(path,SegBw2);
near(i)=maxSame;%记录下字符与模板i同的点个数
end
:
else
fori=minIndex:
maxIndex
%ifi~=find(codes='l')&&i~=find(codes='O
ifcodes(i)~='l'&&codes(i)~='O'
path=strcat('template/',codes(i));
%调用getFromLib遍历文件夹找出同一字符最佳的模板
maxSame=getFromLib(path,SegBw2);
near(i)=maxSame;%记录下字符与模板i同的点个数
(
end
end
end
nearest=max(near);%差别最小的,不同字符模板
index=find(near==nearest);%找出差别最小的模板的下标
程序代码(遍历单个字符模板库,返回最佳的模板):
。
function[maxSame]=getFromLib(path,carNum)
files=dir([path'/*.jpg']);
fori=1:
length(files)
file=imread([path'/'num2str(i)'.jpg']);
ifislogical(file)==0
filebw=im2bw(file);
else
filebw=file;
!
end
subImg=carNum-filebw;
%以上相当于两幅图相减得到第三幅图进行匹配
sameDots=subImg==0;
%记录下字符与模板相同的点个数
sumDots=sum(sameDots(:
));
arr(i)=sumDots;
end
|
maxSame=max(arr);
4、系统界面的实现:
界面我们小组一共分有了两个模块:
一个是父模块车牌识别系统,进行显图,定位,分割和识别的操作;
另一个是子模块是字符模块,是为了增加字符的模块进库,提高车牌的识别效率。
父模块——车牌识别系统
图一
界面分别有载入图片,车牌定位,车牌分割,车牌识别和增加字符模块五个按钮,每个按钮对应不同的功能。
载入车牌:
选择你需要识别的带有车牌的图片并显示出来在原始图片的位置。
车牌定位:
内部进行定位函数对车牌进行定位,并在原图上用黄线圈出车牌相应的位置。
车牌分割:
将定位好的车牌进行分割,分割出7个独立的字符模块。
车牌识别:
对每个分割出来的字符进行识别,并文本输出来。
增加字符模块:
点击进入子界面,进行字符模块的增加,提高车牌识别的效率。
效果如下图:
图二
子模块——字符模块
图三
字符模块分为5大部分,分别是车牌显示,选择添加模板的
|