实验报告用MATLAB实现车牌识别系统.docx
- 文档编号:17416528
- 上传时间:2023-07-25
- 格式:DOCX
- 页数:41
- 大小:750.18KB
实验报告用MATLAB实现车牌识别系统.docx
《实验报告用MATLAB实现车牌识别系统.docx》由会员分享,可在线阅读,更多相关《实验报告用MATLAB实现车牌识别系统.docx(41页珍藏版)》请在冰点文库上搜索。
实验报告用MATLAB实现车牌识别系统
图像处理大作业实验报告
--用MATLAB实现车牌识别系统
作者东南大学电子系李浩翔06006435
指导老师张雄
实验日期2010-1-10
索引:
实验目的
实验原理
实验步骤
1.预处理
2.边缘识别
3.小区块联通
4.车牌区域的识别并截取
5.字符截取
6.字符识别
实验思路分析
本程序的局限性
附录
附录1程序源代码
1.主程序
2.子函数(code)
附录2测试图像处理过程汇总
1.测试图像1
2.测试图像2
附录3参考文献及参考程序
实验目的(返回索引)
使用MATLAB对包含车牌的图片进行处理,利用算法识别出车牌所在的区域,并辨认其数字及字母,最后在屏幕上输出所识别出的车牌号。
实验原理(返回索引)
1.将拍摄下的彩色图像转换为灰度图,之后用中值滤波对灰度图像进行预处理,从而减少干扰信息。
2.使用sobel算子识别出图像的边缘,并转化为二值化图像。
并对二值化之后的图像进行卷积,加强边缘的轮廓。
3.用膨胀-再腐蚀的方法分别作用于图像的横轴与纵轴,将小块的联通区域连接起来,使车牌的形状更加清晰,为下一步的识别做好准备。
4.利用车牌长宽比的特性对各个联通区域进行判断,识别出车牌所在区域,并截取。
5.对截取出的车牌区域进行进一步的处理,分割出各个字符。
6.对分割出的字符进行特征判断,从而识别出具体的车牌号。
实验步骤(返回索引)
1.预处理(返回索引)
A.将拍摄下的彩色图像转换为灰度图,便于进行接下来的算法处理。
im_gray=rgb2gray(im);
图1拍摄下的图片
图2转换的灰度图
B.对灰度图进行中值滤波,减少干扰点对二值化运算结果的影响。
im_gray=medfilt2(im_gray,[33]);
图3进行中值滤波后的灰度图
C.将中值滤波后的灰度图用设定门限灰度的方法(取门限值为0.2)转化为二值化图像,在后继的车牌区域截取运算中作为源图像使用。
Image=im2bw(im_gray,0.2);
图4使用设定灰度门限的方法获得的二值化图像
2.边缘识别(返回索引)
A.利用sobel算子识别出图3中的边缘区域,并将其转换为二值化图像。
在转换后的二值化图像中,边缘区域被作为白点标出,而非边缘区域被黑色区域覆盖。
BW=edge(im_gray,'sobel');
图5识别出的边缘区域
B.使用卷积的方法,对图5的边缘区域进行加强,为下一步的运算做好准备。
msk=[00000;
01110;
01110;
01110;
00000;];
B0=conv2(double(BW),double(msk));
图6加强后的边缘区域
3.小区块联通(返回索引)
使用膨胀-再腐蚀的方法对图像进行三次处理,联通小区块,从而使车牌的形状更易于识别。
A.第一次处理,选用高为2宽为80的矩阵进行运算。
se=ones(2,80);
B1=imdilate(B0,se);
B2=imerode(B1,se);
图7第一次膨胀运算后
图8第一次腐蚀运算后
B.第二次处理,选用高为20宽为2的矩阵进行运算。
se=ones(20,2);
B3=imdilate(B2,se);
B4=imerode(B3,se);
图9第二次膨胀运算后
图10第二次腐蚀运算后
C.第三次处理,选用高为50宽为2的矩阵进行运算。
se=ones(50,2);
B5=imdilate(B4,se);
B6=imerode(B5,se);
图11第三次膨胀运算后
图12第三次腐蚀运算后
4.车牌区域的识别与截取(返回索引)
A.以图12为目标图像进行联通区域的标记,并用线条给每个联通区域标上边界线。
[B,L]=bwboundaries(B6,4);
imshow(label2rgb(L,@jet,[.5.5.5]))%对联通区域进行标记
holdon
fork=1:
length(B)%用线条给联通区域标上边界线
boundary=B{k};
plot(boundary(:
2),boundary(:
1),'w','LineWidth',2)
end
图13以图12为源图标记出联通区域
B.单行的车牌号大多为长宽比为4.5:
1的矩形(中外车牌皆如此,两行字的车牌除外)。
以此为标准对各个联通区域进行判断,并以“metric”单元记录匹配度,匹配度越接近1说明该联通区域越有可能是车牌。
又由于车牌在图像中的面积不可能太小,因此判定某联通区域为车牌的条件为:
metric在0.85到0.15之间,且面积大于1000像素。
以图4为源文件截取出满足条件的联通区域,截取出的图像即为车牌区域。
stats=regionprops(L,'Area','Centroid');%找到每个连通域的质心
fork=1:
length(B)%循环历遍每个连通域的边界
boundary=B{k};%获取一条边界上的所有点
delta_sq=diff(boundary).^2;
perimeter=sum(sqrt(sum(delta_sq,2)));%计算边界周长
area=stats(k).Area;%获取边界所围面积
metric=27*area/perimeter^2;%计算匹配度
metric_string=sprintf('%2.2f',metric);%要显示的匹配度字串
ifmetric>=0.85&&metric<=1.15&&area>1000%截取出匹配度接近1且面积大于1000像素的连通域
centroid=stats(k).Centroid;
plot(centroid
(1),centroid
(2),'ko');%提取该连通域所对应在二值图像中的矩形区域
goalboundary=boundary;
s=min(goalboundary,[],1);
e=max(goalboundary,[],1);
goal=imcrop(Image,[s
(2)s
(1)e
(2)-s
(2)e
(1)-s
(1)]);
endtext(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','g','FontSize',14,'FontWeight','bold');%显示匹配度字串
end
图14标出匹配度后的联通区域
D.对截取出的车牌图像进行反色处理,以便进行接下来的运算。
goal=~goal;figure;
imshow(goal);
图15截取出的车牌区域
5.字符截取(返回索引)
A.对截取出的车牌区域(图15)进行进一步的处理,将字符区域的上方区域以及下方区域都从图像中舍弃。
具体实现方法为:
从该图的水平中轴开始向上扫描,扫描到字符的顶端时(判断条件为该行白点数少于每行总点数的1/10)停止,并记录此时的纵轴坐标;再从水平中轴向下扫描,扫描到字符的底端时停止,并记录此时的纵轴坐标。
之后,根据记录下的纵轴坐标对图15进行进一步的截取。
[a,b]=size(goal);
fori=a/2:
-1:
1%从图像水平中轴开始向上扫描,当白点数少于每行总点数的1/10时,停止扫描,并将该行定义为车牌字符区域的上限.
num=0;
forj=1:
b
ifgoal(i,j)==1
num=num+1;
end
end
ifnum<(b*0.1)
line_up=i;
break;
end
end
fori=a/2:
a%从图像水平中轴开始向下扫描,当白点数少于每行总点数的1/10时,停止扫描,并将该行定义为车牌字符区域的下限.
num=0;
forj=1:
b
ifgoal(i,j)==1
num=num+1;
end
end
ifnum<(b*0.1)
line_down=i;
break;
end
end
goal=goal(line_up:
line_down,1:
b);%根据之前定义的上下限截取车牌字符区域
图16舍弃字符上方以及下方后的车牌区域
B.以图16为源图像进行字符分割。
具体实现方法为:
对图像进行列扫描,每当该列的白点数从每列总点数的1/10以上掉落到每列总点数的1/10以下时,或者该列的白点数从1/10以下上升到1/10以上时,记录该列。
[a,b]=size(goal);
row=zeros(18);
now=1;
flag=0;
forj=1:
b%对截取出的字符区域进行竖列扫描,并取每列总点数的1/10作为阈值点,当每列的白点数从阈值以上掉落到阈值以下或从阈值以下上升到阈值以上时,记录该列的横坐标
num=0;
fori=1:
a
ifgoal(i,j)==1
num=num+1;
end
end
ifflag==0
ifnum<0.1*a
row(now)=j;
now=now+1;
flag=1;
end
else
ifnum>0.1*a
row(now)=j;
now=now+1;
flag=0;
end
end
end
C.判断所记录下的第二列以及第三列之间的区域(即被列标记分割出的第三块区域)是否含有有效字符,如含有有效字符,则从第三块区域开始扫描;如没有,则从第二块区域进行扫描。
判断是否为有效字符的依据为该区域宽度是否大于10。
ifrow(3)-row
(2)>10
now=2;
else
now=1;
end
图17字符分割示意图
图18字符分割结果
D.由标记部分(本步骤的B部分)可知,如某一块区域为字符区域,则其相邻区域必为黑色区域,而与其相隔一块的区域必为字符区域。
根据上一步的判断结果从第二块或第三块区域开始,隔一块进行一次判断。
如果该区域白点数大于总像素点的2/5时,输出,且计数器l1加一(避免输出中国车牌所使用的点状分隔符)。
对每个字符区域调用子程序进行识别,如识别成功则将该字符的ASCII码记录在数组中,且计数器l2加一。
图19MATLAB界面的文件名输入及输出结果
6.字符识别(子程序)(返回索引)
识别的具体过程如下:
A.对截取的字符进行水平中轴的笔划扫描,并记录扫描到的笔画数,并记录为line_x。
B.对截取的字符进行竖直中轴的笔划扫描,并记录扫描到的笔划数,并记录为line_y。
C.对截取的字符进行白点总数的计算,如白点数大于字符总像素的4/5,则识别该字符为“I”。
D.对截取的字符下方的3/4处进行笔划扫描,并记录扫描到的笔划数,并记录为line_x_1。
E.对截取的字符下方的9/10处进行笔划扫描,并记录扫描到的笔划数,并记录为line_x_2。
F.对截取的字符的最左侧进行判断,如左数第一列的白点数大于每列总点数的4/5,则记flag_1=1。
G.对截取的字符的下方的9/10处进行点数计算,如该列的白点数大于每列总点数的9/10,则记flag_2=1。
图20扫描路线示意图
根据以上7个特征值,已可以识别出两幅测试图像中的“2”“4”“8”“9”“A”“B”“I”“M”“P”等字符。
具体程序请参见附录1。
实验思路分析(返回索引)
1.在最开始处理图像时,采用的是灰度门限法对图像进行二值化处理。
但后来发现,这种方法虽然很简单易行,但当车牌颜色变化时需要不断地改变门限阈值,且很容易受噪声或背景图像中的干扰信息的影响。
最后,在参阅了相关文献之后,使用边缘识别+膨胀连接的方法,获得了较好的效果,且这种方法不受车牌颜色的限制,当车牌字体变化时,只需在识别时进行反色处理即可。
2.对车牌区域的识别采取的是对联通区域的周长面积比进行判断的方法。
此方法易受小区块联通区域的干扰,但可通过对联通区域的像素面积进行判断的方法进行缓解。
3.对字符的识别采取的是行列扫描+特征判断的方法。
虽然本程序中并未对所有可能出现的字符进行判断,但显而易见的是,通过足够多次的行列扫描,可识别出绝大多数字符。
对于一些行列扫描难以判断的字符,则可通过一些字符的固有特征来判断。
比如在传统方法(傅里叶变换识别字符匹配)中难以区分的“8”和“B”,即可以通过扫描它们的最左侧一列进行判断,如果扫描到竖线则为“B”,反之则为“8”。
本程序的局限性(返回索引)
1.本程序并未对车牌的倾斜程度进行判断,所以只适用于识别较为水平的车牌。
2.在对边缘区域进行膨胀处理时的参数为不断调试的结果,并不具有普适性。
但这也是由于平常拍摄的车牌照片的大小与背景均无特定规律所致。
相信在当运用于固定场合拍摄的的具有相对固定的大小的车牌照片时,此缺陷可通过调整合适的参数来克服。
3.由于时间以及图源所限,在字符判断时并没有识别所有的字符。
在拥有足够的时间以及图源时,此缺陷可以很快克服。
附录(返回索引)
附录1程序源代码(返回索引)
主程序(返回索引)
clc;
clearall;
k=input('Enterthefilename:
','s');%输入车牌照片
im=imread(k);
imshow(im);
im_gray=rgb2gray(im);
im_gray=medfilt2(im_gray,[33]);%对图像进行中值滤波
Image=im2bw(im_gray,0.2);
BW=edge(im_gray,'sobel');%找出图像边缘
[imx,imy]=size(BW);%计算图像大小
msk=[00000;
01110;
01110;
01110;
00000;];
B0=conv2(double(BW),double(msk));%对边缘区域进行加强
se=ones(2,80);
B1=imdilate(B0,se);
%imshow(B1);
B2=imerode(B1,se);
%figure;imshow(B2);
se=ones(20,2);
B3=imdilate(B2,se);
%figure;imshow(B3);
B4=imerode(B3,se);
%figure;imshow(B4);
se=ones(50,2);
B5=imdilate(B4,se);
%figure;imshow(B5);
B6=imerode(B5,se);
%figure;imshow(B6);%对边界图进行小区块联通,使车牌区域联通为一个方块
[B,L]=bwboundaries(B6,4);
imshow(label2rgb(L,@jet,[.5.5.5]))%对联通区域进行标记
holdon
fork=1:
length(B)%用线条给联通区域标上边界线
boundary=B{k};
plot(boundary(:
2),boundary(:
1),'w','LineWidth',2)
end
stats=regionprops(L,'Area','Centroid');%找到每个连通域的质心
fork=1:
length(B)%循环历遍每个连通域的边界
boundary=B{k};%获取一条边界上的所有点
delta_sq=diff(boundary).^2;
perimeter=sum(sqrt(sum(delta_sq,2)));%计算边界周长
area=stats(k).Area;%获取边界所围面积
metric=27*area/perimeter^2;%计算匹配度
metric_string=sprintf('%2.2f',metric);%要显示的匹配度字串
ifmetric>=0.85&&metric<=1.15&&area>1000%截取出匹配度接近1且面积大于1000像素的连通域
centroid=stats(k).Centroid;
plot(centroid
(1),centroid
(2),'ko');%提取该连通域所对应在二值图像中的矩形区域
goalboundary=boundary;
s=min(goalboundary,[],1);
e=max(goalboundary,[],1);
goal=imcrop(Image,[s
(2)s
(1)e
(2)-s
(2)e
(1)-s
(1)]);
end
text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','g','FontSize',14,'FontWeight','bold');%显示匹配度字串
end
goal=~goal;%对截取图像进行反色处理
figure;
imshow(goal);
[a,b]=size(goal);
fori=a/2:
-1:
1%从图像水平中轴开始向上扫描,当白点数少于每行总点数的1/10时,停止扫描,并将该行定义为车牌字符区域的上限.
num=0;
forj=1:
b
ifgoal(i,j)==1
num=num+1;
end
end
ifnum<(b*0.1)
line_up=i;
break;
end
end
fori=a/2:
a%从图像水平中轴开始向下扫描,当白点数少于每行总点数的1/10时,停止扫描,并将该行定义为车牌字符区域的下限.
num=0;
forj=1:
b
ifgoal(i,j)==1
num=num+1;
end
end
ifnum<(b*0.1)
line_down=i;
break;
end
end
goal=goal(line_up:
line_down,1:
b);%根据之前定义的上下限截取车牌字符区域
figure;imshow(goal);%显示车牌字符区域
[a,b]=size(goal);
row=zeros(18);
now=1;
flag=0;
forj=1:
b%对截取出的字符区域进行竖列扫描,并取每列总点数的1/10作为阈值点,当每列的白点数从阈值以上掉落到阈值以下或从阈值以下上升到阈值以上时,记录该列的横坐标
num=0;
fori=1:
a
ifgoal(i,j)==1
num=num+1;
end
end
ifflag==0
ifnum<0.1*a
row(now)=j;
now=now+1;
flag=1;
end
else
ifnum>0.1*a
row(now)=j;
now=now+1;
flag=0;
end
end
end
ifrow(3)-row
(2)>10%判断扫描出的第二块区域(扫描到的第二列与第三列之间)是否包含有效字符.如包含,则将扫描到的第二列定为字符分割的起始列;否则,则定义第一列为起始列.
now=2;
else
now=1;
end
figure;
l1=0;
l2=0;
fork=1:
8
m=row(now);
n=row(now+1);
temp=goal(1:
a,m:
n);
point=0;%扫描每一个字符图片的白点点数
fori=1:
a
forj=1:
n-m
iftemp(i,j)==1
point=point+1;
end
end
end
ifpoint>0.4*a*(n-m)&&n>m%当扫描到的白点数小于总点数的2/5时放弃输出(有可能是车牌上的点状分隔符);
l2=l2+1;%l2用来记录识别出的字符数
subplot(1,7,l2);
x(k)=code(temp);%调用子程序进行字符扫描,并返回字符的ASCII码.
x(k)=uint8(x(k));
ifx(k)>0%当所选区域不为空时进行输出.
l1=l1+1;%l1用来记录输出的字符数
s(l1)=char(x(k));
end
temp(32,32)=0;
imshow(temp);
end
now=now+2;
end
y=char(s);%将得到的ASCII码重新转换为字符并在屏幕上输出
fprintf('\r\n该车辆的车牌号为:
\r\n');
disp(y);
fprintf('\r\n输出的字符数为:
%4d\r\n',l1);
fprintf('识别出的字符数为:
%4d\r\n',l2);
子函数(code)(返回索引)
functionco=code(aim)
[a1,b1]=size(aim);
num1=0;
fori1=1:
a1
forj1=1:
b1
ifaim(i1,j1)==1
num1=num1+1;
end
end
end
ch=0;
ifnum1>a1*b1*0.8
ch='I';
end
line_x=0;
line_y=0;
flag=0;
fori1=1:
a1
ifaim(i1,round(b1/2))==1&&flag==0
flag=1;
line_y=line_y+1;
end
ifaim(i1,round(b1/2))==0&&flag==1
flag=0;
end
end
flag=0;
forj1=1:
b1
ifaim(round(a1/2),j1)==1&&flag==0
flag=1;
line_x=line_x+1;
end
ifaim(round(a1/2),j1)==0&&flag==1
flag=0;
end
end
line_x_1=0;
flag=0;
forj1=1:
b1
ifaim(round(a1*3/4),j1)==1&&flag==0
flag=1;
line_x_1=line_x_1+1;
end
ifaim(round(a1*3/4),j1)==0&&flag==1
flag=0;
end
end
line_x_2=0;
flag=0;
forj1=1:
b1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告 MATLAB 实现 车牌 识别 系统