%%%%车牌定位算法
clear all
clc
img=imread('D:\Matlab\work\plates\car4.jpg');
I=rgb2gray(img);
imwrite(I,'D:\Matlab\work\plates\gray.jpg');
e=edge(I,'canny',0.25);
imwrite(e,'D:\Matlab\work\plates\canny.jpg');
%figure,imshow(I,[]);
%figure,imshow(e);
[row,clo]=size(I);
r=zeros(row,clo);
%%%%%%%%%%%字符轮廓检测
for i=2:row-1
for j=2:clo-1
if(e(i,j)==1)
if(e(i-1,j-1)==1 && e(i-1,j+1)==0 &&e(i+1,j-1)==0 )
r(i,j)=1;
r(i-1,j-1)=1;
end
if(e(i+1,j+1)==1 && e(i+1,j-1)==0 &&e(i-1,j+1)==0 )
r(i,j)=1;
r(i+1,j+1)=1;
end
if(e(i-1,j+1)==1 && e(i-1,j-1)==0 &&e(i+1,j+1)==0 )
r(i,j)=1;
r(i-1,j+1)=1;
end
if(e(i+1,j-1)==1 && e(i-1,j-1)==0 &&e(i+1,j+1)==0 )
r(i,j)=1;
r(i+1,j-1)=1;
end
if(e(i-1,j)==1 && e(i-1,j-1)==0 &&e(i-1,j+1)==0 )
r(i,j)=1;
r(i-1,j)=1;
end
if(e(i+1,j)==1 && e(i+1,j-1)==0 &&e(i+1,j+1)==0 )
r(i,j)=1;
r(i+1,j)=1;
end
end
end
end
%%%%%%%%%%%%%%%%%%%小范围统计 step*step
step=4;
row1=floor(row/step);
clo1=floor(clo/step);
W=zeros(row,clo);
WW=zeros(row,clo);
RR=zeros(row1,clo1);
R=zeros(row1,clo1);
count=0;%%%%%%%字符轮廓点统计
for i=2:row1-1
for j=2:clo1-1
ii=(i-1)*step;
jj=(j-1)*step;
count=sum(sum(r(ii+1:ii+step,jj+1:jj+step)));
if (count>1)
RR(i,j)=1;
W(ii+1:ii+step,jj+1:jj+step)=1;
end
end
end
%figure,imshow(W);
imwrite(W,'D:\Matlab\work\plates\轮廓.jpg');
%%%%%%横向膨胀---隔一膨胀
%for i=1:row1
% for j=2:clo1-1
% if(RR(i,j-1)==1 && RR(i,j+1)==1)
% ii=(i-1)*step;
% jj=(j-1)*step;
% RR(i,j)=1;
% W(ii+1:ii+step,jj+1:jj+step)=1;
% end
% end
%end
%%%%%%横向膨胀,五步填充,消除横向缝隙
%%%%%%left , right 左右界,填充【 left,right】之间的缝隙
left=0;
right=0;
%%%%%%%%%%%lstart,rend,映射到原图像中的横向坐标
lstart=0;
rend=0;
W(:,:)=0;
for i=1:row1
for j=3:clo1-2
left=0;right=0;
for k=j-1:-1:j-2
if (RR(i,k)==1)
left=k;
break;
end
end
for k=j+1:j+2
if(RR(i,k)==1)
right=k;
break;
end
end
if(left>0 && right>0)
RR(i,left:right)=1;
ii=(i-1)*step;
lstart=(left-1)*step;
rend=right*step;
W(ii+1:ii+step,lstart+1:rend)=1;
end
end
end
%%%figure,imshow(W);
%%%%%%纵向膨胀,五步填充,三步效果较差,消除纵向缝隙
high=0;
low=0;
%%%%%%%%%%%%%%hstart,lend 映射到原图像纵坐标
hstart=0;
lend=0;
for i=3:row1-2
for j=1:clo1
high=0;low=0;
for k=i-1:-1:i-2
if (RR(k,j)==1)
high=k;
break;
end
end
for k=i+1:i+2
if(RR(k,j)==1)
low=k;
break;
end
end
if(high>0 && low>0)
RR(high:low,j)=1;
hstart=(high-1)*step;
lend=high*step;
jj=(j-1)*step;
W(hstart+1:lend,jj+1:jj+step)=1;
end
end
end
%figure,imshow(W);
imwrite(W,'D:\Matlab\work\plates\膨胀.jpg');
%%%%%%%%%%%%利用宽度阈值,消除干扰
Twidth1=10;
Twidth2=18;
W(:,:)=0;
left=0; right=0; lstart=0;rend=0;
for i=1:row1
for j=1:clo1
if(RR(i,j)==1)
k=j+1;
left=j;right=j;
while(RR(i,k)==1 && k<clo1)
k=k+1;
end
right=k-1;
if((right-left)<Twidth2 &&(right-left)>Twidth1)
R(i,left:right)=1;
ii=(i-1)*step;
lstart=(left-1)*step;
rend=right*step;
W(ii+1:ii+step,lstart+1:rend)=1;
end
j=right+1;
end
end
end
RR(:,:)=0;
%figure,imshow(W);
imwrite(W,'D:\Matlab\work\plates\水平干扰.jpg');
%%%%%%%%%%%%%%%%%%%%候选车牌区域提取
%%%%% N 候选车牌区域数最大值
%%%%% T 质心 横、纵坐标差值阈值,即如果两区域,质心距离大于T
%%%%% 则认为两候选区域为单独区域
%%%%% weightRow[],weightClo[]为质心横,纵坐标数组
%%%%% width[], height[] 为候选区域宽,高均值
%%%%% CurRow CurClo CurWidth 当前区域横、纵坐标及宽度
N=20;
T=15;
weightRow(N)=0;
weightClo(N)=0;
width(N)=0;
height(N)=0;
left=0; right=0; lstart=0; rend=0;
WW=zeros(row,clo);
CurRow=0;
CurClo=0;
CurWidth=0;
for i=row1:-1:1
j=1;
while(j<clo)
left=j;right=j;
if(j<clo1+1 && R(i,j)==1)
k=j+1;
while(k<clo1+1 && R(i,k)==1 )
k=k+1;
end
right=k-1;
if((right-left)<Twidth1)
%RR(i,left:right)=0;
else
ii=(i-1)*step;
lstart=(left-1)*step;
rend=right*step;
WW(ii+1:ii+step,lstart+1:rend)=1;
%%%%%%%%%%%%%%%%%%%质心横、纵坐标
CurRow=i;
CurClo=round((left+right)/2);
CurWidth=right-left+1;
l=0;
while(l<N)
l=l+1;
if(height(l)==0)%%%%%初始找到,或示找到匹配项
weightRow(l)=CurRow;
weightClo(l)=CurClo;
width(l)=CurWidth;
height(l)=1;
break;
else
if (abs(weightRow(l)-CurRow)<T && abs(weightClo(l)-CurClo)<T)
%%%%%%%%%%%%%%%%%%%%对候选区域进行横、纵、宽、高进行更新,全平均法
weightRow(l)=round((height(l)*weightRow(l)+CurRow)/(height(l)+1));
weightClo(l)=round((height(l)*weightClo(l)+CurClo)/(height(l)+1));
width(l)=round((height(l)*width(l)+CurWidth)/(height(l)+1));
height(l)=height(l)+1;
%%%%%更新后消除本区域
R(i,left:right)=0;
break;
end
end
end
end
j=right+1;
else
j=j+1;
end
end
end
%%%%%%%%显示
%figure,imshow(WW);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%候选区域进行宽高比生成
%%%%%%%%%%%%%rateCount候选区域个数
%%%%%%%%%%%%%rateValue,rateIndex与标准系数StandRate=0.318=140/440最接近候选区域值与索引值
%%%%% rate[] 为候选区域高宽比
rate(N)=0;
StandRate=0.318;
Theight=4;
for l=1:N
if(height(l)==0)
break;
elseif (height(l)<Theight)
rate(l)=5*StandRate;
else
rate(l)=1.0*height(l)/width(l);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%候选区域宽高比检测
Result=zeros(row,clo);
temp=0;
Candidade(N)=0;
CandidateNumber=1;
l=1;
while(rate(l)>0)
if(rate(l)==0)
break;
end
minValue=0; minIndex=0;
FinalHighStart=0;FinalLowEnd=0; FinalLeftStart=0; FinalRightEnd=0;
[minValue,minIndex]=min(abs(rate-StandRate));
if (minValue>0.2)%%%%%%%%宽高比与标准值的差值上限>0.2认为没有候选区
break;
else
Candidate(CandidateNumber)=minIndex;
CandidateNumber=CandidateNumber+1 ;
end
%%%%%%%%%%标记索引项,避免重复检测
rate(minIndex)=5*StandRate;
temp=0;
temp=floor(weightRow(minIndex)-height(minIndex));
if(temp>0)
FinalHighStart=temp;
else
FinalHighStart=1;
end
temp=floor(weightRow(minIndex)+height(minIndex));
if(temp<ro