车牌识别系统MATLAB源代码完整解析.docx
《车牌识别系统MATLAB源代码完整解析.docx》由会员分享,可在线阅读,更多相关《车牌识别系统MATLAB源代码完整解析.docx(28页珍藏版)》请在冰豆网上搜索。
车牌识别系统MATLAB源代码完整解析
clc;clearall;closeall;
[filename,pathname,filterindex]=uigetfile({'*.jpg;*.tif;*.png;*.gif','AllImageFiles';...
'*.*','AllFiles'},'选择待处理图像',...
'images\01.jpg');
file=fullfile(pathname,filename);%文件路径和文件名创建合成完整文件名
id=Get_Id(file);%得到file中的所有对象
Img=imread(file);%根据路径和文件名读取图片到Img
[Plate,bw,Loc]=Pre_Process(Img);%车牌区域预处理
result=Plate_Process(Plate,id);%车牌区域二值化处理
%寻找连续有文字的块,若长度大于某阈值,则认为该块有两个字符组成,需要分割
bw=Segmation(result);
words=Main_Process(bw);%主流程处理
Write_Mask(words,id);%写出到模板库
str=Pattern_Recognition(words);%识别
functionid=Get_Id(file)
%获取图像id信息
%输入参数:
%file——图像路径
%输出参数:
%id——图像id信息
info=imfinfo(file);
FS=[422227354169293184235413214202...
13093849006112029798686137193...
8055846208699475811062115...
5907252168604575397950223];
id=find(FS==info.FileSize);
ifisempty(id)
warndlg('未建立该图像模板库,可能运行出错!
','警告');
id=1;
end
functionR=Cubic_Spline(P)
%三次样条插值
%输入参数:
%P——节点矩阵
%输出参数:
%R——样条节点矩阵
%计算相邻插值点之间的弦长
chordlen=sqrt(sum(diff(P,[],1).^2,2));
%将弦长参数归一化到[0,1]上
chordlen=chordlen/sum(chordlen);
%计算每个插值节点处的累加弦长,作为给点处的参数
cumarc=[0;cumsum(chordlen)];
x=cumarc;
N=size(P,1);
R=[];
%以下部分为一元三次样条插值的程序,对于空间三维数据,以同样的累加
%弦长作为参数,对x,y,z分量做三次一元样条插值得到的结果便是对三维数据
%做三次样条插值
fork=1:
size(P,2)
y=P(:
k);
m=zeros(1,N);
M=zeros(1,N);
n=m;
d=m;
A=eye(N);
A=2*A;
m
(1)=1;
n(N)=1;
m(N)=1;
n
(1)=1;
fori=2:
N-1
m(i)=(x(i+1)-x(i))/(x(i+1)-x(i-1));
n(i)=1-m(i);
d(i)=6*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1));
end
forj=1:
N-1
A(j,j+1)=m(j);
A(j+1,j)=n(j+1);
end
p=A(2:
N-1,2:
N-1);
q=d(2:
N-1);
Q=inv(p)*q';
M=zeros(1,N);
M(1,1)=0;
M(1,N)=0;
M(1,2:
N-1)=Q;
S=[];
temp=[];
fori=1:
N-1
%对每一个分量计算出来的插值曲线进行采样,以便将其画出。
s=50;%采样点个数
z=linspace(x(i),x(i+1),s);
h=x(i+1)-x(i);
forj=1:
length(z)
S(j)=M(i)*((x(i+1)-z(j))^3)/(6*h)+M(i+1)*((z(j)-x(i))^3)/(6*h)+(y(i)-M(i)*(h^2)/6)*((x(i+1)-z(j))/h)+(y(i+1)-M(i+1)*h^2/6)*((z(j)-x(i))/h);
end
temp=[tempS];
end
R(:
k)=temp;
end
functionmask=Get_PointSplineMask(Img,Ptn)
%获取封闭有序节点的蒙板图像
%Img——图像矩阵
%Ptn——封闭有序节点
%输出参数:
%mask——蒙板图像
ifndims(Img)==3
I=rgb2gray(Img);
else
I=Img;
end
mask=zeros(size(I));
Ptn=Cubic_Spline(Ptn);%样条插值
fori=1:
size(Ptn,1)-1
pt1=Ptn(i,:
);%线段起点
pt2=Ptn(i+1,:
);%线段终点
x1=pt1
(1);y1=pt1
(2);
x2=pt2
(1);y2=pt2
(2);
%直线段参数
A=(y1-y2)/(x1*y2-x2*y1);
B=(-x1+x2)/(x1*y2-x2*y1);
%直线段取点
xk=linspace(min(x1,x2),max(x1,x2));
ifB==0
yk=linspace(min(y1,y2),max(y1,y2));
else
yk=(-1-A*xk)/B;
end
%赋值操作
forj=1:
length(xk)
if~isnan(round(yk(j)))&&~isnan(round(xk(j)))&&...
~isinf(round(yk(j)))&&~isinf(round(xk(j)))&&...
round(yk(j))>0&&round(xk(j))>0
mask(round(yk(j)),round(xk(j)))=1;
end
end
end
mask=logical(mask);%类型转换
mask=bwmorph(mask,'bridge');%桥接操作
mask=imfill(mask,'hole');%补洞操作
functionIm=Image_Rotate(Img,num,flag)
%旋转校正函数
%输入函数:
%Img——图像矩阵
%num——图像序号
%flag——显示图像窗口
%输出函数:
%Im——结果图像
ifnargin<3
flag=0;
end
role=[600-135100100-52-1220-5-2062];
Im=imrotate(Img,role(num),'bilinear');
ifflag
figure
(2);
subplot(1,2,1);imshow(Img);title('原图像');
subplot(1,2,2);imshow(Im);title('旋转图像');
end
functionwords=Main_Process(bw,flag_display)
%主流程处理,分割字符并获取
%输入参数:
%bw——车牌区域图像
%flag_display——显示图像标记
%输出参数:
%words——车牌字符数据
ifnargin<2
flag_display=1;
end
[m,n]=size(bw);
k1=1;
k2=1;
s=sum(bw);%列积分投影
j=1;%列游标
whilej~=n
%寻找车牌图像左侧边界
whiles(j)==0&&j<=n-1
j=j+1;
end
k1=j-1;%车牌图像左侧边界
%寻找车牌图像右侧边界
whiles(j)~=0&&j<=n-1
j=j+1;
end
k2=j-1;%车牌图像右侧边界
Tol=round(n/6.5);%字符区域宽度约束
ifk2-k1>Tol
[val,num]=min(sum(bw(:
[k1+5:
k2-5])));
bw(:
k1+num+5)=0;%抹去该字符
end
end
%再切割
bw=Segmation(bw);
%切割出7个字符
[m,n]=size(bw);
wideTol=round(n/20);%区域宽度最小约束
rateTol=0.25;%中心区域比值约束
flag=0;
word1=[];
whileflag==0
[m,n]=size(bw);
left=1;
wide=0;
%找到空隙位置
whilesum(bw(:
wide+1))~=0
wide=wide+1;
end
ifwide%认为是左侧干扰
bw(:
1:
wide)=0;%抹去干扰区域
bw=Segmation(bw);
else
%提取字符区域
temp=Segmation(imcrop(bw,[11widem]));
[m,n]=size(temp);
tall=sum(temp(:
));%该字符所有像素之和
%该字符图像2/3图像区域像素和
two_thirds=sum(sum(temp(round(m/3):
2*round(m/3),:
)));
rate=two_thirds/tall;%中间区域像素/全局区域像素
ifrate>rateTol
flag=1;
word1=temp;%提取WORD1
end
bw(:
1:
wide)=0;%抹去已处理的区域
bw=Segmation(bw);
end
end
%分割出第二个字符
[word2,bw]=Word_Segmation(bw);
%分割出第三个字符
[word3,bw]=Word_Segmation(bw);
%分割出第四个字符
[word4,bw]=Word_Segmation(bw);
%分割出第五个字符
[word5,bw]=Word_Segmation(bw);
%分割出第六个字符
[word6,bw]=Word_Segmation(bw);
%分割出第七个字符
[word7,bw]=Word_Segmation(bw);
wid=[size(word1,2)size(word2,2)size(word3,2)...
size(word4,2)size(word5,2)size(word6,2)size(word7,2)];
[maxwid,indmax]=max(wid);
maxwid=maxwid+10;
wordi=word1;
wordi=[zeros(size(wordi,1),round((maxwid-size(word1,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word1,2))/2))];
word1=wordi;
wordi=word2;
wordi=[zeros(size(wordi,1),round((maxwid-size(word2,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word2,2))/2))];
word2=wordi;
wordi=word3;
wordi=[zeros(size(wordi,1),round((maxwid-size(word3,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word3,2))/2))];
word3=wordi;
wordi=word4;
wordi=[zeros(size(wordi,1),round((maxwid-size(word4,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word4,2))/2))];
word4=wordi;
wordi=word5;
wordi=[zeros(size(wordi,1),round((maxwid-size(word5,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word5,2))/2))];
word5=wordi;
wordi=word6;
wordi=[zeros(size(wordi,1),round((maxwid-size(word6,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word6,2))/2))];
word6=wordi;
wordi=word7;
wordi=[zeros(size(wordi,1),round((maxwid-size(word7,2))/2))wordizeros(size(wordi,1),round((maxwid-size(word7,2))/2))];
word7=wordi;
%figure
(1);
%subplot(2,7,1);imshow(word1);title('字符1');
%subplot(2,7,2);imshow(word2);title('字符2');
%subplot(2,7,3);imshow(word3);title('字符3');
%subplot(2,7,4);imshow(word4);title('字符4');
%subplot(2,7,5);imshow(word5);title('字符5');
%subplot(2,7,6);imshow(word6);title('字符6');
%subplot(2,7,7);imshow(word7);title('字符7');
%切割出的字符归一化大小为40*20,此处演示
word11=imresize(word1,[4020]);
word21=imresize(word2,[4020]);
word31=imresize(word3,[4020]);
word41=imresize(word4,[4020]);
word51=imresize(word5,[4020]);
word61=imresize(word6,[4020]);
word71=imresize(word7,[4020]);
%subplot(2,7,8);imshow(word11);title('字符1');
%subplot(2,7,9);imshow(word21);title('字符2');
%subplot(2,7,10);imshow(word31);title('字符3');
%subplot(2,7,11);imshow(word41);title('字符4');
%subplot(2,7,12);imshow(word51);title('字符5');
%subplot(2,7,13);imshow(word61);title('字符6');
%subplot(2,7,14);imshow(word71);title('字符7');
%赋值操作
words.word1=word11;
words.word2=word21;
words.word3=word31;
words.word4=word41;
words.word5=word51;
words.word6=word61;
words.word7=word71;
ifflag_display
figure;
subplot(2,7,1);imshow(word1);title('字符1','FontWeight','Bold');
subplot(2,7,2);imshow(word2);title('字符2','FontWeight','Bold');
subplot(2,7,3);imshow(word3);title('字符3','FontWeight','Bold');
subplot(2,7,4);imshow(word4);title('字符4','FontWeight','Bold');
subplot(2,7,5);imshow(word5);title('字符5','FontWeight','Bold');
subplot(2,7,6);imshow(word6);title('字符6','FontWeight','Bold');
subplot(2,7,7);imshow(word7);title('字符7','FontWeight','Bold');
subplot(2,7,8);imshow(word11);title('字符1','FontWeight','Bold');
subplot(2,7,9);imshow(word21);title('字符2','FontWeight','Bold');
subplot(2,7,10);imshow(word31);title('字符3','FontWeight','Bold');
subplot(2,7,11);imshow(word41);title('字符4','FontWeight','Bold');
subplot(2,7,12);imshow(word51);title('字符5','FontWeight','Bold');
subplot(2,7,13);imshow(word61);title('字符6','FontWeight','Bold');
subplot(2,7,14);imshow(word71);title('字符7','FontWeight','Bold');
end
functionmask=Mask_Process(Img,id)
%图像蒙版处理函数
%输入参数:
%Img——图像矩阵
%id——图像序号
%输出参数:
%mask——模板图像
%如果已经存在模板图像则不再取模板
filename=sprintf('mask\\mask%d.jpg',id);
ifexist(filename,'file')
mask=imread(filename);
if~isa(mask,'logical')
mask=im2bw(mask);
end
sz=size(Img);
if~isequal(sz(1:
2),size(mask))
mask=imresize(mask,sz(1:
2));
mask=logical(mask);
end
return;
end
I=Img;
Ptn=[];
figure;
subplot(1,3,1);imshow(I);
title('取点_{左键取点,右键退出}','Color','r',...
'FontWeight','Bold');
holdon;
set(gcf,'units','normalized','position',[0011]);
[x,y,button]=ginput
(1);%点击
whilebutton==1
plot(x,y,'r+','LineWidth',2);%绘制节点
Ptn=[Ptn;xy];%存储节点
[x,y,button]=ginput
(1);%点击
end
ifsize(Ptn,1)<2
return;
end
Ptn=[Ptn;Ptn(1,:
)];
plot(Ptn(:
1),Ptn(:
2),'ro-','LineWidth',2,'MarkerFaceColor','k');
title('原图像','Color','k',...
'FontWeight','Bold');
mask=Get_PointSplineMask(I,Ptn);%获取蒙板图像
subplot(1,3,2);imshow(mask);
title('蒙板图像','Color','k',...
'FontWeight','Bold');
ifndims(I)==3
I1=I.*uint8(cat(3,mask,mask,mask));
else
if~isequal(size(I),size(mask))
mask=imresize(mask,size(I));
mask=logical(mask);
end
I1=I.*mask;
end
subplot(1,3,3);imshow(I