基于MATLAB的车牌识别基本原理及算法讲解

  本博文为由星火燎原研发中心推出的基于MATLAB的车牌识别项目的配套解释博文,主要介绍各步骤算法的原理及用到的函数,方便大家快速理解该程序的工作原理,并在此基础上进行修改或者二次开发,该程序或者项目的使用方法,二次开发的方法,及注意事项见B站视频讲解



一:GUI界面预览

二:选择图片

  使用uigetfile函数打开一个模态对话框,其中列出了当前文件夹中的文件。在这里选择或输入文件的名称。选择文件点击打开时,uigetfile将返回文件名。如果点击取消或窗口关闭按钮 (X),uigetfile 将返回 0。:

  对应的GUI界面如下:

三:预处理

  (1)灰度化

  使用Rgb2gray函数将 RGB 图像或颜色图转换为灰度图,图像预处理的第一步是图像灰度化处理。该步骤使图像占用空间减少。灰度化处理结束后输出灰度化图像与灰度直方图:

  对应的GUI界面如下:

  (2)边缘检测

  使用edge函数进行边缘检测,在使用edge函数时可以指定要检测的边缘的方向。Sobel 和 Prewitt 方法可以检测垂直方向和/或水平方向的边缘。Roberts 方法可以检测与水平方向成 45 度角和/或 135 度角的边缘。经过分析和实践,使用Sobel方法效果较好,该函数的第三个参数为二值化阈值,把比该值大的置为1

   为了在GUI中方便调试,我们把边缘检测的阈值设定为一个变量edit2_aa,该变量的值可以通过GUI中的文本框进行设定,如下所示:

  对应的GUI界面如下:

四:车牌定位

  (1)图像腐蚀

  使用imerode() 函数进行图像腐蚀,来去除上一步边缘检测后遗留的噪声点, J = imerode(I,SE) 腐蚀灰度图像、二值图像或压缩二值图像 I,返回腐蚀图像 J。其中SE 是结构元素对象或结构元素对象的数组,由 strel 或 offsetstrel 函数返回。本列中由strel函数返回结构元素SE。

  为方便在GUI中进行调试,矩形结构元素的行数由GUI中可编辑文本框输入,默认为2,列数固定为1

  对应的GUI界面如下:

  可以发现经过图像腐蚀后,去除了除车牌外的干扰点


  (2)平滑处理

  使用 imclose函数,即闭运算:用结构元素对图像先膨胀,再腐蚀。对图像进行平滑处理,闭运算可以用来融合窄的缺口和细长的弯口,去掉小洞,填补轮廓上的缝隙

  本部分的结构元素采用一个大小为 [n n] 的矩形结构,其中矩形结构的行数及列数由GUI的可编辑文本框进行设定

  对应的GUI界面如下:

  可以发现经过平滑处理后,覆盖的区域跟车牌区域吻合度更好了,便于车牌的定位和切割


  (3)移除对象

  使用bwareaopen 函数可以用于从二值图像中删除小对象。该函数使用格式为 BW2 = bwareaopen(BW,P) 从二值图像 BW 中删除少于 P 个像素的所有连通分量(对象)并生成另一个二值图像 BW2。此运算称为面积开运算。

   为GUI方便调试,我将bwareaopen函数的第二个参数,通过GUI可编辑文本框输入,并进行调试

  对应的GUI界面如下:

  由于前一步的平滑处理后并没有小区域,所以对此步而言,效果并不明显。

  (4)定位剪切

  对应的GUI界面如下:

  可以发现通过前面的边缘处理、图像腐蚀、平滑处理、移除对象等操作,图像裁剪效果较好。

