车牌识别Matlab算法详解.docx

上传人:b****8 文档编号:9108418 上传时间:2023-05-17 格式:DOCX 页数:23 大小:251.76KB
下载 相关 举报
车牌识别Matlab算法详解.docx_第1页
第1页 / 共23页
车牌识别Matlab算法详解.docx_第2页
第2页 / 共23页
车牌识别Matlab算法详解.docx_第3页
第3页 / 共23页
车牌识别Matlab算法详解.docx_第4页
第4页 / 共23页
车牌识别Matlab算法详解.docx_第5页
第5页 / 共23页
车牌识别Matlab算法详解.docx_第6页
第6页 / 共23页
车牌识别Matlab算法详解.docx_第7页
第7页 / 共23页
车牌识别Matlab算法详解.docx_第8页
第8页 / 共23页
车牌识别Matlab算法详解.docx_第9页
第9页 / 共23页
车牌识别Matlab算法详解.docx_第10页
第10页 / 共23页
车牌识别Matlab算法详解.docx_第11页
第11页 / 共23页
车牌识别Matlab算法详解.docx_第12页
第12页 / 共23页
车牌识别Matlab算法详解.docx_第13页
第13页 / 共23页
车牌识别Matlab算法详解.docx_第14页
第14页 / 共23页
车牌识别Matlab算法详解.docx_第15页
第15页 / 共23页
车牌识别Matlab算法详解.docx_第16页
第16页 / 共23页
车牌识别Matlab算法详解.docx_第17页
第17页 / 共23页
车牌识别Matlab算法详解.docx_第18页
第18页 / 共23页
车牌识别Matlab算法详解.docx_第19页
第19页 / 共23页
车牌识别Matlab算法详解.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

车牌识别Matlab算法详解.docx

《车牌识别Matlab算法详解.docx》由会员分享,可在线阅读,更多相关《车牌识别Matlab算法详解.docx(23页珍藏版)》请在冰点文库上搜索。

车牌识别Matlab算法详解.docx

车牌识别Matlab算法详解

生成界面时注意事项

1、生成文件主菜单和打开、关闭子菜单不一样的地方,在于文件主菜单不对应实际执行代码,所以在Callback回调函数,这一项,可将其删除为空。

2、在关闭MenuEditor之前,先保存正在编辑的.fig文件,让其自动生成或者更新对应的.m文件

3、在.fig文件编辑器的空白处,双击,弹出PropertyInspector,在其中更改

Resize属性为on,表示窗体大小可以更改;

更改Units的单位为pixels;

Tag的名称代表窗体的名称,默认为figure1,另取一个名称为mainFrm.

注意在关闭PropertyInspector之前总是先保存.fig文件

双击之

4、假如程序运行出了问题,可先在Commandwindow中查看错误说明,根据提示修改。

或者打开.m源代码文件,重新编译运行。

注意在运行之前使用命令窗口中的clc命令清空内存。

5、现在一行一行来解释源代码。

第一行:

functionvarargout=LicenseRecognition(varargin)

分别表示主函数的输出、函数名称、函数输入

在%Begininitializationcode-DONOTEDIT

%Endinitializationcode-DONOTEDIT

这两行注释符之前的代码是编辑菜单时自动生成的,不需要修改

functionLicenseRecognition_OpeningFcn(hObject,eventdata,handles,varargin)

%系统自动生成

handles.output=hObject;%系统自动生成

——————————————————————————————————

%以下代码为手工添加,表示使用handles结构体来保存图形界面中各种对象的句柄,或者中间结果,这些句柄或者中间结果在创建图形对象或运算中产生,需要在以后的回调函数中多次用到,所以这里的作用类似于全局变量的作用,用来进行数据的传递。

handles.imgIn=[];

handles.imgOut=[];

handles.flag=0;%判断标志

handles.pos=[];%图形对象所在位置

handles.lef=1;

handles.top=1;

handles.wid=0;

handles.hig=0;

——————————————————————————————————

%Updatehandlesstructure自动生成,用来将上面定义的数据

guidata(hObject,handles);

%自动生成,定义输出

%---Outputsfromthisfunctionarereturnedtothecommandline.

functionvarargout=LicenseRecognition_OutputFcn(hObject,eventdata,handles)

varargout{1}=handles.output;

第一步:

打开读取文件

%--------------------------------------------------------------------

