汽车牌照识别程序
摘要:
通过对基于MATLAB的字符识别的研究,以汽车牌照识别的设计为实例,详细介绍字符识别的相关原理。整个汽车牌照识别的过程分为预处理、边缘提取、车牌定位、字符分割、字符识别五大模块,用MATLAB软件编程来实现每一个部分,最后识别出汽车牌照。
MATLAB及其图像处理工具概述:
基于MATLAB图像处理的汽车牌照识别系统:
1)系统组成
其中,
(1)原始图像:由数码相机或其它扫描装置拍摄到的图像;
(2)图像预处理:对动态采集到的图像进行滤波、边界增强等处理以克服图像干扰;
(3)车牌定位:计算边缘图像的投影面积,寻找峰谷点,大致确定车牌位置,再计算此连通域内的宽高比,剔除不在域值范围内的连通域,最后得到的便为车牌区域;
(4)字符分割:利用投影检测的字符定位分割方法得到单个的字符;
(5)字符数据库:为第6步的字符识别建立字符模板数据库;
(6)字符识别:通过基于模板匹配的OCR算法或基于人工神经网络的OCR算法,通过特征对比或训练识别出相关的字符,得到最后的汽车牌照,包括英文字母和数字。
2)图像预处理
图像在形成、传输或变换过程中,受多种因素的影响,如:光学系统失真、系统噪声、曝光不足或过量、相对运动等,往往会与原始景物之间或图像与原始图像之间产生了某种差异,这种差异称为降质或退化。因此在图像处理之前必须进行预处理,包括去除噪音、边界增强、增加亮度等。
输入的彩色图像包含大量颜色信息,会占用较多的存储空间,且处理时也会降低系统的执行速度,因此对图像进行识别等处理时,常将彩色图像转换为灰度图像,以加快处理速度。对图像进行灰度化处理、边缘提取、再利用形态学方法对车牌进行定位。
具体步骤如下:首先对图像进行灰度转换,二值化处理然后采用4X1的结构元素对图像进行腐蚀,去除图像的噪声。采用25X25的结构元素,对图像进行闭合应算使车牌所在的区域形成连通。再进行形态学滤波去除其它区域。
I=imread('CAR/0.jpg'); %读取图片
I1=rgb2gray(I); %转化为灰度图像
I2=edge(I1,'robert',0.09,'both'); %采用robert算子进行边缘检测
se=[1;1;1]; %线型结构元素
I3=imerode(I2,se); %腐蚀图像
se=strel('rectangle',[25,25]); %矩形结构元素
I4=imclose(I3,se); %图像聚类、填充图像
I5=bwareaopen(I4,2000); %去除聚团灰度值小于2000的部分<span style="color:#ff0000;">
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
通过对比原始图片,我们可以发现形态滤波后的图像已经很接近正确的车牌位置了,因此后期处理将通过这张图来找出车牌位置。
3) 车牌定位
观察经过预处理后得到的图像发现车牌位置有明显的矩形有明显的矩形图样,通过对矩形区域的定位即可获得具体的车牌位置。
(1)车牌的行起始和终止位置的确定
[y,x,]=size(I5);
I6=double(I5);
%绘制行曲线图
Y1=zeros(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
figure();
subplot(1,3,1);
plot(0:y-1,Y1),title('行像素灰度值累计'),xlabel('行值'),ylabel('像素和');
[temp, MaxY]=max(Y1);
PY1=MaxY;
while ((Y1(PY1,1)>=80)&&(PY1>1))
PY1=PY1-7;
end
PY2=MaxY;
while ((Y1(PY2,1)>=80)&&(PY2<y))
PY2=PY2+7;
end
<span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
(2)车牌的列起始位置和终止位置的确定
%绘制列曲线图
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
subplot(1,3,2);
plot(0:x-1,X1),title('列像素灰度值累计'),xlabel('列值'),ylabel('像数和');
PX1=1;
while ((X1(1,PX1)<3)&&(PX1<x))
PX1=PX1+7;
end
PX2=x;
while ((X1(1,PX2)<3)&&(PX2>PX1))
PX2=PX2-7;
end
DW=I(PY1:PY2,PX1:PX2,:);
subplot(1,3,3);
imshow(DW),title('车牌定位后图像');
4)字符分割
在汽车牌照自动识别过程中,字符分割有承前启后的作用。它在前期牌照定位的基础上进行字符的分割,然后再利用分割的结果进行字符识别。
%% 车牌图像转为灰度
if isrgb(I)
I1 = rgb2gray(I);
else
I1 = I;
end
%% 二值化车牌图像
I1 = im2bw(I1,graythresh(I1));%二值化图像
I2 = bwareaopen(I1,16);%去除小于16像素的区块
figure();
subplot(1,2,1);
imshow(I2),title('二值化车牌图像');
%% 分割字符按行积累量
[y,x]=size(I2);
I3=double(I2);
X1=zeros(1,x);
for j=1:x
for i=1:y
if(I3(i,j,1)==1)
X1(1,j)= X1(1,j)+1;
end
end
end
subplot(1,2,2);
plot(0:x-1,X1),title('车牌列像素点累计'),xlabel('列值'),ylabel('像素和');
%% 分割字符
Px0=1;
Px1=1;
figure();
for i=1:7
while ((X1(1,Px0)<3)&&(Px0<x))
Px0=Px0+1;
end
Px1=Px0;
while (((X1(1,Px1)>=3)&&(Px1<x))||((Px1-Px0)<10))
Px1=Px1+1;
end
Z=I2(:,Px0:Px1,:);
switch strcat('Z',num2str(i))
case 'Z1'
PIN0=Z;
case 'Z2'
PIN1=Z;
case 'Z3'
PIN2=Z;
case 'Z4'
PIN3=Z;
case 'Z5'
PIN4=Z;
case 'Z6'
PIN5=Z;
otherwise
PIN6=Z;
end
subplot(1,7,i);
imshow(Z);
Px0=Px1;
end
5)建立字符模板数据库
模板库的合理建造是字符识别准确的关键之一,所以在字符识别之前必须把模板库设置好。汽车牌照的字符一般有 7个,大部分车牌第一位是汉字,通常代表车辆所属省份,或是军种,警别等有特定含义的字符简称;紧接其后的为字母与数字。车牌字符识别与一般文字识别在于它的字符数有限,十个阿拉伯数字0~9, 26个大写英文字母A~Z以及相关的车牌用汉字:京、沪、苏、台、港、澳、甲、乙、丙、使、领、学、试、境、消、边、警等,以及新式军牌中的汉字南、兰、广、北、沈、济、空、海等;车牌颜色:蓝、白、黑、黄等。所以建立字符模板库也极为方便。
通过前面实验获取的几幅不同的车牌图片截取到的图片加上使用PhotoShop制作的部分图片如下:
建立模板数据库时必须对这些图片进行统一处理,因为对前面处理分割后的车牌图像的测量得知单个字符的最佳宽高比是1:2,所以将这些图片归一化为50×25大小;因为之后的字符识别考虑使用神经网络算法进行字符识别,所以再将上面归一化后的模板图像的样本排列在一起构成1250×18的矩阵样本,程序设计如下:
function inpt = Pretreatment(I)
%% 训练样本前期处理
if isrgb(I)
I1 = rgb2gray(I);
else
I1=I;
end
I1=imresize(I1,[50 25]);%将图片统一划为50*25大小
I1=im2bw(I1,0.9);
[m,n]=size(I1);
inpt=zeros(1,m*n);
%% 将图像按列转换成一个行向量
for j=1:n
for i=1:m
inpt(1,m*(j-1)+i)=I1(i,j);
end
end
这是一个自定义函数的Pretreatment.m 文件,可以解决频繁写重复代码的问题,前面的图像预处理及车牌定位的代码可以写进Location.m文件中,通过代码DW = Location(I); 取得车牌定位后的图像;同时字符分割的代码亦可写进StringSplit.m 文件中,可以通过代码[PIN0,PIN1,PIN2,PIN3,PIN4,PIN5,PIN6]=StringSplit(DW); 取得的字符分割后的图像。
6) 字符识别
字符的识别目前用于车牌字符识别(OCR)中的算法主要有基于模板匹配的OCR算法以及基于人工神经网络的OCR算法。基于模板匹配的OCR的基本过程是:首先对待识别字符进行二值化并将其尺寸大小缩放为字符数据库中模板的大小,然后与所有的模板进行匹配,最后选最佳匹配作为结果。
用人工神经网络进行字符识别主要有两种方法:一种方法是先对待识别字符进行特征提取,然后用所获得的特征来训练神经网络分类器。识别效果与字符特征的提取有关,而字符特征提取往往比较耗时。因此,字符特征的提取就成为研究的关键。另一种方法则充分利用神经网络的特点,直接把待处理图像输入网络,由网络自动实现特征提取直至识别。本文主要研究基于人工神经网络的方法来识别车牌字符。
代码如下:
close all;
clear all;
%% 归一化训练样本
I0=pretreatment(imread('BP/0.jpg'));
I1=pretreatment(imread('BP/1.jpg'));
I2=pretreatment(imread('BP/2.jpg'));
I3=pretreatment(imread('BP/3.jpg'));
I4=pretreatment(imread('BP/4.jpg'));
I5=pretreatment(imread('BP/5.jpg'));
I6=pretreatment(imread('BP/6.jpg'));
I7=pretreatment(imread('BP/7.jpg'));
I8=pretreatment(imread('BP/8.jpg'));
I9=pretreatment(imread('BP/9.jpg'));
I10=pretreatment(imread('BP/A.jpg'));
I11=pretreatment(imread('BP/B.jpg'));
I12=pretreatment(imread('BP/C.jpg'));
I13=pretreatment(imread('BP/D.jpg'));
I14=pretreatment(imread('BP/G.jpg'));
I15=pretreatment(imread('BP/K.jpg'));
I16=pretreatment(imread('BP/L.jpg'));
I17=pretreatment(imread('BP/M.jpg'));
P=[I0',I1',I2',I3',I4',I5',I6',I7',I8',I9',I10',I11',I12',I13',I14',I15',I16',I17'];
T=eye(18,18); %输出样本
%% bp神经网络参数设置
net=newff(minmax(P),[1250,32,18],{'logsig','logsig','logsig'},'trainrp');
net.inputWeights{1,1}.initFcn ='randnr';
net.layerWeights{2,1}.initFcn ='randnr';
net.trainparam.epochs=5000;
net.trainparam.show=50;
%net.trainparam.lr=0.003;
net.trainparam.goal=0.0000000001;
net=init(net);
[net,tr]=train(net,P,T); %训练样本
%% 测试
I=imread('CAR/0.jpg');
DW=Location(I);%车牌定位
[PIN0,PIN1,PIN2,PIN3,PIN4,PIN5,PIN6]=StringSplit(DW);%字符分割及处理
%% 测试字符,得到识别数值
PIN0=pretreatment(PIN0);
PIN1=pretreatment(PIN1);
PIN2=pretreatment(PIN2);
PIN3=pretreatment(PIN3);
PIN4=pretreatment(PIN4);
PIN5=pretreatment(PIN5);
PIN6=pretreatment(PIN6);
P0=[PIN0',PIN1',PIN2',PIN3',PIN4',PIN5',PIN6'];
for i=2:7
T0= sim(net ,P0(:,i));
T1 = compet (T0) ;
d = find(T1 == 1) - 1;
if (d==10)
str='A';
elseif (d==11)
str='B';
elseif (d==12)
str='C';
elseif (d==13)
str='D';
elseif (d==14)
str='G';
elseif (d==15)
str='K';
elseif (d==16)
str='L';
elseif (d==17)
str='M';
elseif (d==0)
str='0';
elseif (d==1)
str='1';
elseif (d==2)
str='2';
elseif (d==3)
str='3';
elseif (d==4)
str='4';
elseif (d==5)
str='5';
elseif (d==6)
str='6';
elseif (d==7)
str='7';
elseif (d==8)
str='8';
elseif (d==9)
str='9';
else
str=num2str(d);
end
switch i
case 2
str2=str;
case 3
str3=str;
case 4
str4=str;
case 5
str5=str;
case 6
str6=str;
otherwise
str7=str;
end
end
%% 识别出的结果以标题形式显示在图上
S=strcat('粤',str2,str3,str4,str5,str6,str7);
figure();
imshow(DW),title(S);
参考文献
[1] 冈萨雷斯《数字图像处理》第二版
[2] MATLAB从入门到精通].周建兴 2008
[4] S.J.Chapman《MATLAB编程》2008
[5] 《MATLAB7_0基础教程》清华大学 2005
[6] 《基于 MATLAB 图像处理的汽车牌照识别系统》仇成群2008(6)
[7] 许志影、李晋平.MATLAB极其在图像处理中的应用.计算机与现代化,2004(4)
[8] 一种复杂车辆图像中的多车牌定位方法, 光子学报 2007(1) Vol.36 No.1
[9] 基于图像处理的汽车牌照的识别,陈秋菊