五:车牌识别

  (1) 灰度处理

  对原图像进行车牌定位,并把车牌裁剪出来后,要重新进行灰度处理,便于后续的操作。

  对应的GUI界面如下:

  (2) 直方图均衡化

  使用 histeq 函数进行直方图均衡化来增强对比度 其函数使用格式为J = histeq(I,n) 其中I为变换灰度图像,J为输出灰度图像,它具有 n 个 bin 的直方图大致平坦。为方便调试,我们将n的值通过GUI的可编辑文本框进行输入

  对应的GUI界面如下:

  (3) 二值化图像

  使用 imbinarize函数进行二值化 ,通过阈值化将二维灰度图像或三维体二值化 ,该函数通过将所有高于全局阈值的值替换为 1 ,并将所有其他值设置为 0,从二维或三维灰度图像 I 创建二值图像。 在默认情况下,imbinarize 使用 Otsu 方法,该方法选择特定阈值来最小化阈值化的黑白像素的类内方差

   imbinarize(I,T) 使用阈值 T 从图像 I 创建二值图像。T 可以是指定为标量亮度值的全局图像阈值,也可以是指定为亮度值矩阵的局部自适应阈值 ,为方便调试,我们将T的值通过GUI的可编辑文本框进行输入。

  对应的GUI界面如下:

  (4) 移除对象

  使用bwareaopen 函数可以用于从二值图像中删除小对象。该函数使用格式为 BW2 = bwareaopen(BW,P) 从二值图像 BW 中删除少于 P 个像素的所有连通分量(对象)并生成另一个二值图像 BW2。此运算称为面积开运算。

   为GUI方便调试,我将bwareaopen函数的第二个参数,通过GUI可编辑文本框输入,并进行调试

   进行此步骤的目的是去除裁剪后车牌的白边和噪声点、干扰点等对后续字符切割造成干扰的信息

  对应的GUI界面如下:

   通过对比,可以明显的观察到,经过车牌识别移除对象操作,很好的去除了B和8之间的圆点,这个圆点如果不去除,对后续的裁剪将会造成很大的干扰,除此之外,位于车牌轮廓的白线及其他噪声点也被消除掉了,经过此步后,车牌内容只剩下要识别的七个字符,对后续的裁剪打下来良好的基础。


  (5) 中值滤波

  使用 medfilt2 函数进行二维中位数滤波, 其格式为 J = medfilt2(I,[m n]) 执行中位数滤波时,其中每个输出像素包含输入图像中对应像素周围的 m×n 邻域中的中位数值。

  在此处添加该步骤并不是为了滤除孤立的噪声点,仅仅是为了将图像字符的边界进行平滑处理,属于对图像的优化操作,若前面的步骤进行的较好,则本步骤的作用并不明显,因此,在操作时可以根据需要灵活选择是否跳过该步骤。

  对应的GUI界面如下:

   通过对比,可以明显的观察到,经过车牌识别移除对象操作,很好的去除了B和8之间的圆点,这个圆点如果不去除,对后续的裁剪将会造成很大的干扰,除此之外,位于车牌轮廓的白线及其他噪声点也被消除掉了,经过此步后,车牌内容只剩下要识别的七个字符,对后续的裁剪打下来良好的基础。


   (6) 图像切割(本部分程序较长,就不放了,见工程文件435-528行,及my_imsplit函数)

  该步骤进行的操作及思路为:首先读取经过中值滤波后的图像数据,调用我们写的my_imsplit函数,对图像进行初步裁剪,在该函数中,依次进行了:获取图像的大小、获取字符的顶部位置、获取字符的底部位置、获取字符的左边界、获取字符的右边界、得到宽和高、裁剪等步骤

  其中在通过size函数得到图像的尺寸信息后,从第一行开始按行向下搜索,找到第一个行像素和非零的行作为图片的顶部位置,然后从左后一行,向上搜索,找到第一个行像素和非零的行作为图片的底部位置,同理和获得左边界和右边界

  为了方便后续识别,我们在找出的上下边界的基础上,向上和向下各拓展了10个像素(若叠加后不超出边界)

  之后的到裁剪后的宽度和高度,调用MATLAB的imcrop函数,对图像进行裁剪,该函数用于返回图像的一个裁剪区域,该函数的第一个参数为需要裁减的图像,第二个参数为一个包含四个元素的行向量,其中第一个和第二个元素为裁剪的左上角的坐标点,第三第四个元素为裁剪后的宽度和高度

  回到主函数文件中,在裁剪完成后进行的操作是第一个字符的切割,首先通过找到第一个像素和非零的列,来作为第一个字符的左边界,在此基础上继续向右搜索,找到第一个像素和为零的列,作为右边界,接下来通过找到的该字符的宽度与车牌整体宽度的比值来判断是否裁剪异常,若异常则选取左右边界内像素和最小的列作为右边界,并将其置零。并进行多项异常检测与纠正。

  每裁剪出一个字符,就将车牌中其对应位置的像素均清零,方便后续搜寻

  同理可以得到后面的六个字符,将裁剪后的字符的大小统一制定为[40 20],进行保存,并绘制出图像

  其切割效果如下::

   可以发现切割效果较好

   (7)模板匹配

  我们将要识别的字符放置到一个字符串中,该字符串的第1到第10的元素存放数字0到9,第11到34的元素存放字母A~Z(除I和O),第35个存放汉字鲁

  对于每个字符,我们首先读取之前裁剪出的车牌字符,并调整图片的大小,进行二值化处理,对于第一个字符设定其搜索范围为35,第二个字符搜索范围为11到34,其余的字符搜索范围为1到34

   接着读取字符库的图片模板跟车牌中裁剪出的字符进行匹配,此处的匹配我们用了两种方法,基础方法是对比两张图片的每一个像素点,统计其不相等的像素个数,并将相似度最高的模板作为识别结果,并将识别的结果通过msgbox函数进行展示

  识别结果为:

