车牌识别的MATLAB实现
目录
1.图像数据读入
2.图像转换
3.边缘检测
4.腐蚀处理
5.平滑处理
6.移除小对象
7.确定车牌位置
8.定位剪切
9.车牌图像二值化
10.均值滤波,膨胀或腐蚀处理
11.切割
12.分离字符
1.图像数据读入
要实现车牌识别,首先要从计算机中读取含有要识别车牌的图片,为了使用户更方便地从文件系统中直接选取图片,这里使用了uigetfile函数。
uigetfile函数的调用格式为:[filename,filepath]=uigetfile(…),执行此函数可得到供用户选择图片文件的对话框,用户选择要识别的图片并点击“打开”按钮后,会返回此图片的文件名和路径名,分别保存到filename和pathname两个变量中(为了避免用户在对话框中选择非图片文件出现异常,在调用uigetfile函数时将函数参数设置成了“.png;.jpg”,所以文件选择对话框中只会出现图片文件),然后通过imread函数将图像数据读出,赋值给变量I,从而实现图像数据的读入。
2.图像转换
由于彩色图不易确定车牌边界,将彩色图转换为灰度图以进一步处理图片。这里使用了rgb2gray函数,该函数接收一个rgb图像变量作为参数,返回该图像转换为灰度图后的图像数据,并将该数据赋值给变量I1。
若想得到该灰度图的灰度分布情况,可使用imhist函数画出该灰度图的灰度值分布直方图。
3.边缘检测
在将彩色图转换为灰度图后,便可用edge函数识别该图像的边界,edge函数通过使用一阶导数和二阶导数检测亮度的不连续来确定图像的边界,它可以使用Sobel,Prewitt,Roberts,Canny,LoG,零交叉等多种算子,这里使用最强大的Canny算子进行边缘检测。
edge函数的调用格式如下:
BW = edge(I,’canny’,THRESH,SIGMA)
4.腐蚀处理
由于边缘检测后的图像中无关结构太多,这里需对图像进行腐蚀处理,实现腐蚀处理的函数为imerode,它接收一个图像数据和一个结构子,图像中背景与结构子完全重合的像素点输出值为1,不完全重合的和完全不重合的像素点输出值为0,最后返回使用该结构子腐蚀过后的图像数据,以此实现削减无关结构的目的。
5.平滑处理
腐蚀后的图像结构大多呈分散状分布,不连贯。为了方便之后确认车牌位置,这里需对该图像进行平滑处理,在此我们使用闭操作使车牌平滑,并减小噪音,闭操作可以理解为先膨胀后腐蚀,实现函数为imclose,调用格式如下:
IM2 = imclose(IM,SE)
(其中IM是图像数据,SE是结构子)
6.移除小对象
为了使接下来车牌位置的确定更精确,这里使用了bwareaopen函数从图象中移除小对象,调用格式如下:
BW2 = bwareaopen(BW,P,CONN)
7.确定车牌位置
在经过上面的处理之后,最初要识别的彩色图像已经变成了以车牌为主要结构的二值图像,我们可以对这种主体结构清晰的二值图像进行扫描,进而确定出车牌的位置。
这里确定车牌位置的思路为:
首先使用size函数得到该图像矩阵的行数y和列数x,用zero函数建立一个y行1列的零矩阵white_y,然后使用嵌套循环结构遍历该二值图像的每一个像素点,把每行值为1的像素点(也就是白色像素点)的数量分别记录在先前创建的矩阵white_y中。遍历完之后,找出white_y矩阵中值最大的元素,它所对应的行即为该二值图像中白色像素点最多的行,该行可认为是靠近车牌中心的一行。
然后我们以这一行为起点,分别向上向下逐行扫描,当被扫描到的行中白色像素点多于120时(该值只是一个用于判断的估计值),继续向上(或向下)扫描,直到扫描到某行中的白色像素点数量小于120时,停止扫描,并记录这一行的行数,该行数即为车牌的上边界(或下边界)。
同理,我们可以用相同的方法确定出车牌的左边界和右边界。
8.定位剪切
通过以上定位,我们得到了车牌的上边界PY1,下边界PY2,左边界PX1,右边界PX2,我们可以通过这四个边界值从原彩色图像中切割出车牌:
dw=I(PY1:PY2,PX1:PX2,:);
9.车牌图像二值化
在得到车牌的彩色图像之后,为了便于将其中的字符分离,我们将它转换为二值图像,具体代码如下:
g_max=double(max(max(b)));
g_min=double(min(min(b)));
T=round(g_max-(g_max-g_min)/3);
[m,n]=size(b);
d=(double(b)>=T);
10.均值滤波,膨胀或腐蚀处理
在车牌转换为二值图像后,为了使图像中干扰元素减少,我们对其进行均值滤波,通过fspecial函数构造均值滤波器,然后使用filter2函数进行滤波,以减小图中噪音。
由于不同原始图像的差异,处理到这里后,字符可能会不连续,也可能会连在一起,这时我们需要再次对滤波后的图像进行腐蚀或者膨胀处理,这里使用判断结构以图中白色部分的面积为判断依据决定使用腐蚀或者膨胀。
11.切割
在分离字符之前,我们还要切去车牌边缘的黑色部分,在这里我们定义了一个用于切割的函数qiege,思路如下:
从图像顶部向底部逐行扫描,对扫描到的行求和,若某行全部像素点求和为0(即该行所有像素点均为黑色),则切去这一行,直到扫描到某一行求和后值不为零,以这一行为上边界。
同理,再用相同的方法从其他三个方向扫描,切割出下边界,左边界和·右边界,最后得到切去边缘黑色部分的图像。
12.分离字符
将切割过后,就可以对图片中的字符进行分离了,这里我们定义了一个用于分离字符的函数getword,思路如下:
对图像从左到右逐列扫描,并将每列中像素点的值进行求和,若和不为零(即这一列是组成某字符的一列),则向右继续扫描下一列,直到某一列求和后值为零(即这一列是两白色字符之间的黑色间隔),图像最左侧到这一列之间即为第一个字符,将其切出,然后将该区域内所有像素点赋值为0(涂黑),重复以上操作直至分离出所有字符。
源代码