⛄一、车牌识别简介
1 车牌图像处理
车牌图像处理主要有五个组成部分:图像灰度化、图像二值化、图像边缘检测、图像形态学运算和图像滤波处理。它是车牌识别系统中最根本且最基础的操作,车牌图像处理的好坏情况、去噪情况和边缘提取情况都将影响图像中车牌字符的提取效果。
(一)图像灰度化
一张正常的彩色照片图像中每个像素点都是由红绿蓝三种颜色构成, 我们称其为RGB图像。而图像灰度化这一步骤就是将彩色RGB图像灰度化为灰度图像, 将图像信息去除色彩信息, 更能体现增强信息, 这就更加便于计算机获取图像当中的信息。进行灰度化处理的方法有很多,运用比较广泛的为以下三种方法:分量法、最大值法和加权平均法。其中分量法就是将R(红)、G(绿)、B(蓝)当中任意一个分量的亮度来作为该像素点的灰度值g(n),即为g(n)=R或g(n)=G或g(n)=B;而最大值法就是在R(红)、G(绿)、B(蓝)当中选取最大的亮度来作为该像素点的灰度值;加权平均法则是先给R、G、B分别赋予不同的权重,然后算其加权平均值,将所算出的加权平均值作为灰度化图像的灰度值g(n),即g(n)=(Ri+Gj+B*k)/(i+j+k)。
(二)图像二值化
图像二值化的处理就是将图像二进制化,则将图像中的每个像素点的像素值用0和255来表示(0和255分别表示该像素点为黑色和白色),而计算机存储该图像是用0和1来标识每个像素点的像素值(像素值为0和255的像素点分别用0和1来标识存储)。图像二值化处理过程为:第一先对图像的像素点进行阈值的选取;第二开始遍历图像中的每一个像素点;第三将每一次遍历到的像素点的灰度值与阈值进行比较,若阈值小于或等于该像素点的话,则该像素点被视为目标区域则用255来表示,否则被视为背景或噪声则用0来表示。那么处理过后的车牌图像将成为一幅黑白图像。
(三)图像边缘检测
车牌识别系统中边缘提取对于车牌位置的检测有很重要的作用,其目的是标识数字图像中亮度变化明显的点。边缘检测需要运用到算子, 本文简单介绍Canny算子的步骤。该算子有以下五个步骤:(1) 预处理。(2) 梯度计算。(3) 梯度处理。(4)边缘提取。(5)抑制孤立弱边缘。经过上面五个步骤最终可使图像完成边缘检测处理环节。
(四)图像形态学运算
图像形态学运算处理有四个基本运算,分别为:膨胀运算、腐蚀运算、开运算和闭运算。其中膨胀运算的作用是用来填补图象中的小空洞和消除小型噪声。腐蚀运算的作用是将图像目标区域中一些无用的目标物通过收缩其边界的方法进而将该无用的目标物去除。闭运算是先膨胀再腐蚀,以用来去除图象中所存在的小空洞。开运算则是先腐蚀再膨胀,先通过腐蚀来消除小而无用的目标物体,再膨胀将图像恢复到原来的大小。由于噪声的因素,车牌图像在二值化后图像当中可能会含有噪声空洞。通过连续的开和闭运算能使这种情况可以使噪声空洞大量减少。
(五)图像滤波处理
图像滤波处理能够在保留图像细节特征的前提下,还可以较好地去除图像中噪声。本文将重点介绍均值滤波和中值滤波。均值滤波也叫线性滤波,主要采用的是领域平均法。该方法首先在滤波像素点的位置套入一个模板图1中所演示的是3x3的模板,然后求出该模板中九个像素点的均值,再将该均值替换掉当前像素点的灰度值,并作为当前像素点的新的灰度值。操作原理图示如图1所示。高斯噪声是存在图像中每个像素点里,其噪声大小的分布呈正态分布(即高斯分布),而椒盐噪声是指分布在单独的几个像素点中,其噪声大小是固定的。正因为这两种噪声的性质,均值滤波能够有效地去除高斯噪声,而对椒盐噪声正好相反。
图1 均值滤波原理图示
中值滤波是一种非线性滤波,它将某一点某邻域内所有像素点灰度值的中值赋给该点。让领域内其他像素点替换掉原来的像素点以更加接近真实值,从而消除噪声点。中值滤波与均值滤波相反,它能够有效地抑制椒盐噪声,但不能有效地去除高斯噪声。
2 车牌定位原理
每张车牌的车牌区域都具有鲜明的特征,即车牌的底色、车牌的字体颜色等,那么就可以运用彩色像素点统计的方法来锁定该图像中的车牌区域。首先,先要确定车牌底色R、G、B三个分量分别对应的颜色范围。其次,在y方向(即水平方向)通过行扫描来统计在该颜色范围内的像素点的个数,设置合理的阈值,从而得到了车牌在图像y方向上的区域。
最后,在得到的y方向的区域内通过列扫描来统计x方向(即垂直方向)上在该颜色范围内的像素点的个数,设置合理的阈值从而进行定位,最终得到图像中车牌区域。
3 车牌字符分割
车牌字符分割即将车牌当中的七个字符单独分割出来(以蓝底白字车牌为例),将单独分割出的车牌再进行统一的大小调整处理,即是归一化处理,之后再转交下一步字符识别操作。
车牌字符分割的方法也有很多种,如投影分割法、基于聚类分析的字符分割等。本文将介绍的则是投影分割法。投影分割分为垂直分割与水平分割两种。二者的区别就在于垂直分割中车牌像素灰度值按垂直方向累加,也另一者是按水平方向累加。由于车牌进行二值化处理,背景区域中的灰度值为零,所以在相邻两个车牌字符之间的灰度值就是零,那么在直方图上这相邻的两个字符之间会形成谷底,而在它们各自的字符处会形成波峰。通过对每个字符波峰中心距、峰上升点、峰下降点、谷底宽度的分析和求解计算,可以有效地分割出各个字符。
五 字符识别
字符识别有以下四种方法可以实现对分割出的字符识别,分别是:结构识别、统计识别、BP神经网络和模板匹配。其中模板匹配是比较常用的方法之一,将获取到的分割字符与模板库中的模板数据一一进行对比,将相似度最大的那个模板数据输出,系统将判定该分割字符即是该模板数据中所对应的字符信息。
⛄二、部分源代码
function varargout = main(varargin)gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...'gui_Singleton', gui_Singleton, ...'gui_OpeningFcn', @main_OpeningFcn, ...'gui_OutputFcn', @main_OutputFcn, ...'gui_LayoutFcn', [] , ...'gui_Callback', []);
if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});
endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
elsegui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT% --- Executes just before main is made visible.
function main_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to main (see VARARGIN)% Choose default command line output for main
handles.output = hObject;% Update handles structure
guidata(hObject, handles);% UIWAIT makes main wait for user response (see UIRESUME)
% uiwait(handles.figure1);% --- Outputs from this function are returned to the command line.
function varargout = main_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structure
varargout{1} = handles.output;% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
dd=imread('222.jpg');axes(handles.axes1);imshow(dd);axes(handles.axes71);imshow(dd);axes(handles.axes64);imshow(dd);
axes(handles.axes65);imshow(dd);
axes(handles.axes70);imshow(dd);
axes(handles.axes67);imshow(dd);
axes(handles.axes66);imshow(dd);
axes(handles.axes68);imshow(dd);axes(handles.axes69);imshow(dd);set(handles.edit32,'string','');
set(handles.edit33,'string','');
set(handles.edit34,'string','');
set(handles.edit35,'string','');
set(handles.edit36,'string','');
set(handles.edit37,'string','');
set(handles.edit38,'string','');
set(handles.edit1,'string','');
global I,global I_bai,
global PY2,global PX1,global PX2,global PY1
set(handles.pushbutton2,'Enable','off');
[filename pathname] = ...
uigetfile({'*.jpg';'*.bmp';'*.gif'}, '');
str=[pathname filename];
I=imread(str);
I_bai=I;
[PY2,PY1,PX2,PX1]=caitu_fenge(I);
axes(handles.axes1);
imshow(I_bai);title('待识别图像');
set(handles.pushbutton2,'Enable','on');
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global I,global PY2,global PX1,global PX2,global PY1,global I_bai,global Plate,global threshold
set(handles.pushbutton6,'Enable','off');
[U V]=size(I);
%===============车牌区域根据面积二次修正======================
[PY2,PY1,PX2,PX1,threshold]=SEC_xiuzheng(PY2,PY1,PX2,PX1);
%==============更新图片=============================
Plate=I_bai(PY1:PY2,PX1:PX2,:);%使用caitu_tiquhold on;line1 = [1 PY1; V PY1];plot(line1(:, 1), line1(:, 2), 'y-', 'LineWidth', 2);pause(1.5);hold on;line2 = [1 PY2; V PY2];plot(line2(:, 1), line2(:, 2), 'r-', 'LineWidth', 2);pause(1.5);hold on;line3 = [PX1 1; PX1 U];plot(line3(:, 1), line3(:, 2), 'g-', 'LineWidth', 2);pause(1.5);hold on;line4 = [PX2 1; PX2 U];plot(line4(:, 1), line4(:, 2), 'b-', 'LineWidth', 2);
set(handles.pushbutton6,'Enable','on');
% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton6 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Plate
axes(handles.axes71);
imshow(Plate);title('边界定位图');
% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton7 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Plate,global bw
bw=rgb2gray(Plate);
axes(handles.axes71);
imshow(bw);title('灰度化');
% --- Executes on button press in pushbutton8.
function pushbutton8_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton8 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global bw,global qingxiejiao
qingxiejiao=rando_bianhuan(bw);
bw=imrotate(bw,qingxiejiao,'bilinear','crop');
axes(handles.axes71);
imshow(bw);title('倾斜校正');
% --- Executes on button press in pushbutton9.
function pushbutton9_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton9 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global bw,global threshold
bw=im2bw(bw);%figure,imshow(bw);
bw=bwmorph(bw,'hbreak',inf);%figure,imshow(bw);
bw=bwmorph(bw,'spur',inf);%figure,imshow(bw);title('擦除之前');
bw=bwmorph(bw,'open',5);%figure,imshow(bw);title('闭合运算');
bw = bwareaopen(bw, threshold);
axes(handles.axes71);
imshow(bw);title('擦除');
% --- Executes on button press in pushbutton10.
function pushbutton10_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton10 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global bw
bw=~bw;
axes(handles.axes71);
imshow(bw);title('反色')% --- Executes on button press in pushbutton11.
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton11 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)global bwbw=touying(bw);
axes(handles.axes71);
imshow(bw);title('裁剪边缘');
% --- Executes on button press in pushbutton12.
function pushbutton12_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton12 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)global bw,global threshold,global qingxiejiao
bw=~bw;
bw = bwareaopen(bw, threshold);
bw=~bw;%figure,imshow(bw);title('二次擦除');
[y,x]=size(bw);%对长宽重新赋值
%=================文字分割=================================
fenge=shuzifenge(bw,qingxiejiao)
[m,k]=size(fenge);
%=================显示分割图像结果========================= %================ 给七张图片定位===============桂AV6388
han_zi =bw( 1:y,fenge(1):fenge(2));
zi_mu =bw( 1:y,fenge(3):fenge(4));
zm_sz_1 =bw( 1:y,fenge(5):fenge(6));
zm_sz_2 =bw( 1:y,fenge(7):fenge(8));
shuzi_1 =bw( 1:y,fenge(9):fenge(10));
shuzi_2 =bw( 1:y,fenge(11):fenge(12));
shuzi_3 =bw( 1:y,fenge(13):fenge(14));
%==========================识别====================================
%======================把修正数据读入==============================
xiuzhenghanzi = imresize(han_zi, [110 55],'bilinear');
xiuzhengzimu = imresize(zi_mu, [110 55],'bilinear');
xiuzhengzm_sz_1= imresize(zm_sz_1,[110 55],'bilinear');
xiuzhengzm_sz_2 = imresize(zm_sz_2,[110 55],'bilinear');
xiuzhengshuzi_1 = imresize(shuzi_1,[110 55],'bilinear');
xiuzhengshuzi_2 = imresize(shuzi_2,[110 55],'bilinear');
xiuzhengshuzi_3 = imresize(shuzi_3,[110 55],'bilinear');axes(handles.axes64);imshow(xiuzhenghanzi);
axes(handles.axes65);imshow(xiuzhengzimu);
axes(handles.axes66);imshow(xiuzhengzm_sz_1);
axes(handles.axes67);imshow(xiuzhengzm_sz_2);
axes(handles.axes68);imshow(xiuzhengshuzi_1);
axes(handles.axes69);imshow(xiuzhengshuzi_2);
axes(handles.axes70);imshow(xiuzhengshuzi_3);%============ 把0-9 , A-Z以及省份简称的数据存储方便访问====================
hanzishengfen=duquhanzi(imread('cpgui.bmp'),imread('cpguizhou.bmp'),imread('cpjing.bmp'),imread('cpsu.bmp'),imread('cpyue.bmp'));
%因数字和字母比例不同。这里要修改
shuzizimu=duquszzm(imread('0.bmp'),imread('1.bmp'),imread('2.bmp'),imread('3.bmp'),imread('4.bmp'),...imread('5.bmp'),imread('6.bmp'),imread('7.bmp'),imread('8.bmp'),imread('9.bmp'),...imread('10.bmp'),imread('11.bmp'),imread('12.bmp'),imread('13.bmp'),imread('14.bmp'),...imread('15.bmp'),imread('16.bmp'),imread('17.bmp'),imread('18.bmp'),imread('19.bmp'),...imread('20.bmp'),imread('21.bmp'),imread('22.bmp'),imread('23.bmp'),imread('24.bmp'),...imread('25.bmp'),imread('26.bmp'),imread('27.bmp'),imread('28.bmp'),imread('29.bmp'),...imread('30.bmp'),imread('31.bmp'),imread('32.bmp'),imread('33.bmp'));
zimu = duquzimu(imread('10.bmp'),imread('11.bmp'),imread('12.bmp'),imread('13.bmp'),imread('14.bmp'),...imread('15.bmp'),imread('16.bmp'),imread('17.bmp'),imread('18.bmp'),imread('19.bmp'),...imread('20.bmp'),imread('21.bmp'),imread('22.bmp'),imread('23.bmp'),imread('24.bmp'),...imread('25.bmp'),imread('26.bmp'),imread('27.bmp'),imread('28.bmp'),imread('29.bmp'),...imread('30.bmp'),imread('31.bmp'),imread('32.bmp'),imread('33.bmp'));
shuzi = duqushuzi(imread('0.bmp'),imread('1.bmp'),imread('2.bmp'),imread('3.bmp'),imread('4.bmp'),...imread('5.bmp'),imread('6.bmp'),imread('7.bmp'),imread('8.bmp'),imread('9.bmp'));
%============================识别结果================================
i=1;%shibiezm_sz该函数识别数字有问题
jieguohanzi = shibiehanzi(hanzishengfen,xiuzhenghanzi);shibiejieguo(1,i) =jieguohanzi; i=i+1;
jieguozimu = shibiezimu(zimu,xiuzhengzimu); shibiejieguo(1,i) =jieguozimu; i=i+1;
jieguozm_sz_1= shibiezm_sz(shuzizimu,xiuzhengzm_sz_1); shibiejieguo(1,i) =jieguozm_sz_1;i=i+1;
jieguozm_sz_2= shibiezm_sz(shuzizimu,xiuzhengzm_sz_2); shibiejieguo(1,i) =jieguozm_sz_2;i=i+1;
jieguoshuzi_1= shibieshuzi(shuzi,xiuzhengshuzi_1); shibiejieguo(1,i) =jieguoshuzi_1;i=i+1;
jieguoshuzi_2= shibieshuzi(shuzi,xiuzhengshuzi_2); shibiejieguo(1,i) =jieguoshuzi_2;i=i+1;
jieguoshuzi_3= shibieshuzi(shuzi,xiuzhengshuzi_3); shibiejieguo(1,i) =jieguoshuzi_3;i=i+1;
%==========================对话框显示显示=============================================NN=shibiejieguo;
%msgbox(shibiejieguo,'识别结果');
%=====================导出文本==================
fid=fopen('Data.xls','a+');
fprintf(fid,'%s\r\n',shibiejieguo,datestr(now));
fclose(fid);set(handles.edit32,'string',char(NN(1)));set(handles.edit33,'string',char(NN(2)));set(handles.edit34,'string',char(NN(3)));set(handles.edit35,'string',char(NN(4)));set(handles.edit36,'string',char(NN(5)));set(handles.edit37,'string',char(NN(6))); set(handles.edit38,'string',char(NN(7)));
% --- Executes on button press in pushbutton13.set(handles.edit1,'string',['车牌号码:',NN]);% --- Executes on button press in pushbutton15.
function pushbutton15_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton15 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
close(gcf);function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispcset(hObject,'BackgroundColor','white');
elseset(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
endfunction edit2_Callback(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispcset(hObject,'BackgroundColor','white');
elseset(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end## ⛄三、运行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210518000747427.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RJUUNtYXRsYWI=,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210518000747424.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1RJUUNtYXRsYWI=,size_16,color_FFFFFF,t_70#pic_center)
## ⛄四、matlab版本及参考文献
**1 matlab版本**
2014a**2 参考文献**
[1]呙润华,苏婷婷,马晓伟.BP神经网络联合模板匹配的车牌识别系统[J].清华大学学报(自然科学版),2013,53(9):1221-1226.
[2]鲁扬.基于BP神经网络的车牌识别算法研究[D].大庆:东北石油大学,2018.
[3]李强,张娟.一种改进的基于模板匹配的污损车牌识别方法[J].智能计算机与应用. 2019,9(03).
[4] 梁凯.基于MATLAB的汽车车牌识别系统的设计与实现[D] .哈尔滨:黑龙江大学, 2018.
[5]刘雄飞,朱盛春.车牌字符多特征提取与BP神经网络的识别算法[J].计算机仿真,2014,31(10):161-164,290.
[6]乔有田.基于数学形态学和灰度跳变特征的车牌定位方法[J].工业控制计算,2015(2):77-78**3 备注**
简介此部分摘自互联网,仅供参考,若侵权,联系删除