functionMenu_File_Open_Callback(hObject,eventdata,handles)%该行为自动生成

[fname,pname]=uigetfile({'*.bmp;*.jpg;*.tif','AllIMAGEFiles(*.bmp,*.jpg,*.tif)'},'Openaninputimage');%弹出打开文件的对话框

strPath=[pnamefname];%设置文件名和路径名

if~isempty(strPath)

[img,cmap]=imread(strPath);%读取文件数据

[hig,wid,page]=size(img);%获得图像大小

ifpage==3%假设图像是RGB彩色

imgIn=rgb2gray(img);%转换为灰度图象

else

imgIn=img;

end

handles.imgIn=imgIn;%将结果赋给全局变量,以便交给下一个函数处理

handles.flag=1%标志为1表示数据已经读取

%pos=get(handles.mainFrm,'Position');

figure(handles.mainFrm);%创建图形界面,用来显示图像

set(handles.mainFrm,'Position',[400,300,wid,hig]);%设置该图形界面的显示位置

image(imgIn);%显示图像,其和imshow功能类似,但带有默认的调色板

colormap(gray(256));%将其默认调色板更改为256级灰度

handles.pos=[400,300,wid,hig];%将图形界面的位置保存到hdl结构体中

guidata(hObject,handles);%保存图形界面数据

set(handles.Menu_EdgeDetect,'Enable','On');%设置下一个菜单为可点击的亮色

end

%完成菜单退出功能--------------------------------------------------------------------

functionMenu_File_Exit_Callback(hObject,eventdata,handles)

ifhandles.flag==1

