车牌识别Matlab算法详解_第1页
车牌识别Matlab算法详解_第2页
车牌识别Matlab算法详解_第3页
车牌识别Matlab算法详解_第4页
车牌识别Matlab算法详解_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 生成界面时考前须知1、生成文件主菜单和翻开、关闭子菜单不一样的地方,在于文件主菜单不对应实际执行代码,所以在Callback回调函数,这一项,可将其删除为空。 3、在.fig文件编辑器的空白处,双击,弹出Property Inspector,在其中更改Resize 属性为on,表示窗体大小可以更改;更改Units 的单位为 pixels ;Tag的名称代表窗体的名称,默认为figure1,另取一个名称为mainFrm.双击之4、假设程序运行出了问题,可先在Command window中查看错误说明,根据提示修改。或者翻开.m源代码文件,重新编译运行。注意在运行之前使用命令窗口中的clc命令清

2、空内存。5、现在一行一行来解释源代码。第一行:function varargout = LicenseRecognition(varargin)分别表示主函数的输出、函数名称、函数输入在% Begin initialization code - DO NOT EDIT% End initialization code - DO NOT EDIT这两行注释符之前的代码是编辑菜单时自动生成的,不需要修改function LicenseRecognition_OpeningFcn(hObject, eventdata, handles, varargin)%系统自动生成handles.output

3、= hObject; %系统自动生成%以下代码为手工添加,表示使用handles结构体来保存图形界面中各种对象的句柄,或者中间结果,这些句柄或者中间结果在创立图形对象或运算中产生,需要在以后的回调函数中屡次用到,所以这里的作用类似于全局变量的作用,用来进行数据的传递。handles.imgIn = ; handles.imgOut = ;handles.flag = 0;%判断标志handles.pos = ;%图形对象所在位置handles.lef = 1;handles.top = 1;handles.wid = 0;handles.hig = 0;% Update handles str

4、ucture 自动生成,用来将上面定义的数据guidata(hObject, handles);%自动生成,定义输出% Outputs from this function are returned to the command line.function varargout = LicenseRecognition_OutputFcn(hObject, eventdata, handles) varargout1 = handles.output;第一步:翻开读取文件% function Menu_File_Open_Callback(hObject, eventdata, handles)

5、%该行为自动生成fname,pname = uigetfile(*.bmp;*.jpg;*.tif, All IMAGE Files (*.bmp, *.jpg, *.tif),Open an input image); %弹出翻开文件的对话框strPath = pname fname; %设置文件名和路径名if isempty(strPath) img,cmap = imread(strPath); %读取文件数据 hig,wid,page = size(img); %获得图像大小 if page = 3 %假设图像是RGB彩色 imgIn = rgb2gray(img); %转换为灰度图象

6、 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)

7、; %将其默认调色板更改为256级灰度 handles.pos = 400,300,wid,hig; %将图形界面的位置保存到hdl结构体中 guidata(hObject,handles); %保存图形界面数据 set(handles.Menu_EdgeDetect,Enable,On); %设置下一个菜单为可点击的亮色end% 完成菜单退出功能function Menu_File_Exit_Callback(hObject, eventdata, handles)if handles.flag = 1 str = Are you sure about exiting the program

8、?,If so, the data will be lost!; ret = questdlg(str,Warning); switch ret case Yes delete(gcf); case No, Cancel return; endend% 第二步:边缘检测功能实现function Menu_EdgeDetect_Callback(hObject, eventdata, handles)if isempty(handles.imgIn) %检查图像数据是否非空 imgIn = double(handles.imgIn); %在处理之前将图像数据类型转换为double型% BW =

9、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) Cs is the same size as A: 3-by-3 ve

10、rt = 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(handle

11、s.Menu_RoughLocate,Enable,On); set(handles.Menu_FineLocate,Enable,Off); set(handles.Menu_CharacterCutout,Enable,Off); set(handles.Menu_LicenseRecognition,Enable,Off);end第三步:车牌粗定位% 车牌粗定位:根据车牌区域在水平方向灰度值具有明显频繁的跳变,可求边缘提取后水平方向的差分,然后进行水平方向上的投影,也即沿水平方向进行相邻像素差分值的累加,绘制的投影图横轴为图像高度,原点为左上角,纵轴即为沿水平方向的差分值累加和。差分累加

12、车牌纵向定位图像高度纵向定位function Menu_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列,依次减下去 c

13、um_horz = sum(diff_horz);%对图像矩阵先转置,再投影 figure; %绘制投影图形,横轴为1到图像高,纵轴为水平方向差分值累计和 bar(1:hig,cum_horz,r); title(horizontal projection); % 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(vertical projection

14、); %通过观察投影图,给出车牌的大概位置是,左上角坐标为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 = i