六:结果转换

   (1) 车牌模板匹配

  IDFind函数的作用是,输入一个字符串,也就是识别出的车牌,将其与模板库里的车牌进行匹配,寻找相似度最高的一个作为匹配结果,其中IDLib用来存放需要匹配的车牌号与其对应的隐含信息等,该函数返回量依次为,匹配的车牌号、设定的其他隐含信息

   (2) 生成二维码

  该部分用于识别的车牌匹配出的数字信息转换成二维码进行显示,包含了要求的灰度二维码以及拓展提高的QR二维码

   其中QRcode函数用来生成QR二维码,其代码如下:

   其中graycode函数用来生成灰度二维码,其代码如下:

   灰度二维码的转换过程为:将匹配的数字信息传入该函数,对每一个学号进行提取,并按比例放缩到0 ~ 255像素之间,也就是转换成灰度值进行显示,将0 ~ 255划分成10部分依次对应数字0~10。

   对应的GUI界面如下:

七:拓展提高–使用神经网络进行车牌识别

   (1) 网络训练(该部分程序较长,就不放了,见工程文件BP_train.m)

   将已有的切割出的N个车牌字符作为输入量,其对应的正确的识别字符在licode中的索引值作为输出值进行网络训练,首先我们需要挨个读入字符照片(40x20),然后将其通过sum(:2)转换为列向量,这样最终得到的40xN打的矩阵作为训练网络的输入值,其中N为训练的字符个数,调节好神经网络的参数后,对网络进行数据进行归一化处理,并调用网络进行网络训练,将训练好的网络通过save命令进行保存,同时两个归一化参数也需要保存,供后续识别使用

   (2) 调用训练好的网络进行车牌识别

   其中BP_NET()函数用来调用训练好的网路进行识别,其代码见工程文件BP_NET.m,在BP_NET()函数中,首先要读取训练好的网络及归一化变量,对读入的每个切割出的字符要进行处理,将其转换为40x1的列向量,每次车牌识别需要识别六个字符(鲁字不识别),最终得到的40x6的数组作为输入量进行网络预测,调用网络进行预测,将预测的车牌号作为返回量进行输出

   (3) 算法切换的实现

   其中BP_NET()函数用来调用训练好的网路进行识别,其代码见工程文件BP_NET.m,在BP_NET()函数中,首先要读取训练好的网络及归一化变量,对读入的每个切割出的字符要进行处理,将其转换为40x1的列向量,每次车牌识别需要识别六个字符(鲁字不识别),最终得到的40x6的数组作为输入量进行网络预测,调用网络进行预测,将预测的车牌号作为返回量进行输出

   通过GUI界面的一个按钮组进行算法的选择与切换,如下所示:

猜你喜欢

转载自blog.csdn.net/qq_44339029/article/details/119427477
今日推荐