str={'Areyousureaboutexitingtheprogram?

','Ifso,thedatawillbelost!

'};

ret=questdlg(str,'Warning');

switchret

case'Yes'

delete(gcf);

case'No','Cancel'

return;

end

end

%第二步:

边缘检测功能实现

--------------------------------------------------------------------

functionMenu_EdgeDetect_Callback(hObject,eventdata,handles)

if~isempty(handles.imgIn)%检查图像数据是否非空

imgIn=double(handles.imgIn);%在处理之前将图像数据类型转换为double型

%BW=uint8(255*edge(handles.imgIn,'roberts'));

%handles.imgOut=BW;

%guidata(hObject,handles);

%set(handles.mainFrm,'Position',handles.pos);

%image(BW);

%colormap(gray(256));

filt=fspecial('sobel');%构建soble算子的模板

horz=conv2(imgIn,filt,'same');%进行卷积运算

%Cs=conv2(A,B,'same')CsisthesamesizeasA:

3-by-3

vert=conv2(imgIn,filt','same');

imgOut=uint8(max(horz,vert));%取水平和垂直方向运算结果的最大值

%imgOut=uint8(sqrt(horz.^2+vert.^2));

handles.imgOut=imgOut;

handles.flag=1;

guidata(hObject,handles);

figure(handles.mainFrm);

set(handles.mainFrm,'Position',handles.pos);

image(imgOut);

colormap(gray(256));

set(handles.Menu_RoughLocate,'Enable','On');

set(handles.Menu_FineLocate,'Enable','Off');

set(handles.Menu_CharacterCutout,'Enable','Off');

set(handles.Menu_LicenseRecognition,'Enable','Off');

end

第三步:

车牌粗定位

%车牌粗定位:

根据车牌区域在水平方向灰度值具有明显频繁的跳变,可求边缘提取后水平方向的差分,然后进行水平方向上的投影,也即沿水平方向进行相邻像素差分值的累加,绘制的投影图横轴为图像高度,原点为左上角,纵轴即为沿水平方向的差分值累加和。

 

--------------------------------------------------------------------

functionMenu_RoughLocate_Callback(hObject,eventdata,handles)

if~isempty(handles.imgOut)

imgIn=double(handles.imgOut);

[hig,wid]=size(imgIn);

diff_horz=zeros(hig,wid);%构建一个与图像大小一样的全为0的矩阵,存储水平方向相邻像素的差值

diff_horz=abs(imgIn(:

1:

wid-1)-imgIn(:

2:

wid));%类似第1列像素减第2列像素,第2列减第3列,依次减下去

cum_horz=sum(diff_horz');%对图像矩阵先转置,再投影

figure;%绘制投影图形,横轴为1到图像高,纵轴为水平方向差分值累计和

bar(1:

hig,cum_horz,'r');

title('horizontalprojection');

%diff_vert=zeros(hig,wid);

%diff_vert=abs(imgIn(1:

hig-1,:

)-imgIn(2:

hig,:

));

%cum_vert=sum(diff_vert);

%figure;

%bar(1:

wid,cum_vert,'b');

%title('verticalprojection');

%通过观察投影图,给出车牌的大概位置是,左上角坐标为(85,225),宽度为60,高度为20。

lef=85;top=225;wid=60;hig=20;

handles.lef=lef;%将检测结果传递给hdl结构体,以传递到下一个微定位的函数

handles.top=top;

handles.wid=wid;

handles.hig=hig;

imgOut=uint8(imgIn(top:

top+hig-1,lef:

lef+wid-1));%按刚才给的位置大小提取出车牌,转换为无符号整型,保存到imgOut中

handles.imgOut=imgOut;

handles.flag=1;

guidata(hObject,handles);

figure(handles.mainFrm);

set(handles.mainFrm,'Position',handles.pos);

image(imgOut);

colormap(gray(256));

axisoff;

set(handles.Menu_FineLocate,'Enable','On');

set(handles.Menu_RoughLocate,'Enable','Off');

set(handles.Menu_CharacterCutout,'Enable','Off');

set(handles.Menu_LicenseRecognition,'Enable','Off');

end

第四步:

车牌微定位

 

如图所示,在粗定位结果的基础上,还需要把红色边框外的图像去掉,以进一步确定字符范围,缩减车牌的左右上下边界,以便后续字符处理。

--------------------------------------------------------------------

functionMenu_FineLocate_Callback(hObject,eventdata,handles)

if~isempty(handles.imgOut)

imgIn=double(handles.imgOut);%传入粗定位的结果图像

[hig,wid]=size(imgIn);%取图像大小

lef_tem=wid*ones(hig,1);%构建一个hig行,1列的值全为1的矩阵,与wid相乘,矩阵值全部为wid

rig_tem=zeros(hig,1);%构建一个hig*1的0矩阵

fori=1:

hig

forj=1:

wid-1%从左到右扫描,遇到相邻像素的灰度值差值大于60时,停止扫描,记下列号,说明此列是车牌左边界

tem=imgIn(i,j+1)-imgIn(i,j);

iftem>=60

lef_tem(i)=j+1;

break;

end

end

%从右向左扫描,遇到相邻像素的灰度值差值大于60时,停止扫描,记下列号,说明此列是车牌右边界

forj=wid:

-1:

2

tem=imgIn(i,j-1)-imgIn(i,j);

iftem>=60

rig_tem(i)=j-1;

break;

end

end

end4

lef=min(lef_tem);%每一行都可以扫描得到一个左边界,取其中最小的

rig=max(rig_tem);%每一行都可以扫描得到一个右边界,取其中最大的

%这也是lef_tem、rig_tem在初始化定义的时候分别为ones全为1的矩阵和全为zeros0的矩阵的原因

top_tem=hig*ones(wid,1);

bot_tem=zeros(wid,1);

forj=lef:

rig

fori=1:

hig-1

tem=imgIn(i+1,j)-imgIn(i,j);

iftem>=60

top_tem(j)=i+1;

break;

end

end

fori=hig:

-1:

2

tem=imgIn(i-1,j)-imgIn(i,j);

iftem>=60

bot_tem(j)=i-1;

break;

end

end

end

top=min(top_tem);%按同样的方法找到上下边界,注意图像左上角为原点

bot=max(bot_tem);

handles.lef=handles.lef+lef-1;%在原始图像上定位微定位后车牌的位置

handles.top=handles.top+top-1;

handles.wid=rig-lef+1;

handles.hig=bot-top+1;

%将微定位后的图像数据取出来

imgOut=uint8(imgIn(top:

bot,lef:

rig));

handles.imgOut=imgOut;

handles.flag=1;

guidata(hObject,handles);

figure(handles.mainFrm);

set(handles.mainFrm,'Position',handles.pos);

image(imgOut);

colormap(gray(256));

axisoff;

set(handles.Menu_CharacterCutout,'Enable','On');

set(handles.Menu_RoughLocate,'Enable','Off');

set(handles.Menu_FineLocate,'Enable','Off');

set(handles.Menu_LicenseRecognition,'Enable','Off');

end

 

第五步:

字符分割

%--------------------------------------------------------------------

functionMenu_CharacterCutout_Callback(hObject,eventdata,handles)

ifhandles.wid~=0

lef=handles.lef;%注意:

这里是微定位后车牌在原始图像上的位置

top=handles.top;

wid=handles.wid;

hig=handles.hig;

%此处imgIn是在原始图像上取微定位后车牌位置区域的数据产生的

imgIn=double(handles.imgIn(top:

top+hig-1,lef:

lef+wid-1));

%maxvalue=max(imgIn(:

));

%minvalue=min(imgIn(:

));

%imgOut=~(imgIn>=(maxvalue+minvalue+30)/2);

imgOut=~JudgeAnalysis(imgIn);%对图像进行二值化,然后反转

[label,num]=bwlabel(imgOut);%对二值图像进行连通成分的标记

%对于以上两个中间变量的结果,大家可以在Matlab的workspace中查看其结果变化,理解

k=0;

fori=1:

num%以下代码为找到像素总数小于10的连通成分,剔除,这里6个字符,但有7个连通成分,剔除其中较少像素的连通成分

tem=(label==i);%把所有label为i的像素统计出来

ifsum(tem(:

))<=10

imgOut(find(label==i))=0;

k=k+1;

end

end

num=num-k;%减去剔除的连通成分的个数

proj_vert=sum(imgOut);%对图像每一列求和,也即垂直投影

ifproj_vert

(1)~=0%如果第一列的投影不为0,说明第一列的像素中有字符

coordx

(1)=1;

k=1;

else

k=0;

end

%以下代码说明:

如果第后一列像素为0,而前一列的像素不为0,则说明此处是字符的右边界

%如果前一列像素为0,后一列不为0,说明此处是字符的左边界

forj=2:

wid-1

tem1=proj_vert(j-1)-proj_vert(j);

tem2=proj_vert(j+1)-proj_vert(j);

if(proj_vert(j)==0)&(tem1>=1)

k=k+1;

coordx(k)=j-1;

elseif(proj_vert(j)==0)&(tem2>=1)

k=k+1;

coordx(k)=j+1;

end

end

%如果倒数第二列不为0,倒数第1列为0,则说明倒数第2列为边界

if(proj_vert(wid-1)~=0)&(proj_vert(wid)==0)

k=k+1;

coordx(k)=wid-1;

end

%k代表总共有k条边界

k=length(coordx);

set(handles.mainFrm,'Position',handles.pos);

image(uint8(255*(~imgOut)));%将其反转回来在0-255之间显示

colormap(gray(256));

axisoff;

holdon;

forj=1:

k

x=coordx(j)*ones(1,hig);%将x的数目变成和y一样多,组成(x,y)坐标点对

y=1:

hig;

plot(x,y,'b');

holdon;

end

holdoff;

%根据上面所找边界线,对字符进行实际的分割

forj=1:

num

tem_wid(j)=coordx(2*j)-coordx(2*j-1)+1;%每个字符由一对边界线分割而成,由右边边界线减去左边边界线的位置,得到的是此字符的宽度

tem=imgOut(:

coordx(2*j-1):

coordx(2*j));%取出每一字符的实际数据

proj_horz=sum(tem');%对该字符的行求累加值

fork=1:

hig%从上往下扫描,找出第j个字符的上边界

ifproj_horz(k)~=0

tem1=k;

coordy(j,1)=tem1;

break;

end

end

fork=hig:

-1:

1%从下往上扫描,找出第j个字符的下边界

ifproj_horz(k)~=0

tem2=k;

coordy(j,2)=tem2;

break;

end

end

tem_hig(j)=tem2-tem1+1;%找出每一字符的高度

end

%以最大的宽和高来统一每个字符的大小

maxwid=max(tem_wid);%总共有6个字符,找出其中最宽的

maxhig=max(tem_hig);%总共有6个字符,找出其中最高的

fork=1:

num

lef=coordx(2*k-1);rig=coordx(2*k);

top=coordy(k,1);bot=coordy(k,2);

wid=rig-lef+1;hig=bot-top+1;

Norm_Char(1:

maxhig,1:

maxwid,k)=ones(maxhig,maxwid);%初始化为大小统一

Norm_Char(1:

hig,1:

wid,k)

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2