15、mgOut; handles.flag = 1; guidata(hObject,handles); figure(handles.mainFrm); set(handles.mainFrm,Position,handles.pos); image(imgOut); colormap(gray(256); axis off; set(handles.Menu_FineLocate,Enable,On); set(handles.Menu_RoughLocate,Enable,Off); set(handles.Menu_CharacterCutout,Enable,Off); set(hand

16、les.Menu_LicenseRecognition,Enable,Off);end第四步:车牌微定位 如下图,在粗定位结果的根底上,还需要把红色边框外的图像去掉,以进一步确定字符范围,缩减车牌的左右上下边界,以便后续字符处理。function Menu_FineLocate_Callback(hObject, eventdata, handles)if isempty(handles.imgOut) imgIn = double(handles.imgOut);%传入粗定位的结果图像 hig,wid = size(imgIn);% 取图像大小 lef_tem = wid * ones(hi

17、g,1); % 构建一个hig行,1列的值全为1的矩阵,与wid相乘,矩阵值全部为wid rig_tem = zeros(hig,1); %构建一个hig*1的0矩阵 for i = 1:hig for j = 1:wid-1 %从左到右扫描,遇到相邻像素的灰度值差值大于60时,停止扫描,记以下号,说明此列是车牌左边界 tem = imgIn(i,j+1) - imgIn(i,j); if tem = 60 lef_tem(i) = j+1; break; end end%从右向左扫描,遇到相邻像素的灰度值差值大于60时,停止扫描,记以下号,说明此列是车牌右边界 for j = wid : -

18、1 : 2 tem = imgIn(i,j-1) - imgIn(i,j); if tem = 60 rig_tem(i) = j-1; break; end end end4 lef = min(lef_tem);%每一行都可以扫描得到一个左边界,取其中最小的 rig = max(rig_tem); %每一行都可以扫描得到一个右边界,取其中最大的%这也是lef_tem、rig_tem在初始化定义的时候分别为ones全为1的矩阵和全为zeros 0的矩阵的原因 top_tem = hig * ones(wid,1); bot_tem = zeros(wid,1); for j = lef:ri

19、g for i = 1:hig-1 tem = imgIn(i+1,j) - imgIn(i,j); if tem = 60 top_tem(j) = i+1; break; end end for i = hig : -1 : 2 tem = imgIn(i-1,j) - imgIn(i,j); if tem = 60 bot_tem(j) = i-1; break; end end end top = min(top_tem); %按同样的方法找到上下边界,注意图像左上角为原点 bot = max(bot_tem); handles.lef = handles.lef + lef - 1;

20、 %在原始图像上定位微定位后车牌的位置 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.

21、pos); image(imgOut); colormap(gray(256); axis off; 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第五步:字符分割% function Menu_CharacterCutout_Callback(hObject, eventdata, h

22、andles)if handles.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 + mi

23、nvalue+30)/2); imgOut = JudgeAnalysis(imgIn); %对图像进行二值化,然后反转label,num = bwlabel(imgOut); %对二值图像进行连通成分的标记 %对于以上两个中间变量的结果,大家可以在Matlab的workspace中查看其结果变化,理解 k = 0; for i = 1:num %以下代码为找到像素总数小于10的连通成分,剔除,这里6个字符,但有7个连通成分,剔除其中较少像素的连通成分 tem = (label = i); %把所有label为i的像素统计出来 if sum(tem(:) = 1) k = k+1; coord

24、x(k) = j-1; elseif (proj_vert(j) = 0) & (tem2 = 1) k = k+1; coordx(k) = j+1; endend%如果倒数第二列不为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); %将

25、其反转回来在0-255之间显示 colormap(gray(256); axis off; hold on; for j = 1:k x = coordx(j) * ones(1,hig);%将x的数目变成和y一样多,组成(x,y)坐标点对 y = 1:hig; plot(x,y,b); hold on; end hold off; %根据上面所找边界线,对字符进行实际的分割 for j = 1:num tem_wid(j) = coordx(2*j) - coordx(2*j-1) + 1; %每个字符由一对边界线分割而成,由右边边界线减去左边边界线的位置,得到的是此字符的宽度 tem =

26、imgOut(:,coordx(2*j-1):coordx(2*j);%取出每一字符的实际数据 proj_horz = sum(tem);%对该字符的行求累加值 for k = 1:hig %从上往下扫描,找出第j个字符的上边界 if proj_horz(k) = 0 tem1 = k; coordy(j,1) = tem1; break; end end for k = hig:-1:1 %从下往上扫描,找出第j个字符的下边界 if proj_horz(k) = 0 tem2 = k; coordy(j,2) = tem2; break; end end tem_hig(j) = tem2

27、- tem1 + 1; %找出每一字符的高度 end %以最大的宽和高来统一每个字符的大小 maxwid = max(tem_wid); %总共有6个字符,找出其中最宽的 maxhig = max(tem_hig); %总共有6个字符,找出其中最高的 for k = 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(max

28、hig,maxwid);%初始化为大小统一 Norm_Char(1:hig,1:wid,k) = imgOut(top:bot,lef:rig);%取出每一字符数据 end handles.Norm_Char = Norm_Char; handles.flag = 1; guidata(hObject,handles);% for k = 1:num% figure;% image(uint8(255*Norm_Char(:,:,k);% colormap(gray(256);% axis off;% end set(handles.Menu_LicenseRecognition,Enable,On); set(handles.Menu_RoughLocate,Enable,Off); set(handles.Menu_FineLocate,Enable,Off); set(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论