%1.读取图片
[fn,pn,fi]=uigetfile('*.jpg','选择图片');
I=imread([pn fn]);
figure(1),
imshow(I);
title('原始图像');
%2.灰度处理
Im1=rgb2gray(I);
figure(2),
subplot(1,2,1),
imshow(Im1);
subplot(1,2,2),
imhist(Im1);
title('灰度图');
%3.增强处理
tiao=imadjust(Im1,[0.2,0.8],[0,1]);
figure(3),
subplot(1,2,1),
imshow(tiao);
subplot(1,2,2),
imhist(tiao);
title('增强效果图');
%4.边缘检测-sobel算子
Im2=edge(tiao,'sobel',0.15);
figure(4),
imshow(Im2);
title('sobel算子边缘检测');
%5.灰度图腐蚀
se=[1;1]; %刷子矩阵
Im3=imerode(Im2,se);
figure(5),
imshow(Im3);
title('腐蚀效果图');
%6.图像平滑处理
se=strel('rectangle',[25,25]); %创建结构元素
Im4=imclose(Im3,se) %平滑轮廓
figure(6),
imshow(Im4);
title('平滑图像轮廓');
%7.移除小对象
Im5=bwareaopen(Im4,10000);
figure(7),
imshow(Im5);
title('移除小对象'); %gtmd水印
%8.牌照区域分割(看不懂)
[y,x]=size(Im5);
Im6=double(Im5);
Blue_y=zeros(y,1); %创建元素为零的矩阵y*1
for i=1:y
for j=1:x
if(Im6(i,j,1)==1)
Blue_y(i,1)=Blue_y(i,1)+1;%根据Im5的y值确定
end
end
end
[temp MaxY]=max(Blue_y);
PY1=MaxY;
while((Blue_y(PY1,1)>=5)&&(PY1>1))
PY1=PY1-1;
end
PY2=MaxY;
while((Blue_y(PY2,1)>=5)&&(PY2<y))
PY2=PY2+1;
end
IY=I(PY1:PY2,:,:);
Blue_x=zeros(1,x);
for j=1:x
for i=PY1:PY2
if(Im6(i,j,1)==1)
Blue_x(1,j)=Blue_x(1,j)+1; %根据Im5的x值确定
end
end
end
PX1=1;
while((Blue_x(1,PX1)<3)&&(PX1<x))
PX1=PX1+1;
end
PX2=x;
while((Blue_x(1,PX2)<3)&&(PX1<PX2))
PX2=PX2-1;
end
PX1=PX1-1; %车牌方向校正
PX2=PX2+1;
dw=I(PY1:PY2-6,PX1:PX2,:);
figure(8),
subplot(1,2,1),
imshow(IY),
title('垂直方向的合理区域');
figure(8),
subplot(1,2,2),
imshow(dw),
title('定位剪切后的彩色车牌图像')
%9.滤波,二值化,膨胀与腐蚀处理
imwrite(dw,'dw.jpg');
a=imread('dw.jpg');
b=rgb2gray(a);
figure(9),
subplot(2,2,1),
imshow(b),
title('1.车牌灰度图像');
g_max=max(max(b));
g_min=min(min(b));
T=round((2/3)*g_max+(1/3)*g_min); %设定阈值
[m,n]=size(b);
d=(double(b)>=T);
figure(9),
subplot(2,2,2),
imshow(d),
title('2.车牌二值图像');
figure(9),
subplot(2,2,3),
imshow(d),
title('3.均值滤波前');
h=fspecial('average',3);
d=im2bw(round(filter2(h,d)));
figure(9),
subplot(2,2,4),
imshow(d),
title('4.均值滤波后');
%有问题
% [m,n]=size(d);
% if bwarea(d)/m/n>=0.365
% d=imerode(d,se);
% elseif bwarea(d)/m/n<=0.235
% d=imdilate(d,se);
% end
% imwrite(d,'膨胀或腐蚀处理后.jpg');
% figure(9),
% subplot(3,2,5),
% imshow(d),
% title('5.膨胀或腐蚀处理后')
%10.字符分割与归一化
d=qiege(d);
[m,n]=size(d);
% subplot(3,2,5),imshow(d),title(n)
k1=1;k2=1;s=sum(d);j=1;
while j~=n
while s(j)==0
j=j+1;
end
k1=j;
while s(j)~=0 && j<=n-1
j=j+1;
end
k2=j-1;
if k2-k1>=round(n/6.5)
[val,num]=min(sum(d(:,[k1+5:k2-5])));
d(:,k1+num+5)=0; % 分割
end
end
% 再切割
d=qiege(d);
% 切割出 7 个字符
y1=10;y2=0.25;flag=0;word1=[];
while flag==0
[m,n]=size(d);
left=1;wide=0;
while sum(d(:,wide+1))~=0
wide=wide+1;
end
if wide<y1 % 认为是左侧干扰
d(:,[1:wide])=0;
d=qiege(d);
else
temp=qiege(imcrop(d,[1 1 wide m]));
[m,n]=size(temp);
all=sum(sum(temp));
two_thirds=sum(sum(temp([round(m/3):2*round(m/3)],:)));
if two_thirds/all>y2
flag=1;word1=temp;
end
d(:,[1:wide])=0;d=qiege(d);
end
end
% 分割出第二个字符
[word2,d]=getword(d);
% 分割出第三个字符
[word3,d]=getword(d);
% 分割出第四个字符
[word4,d]=getword(d);
% 分割出第五个字符
[word5,d]=getword(d);
% 分割出第六个字符
[word6,d]=getword(d);
% 分割出第七个字符
[word7,d]=getword(d);
figure(10);
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');
[m,n]=size(word1);
% 商用系统程序中归一化大小为 40*20,此处演示
word1=imresize(word1,[40 20]);
word2=imresize(word2,[40 20]);
word3=imresize(word3,[40 20]);
word4=imresize(word4,[40 20]);
word5=imresize(word5,[40 20]);
word6=imresize(word6,[40 20]);
word7=imresize(word7,[40 20]);
subplot(2,7,8),imshow(word1),title('1');
subplot(2,7,9),imshow(word2),title('2');
subplot(2,7,10),imshow(word3),title('3');
subplot(2,7,11),imshow(word4),title('4');
subplot(2,7,12),imshow(word5),title('5');
subplot(2,7,13),imshow(word6),title('6');
subplot(2,7,14),imshow(word7),title('7');
imwrite(word1,'1.jpg');
imwrite(word2,'2.jpg');
imwrite(word3,'3.jpg');
imwrite(word4,'4.jpg');
imwrite(word5,'5.jpg');
imwrite(word6,'6.jpg');
imwrite(word7,'7.jpg');
liccode=char(['0':'9' 'A':'Z' '京辽鲁陕苏豫浙']); %建立自动识别字符代码表
SubBw2=zeros(40,20); %产生40*20的全0矩阵
l=1;
for I=1:7
ii=int2str(I); %转为串
t=imread([ii,'.jpg']); %读取图片文件中的数据
SegBw2=imresize(t,[40 20],'nearest'); %对图像做缩放处理
SegBw2=double(SegBw2)>20;
if l==1 %第一位汉字识别
kmin=37;
kmax=43;
elseif l==2 %第二位 A~Z 字母识别
kmin=11;
kmax=36;
else l>=3 %第三位以后是字母或数字识别
kmin=1;
kmax=36;
end
for k2=kmin:kmax
fname=strcat('D:\MATLAB\字符模板\',liccode(k2),'.jpg'); %把行向量转化成字符串
SamBw2 = imread(fname);
SamBw2=double(SamBw2)>1;
for i=1:40
for j=1:20
SubBw2(i,j)=SegBw2(i,j)-SamBw2(i,j);
end
end
% 以上相当于两幅图相减得到第三幅图
Dmax=0;
for k1=1:40
for l1=1:20
if ( SubBw2(k1,l1) > 0 | SubBw2(k1,l1) <0 )
Dmax=Dmax+1;
end
end
end
Error(k2)=Dmax;
end
Error1=Error(kmin:kmax);
MinError=min(Error1);
findc=find(Error1==MinError);
Code(l*2-1)=liccode(findc(1)+kmin-1);
Code(l*2)=' '; %输出最大相关图像
l=l+1;
end
figure(11),imshow(dw),title (['车牌号码:', Code],'Color','r');