基于matlab+模板匹配的车牌识别

一、前言

       随着我国经济的快速发展,汽车拥有量的急剧增加,公路交通成为我国重要的交通运输途径,是国家大力发展的基础设施之一。因此,交通管理的现代化和智能化就越来越显得重要和亟迫。利用电子信息技术来提高管理效率、交通效率和打造安全的智能交通系统已成为当前交通管理发展的主题。实现交通管理现代化和智能化的核心技术之一就是车牌自动识别技术。与传统的车辆管理方法相比,它大大提高了管理效率和水平,节省了人力、物力,实现了车辆管理的科学化、规范化,对交通治安起到了保障作用,拥有广泛的应用前景。

        现在正值暑假期间,楼主在家复习图像处理的基础知识,准备为今年的秋招增加一点砝码,为了巩固知识点以及联系的作用,就看文献以及查找资料制作了一个车牌识别的系统,这个车牌的识别系统是基于matlab的,程序实现起来比较的简单,做的也比较粗糙,所以准确率来说相对低了很多,但是整体的框架以及一些步骤用来复习知识点以及项目参考是可以的,所以想要追求高识别率以及覆盖率的童鞋不要抱太大的希望哦,哈哈哈哈嗝!!!

二、结果预览

                            

三、程序框图

          基于matlab+模板匹配的车牌识别_第1张图片

四、代码分析

1.图像的预处理

        这个部分的处理是为了减小、去除原始图像的噪声的影响,同时将原始图像中想要提取的部分得到加强,便于后面的处理。首先,彩色图像的数据量较大并且底色不同的话会对实验结果造成误差,所以我们先将原始图像转为灰度图像;其次,转为灰度图像之后,我们要对灰度图像进行加强并均匀化,灰度的加强可以直接使用histeq直接加强,也可以使用imadjust对于想要加强的部分进行加强操作;最后,我们对加强之后的灰度图进行边缘检测,我这边用到的边缘检测的方法是sobel,其实,在边缘检测方面,canny边缘检测是检测的首选,但是,我一直在尝试的过程中发现,canny检测完后出来的边界的线条过于多,对于下一步的处理造成影响,因此选用了sobel检测,执行完之后的结果如下图所示。

基于matlab+模板匹配的车牌识别_第2张图片  基于matlab+模板匹配的车牌识别_第3张图片  基于matlab+模板匹配的车牌识别_第4张图片

    global picture;
    picture = imread(pictureName);
    picture2Gray = rgb2gray(picture);                %转为灰度图像
    figure,
    subplot(1, 3, 1),imshow(picture);title('原始图像');          
    subplot(1, 3, 2),imshow(picture2Gray);title('原始图像的灰度图');
    subplot(1, 3, 3),imhist(picture2Gray);title('原始图像的灰度直方图');colorbar;
%     grayEn = imadjust(picture2Gray, [], [0.25, 0.75], 2);       %灰度图增强
    grayEn = histeq(picture2Gray);              %灰度图均匀化
    figure, 
    subplot(1, 2, 1), imshow(grayEn);title('灰度增强之后的图像');
    subplot(1, 2, 2), imhist(grayEn);title('灰度增强之后的直方图');
    %边缘检测
    grayEn = imfilter(grayEn, fspecial('average', 3));      %均值平滑增强之后的灰度图像
    pictureOut = edge(grayEn, 'sobel');     
    figure,
    imshow(pictureOut), title('sobel边缘检测之后的图像');
    close all;

 

2.车牌的初步定位

       车牌的初步定位是将车牌位置从整张图像中提取出来,同时去除其他部分的干扰。

       首先,先用腐蚀操作,腐蚀的目的是消除小而无意义的物体,这里选用se[1, 1, 1]的腐蚀算子;接着,对于腐蚀后的图像进行闭运算,平滑图像,这时候的算子se选用长方形的样式,只要小于这个面积值就会被连接在一起,可以看到,闭运算完之后车牌部分被连接在一起了,但是还是有很多其他的东西的干扰;最后,我们使用bwareaopen函数对小面积进行切除,即可得到完美的车牌区域了。

基于matlab+模板匹配的车牌识别_第5张图片  基于matlab+模板匹配的车牌识别_第6张图片  基于matlab+模板匹配的车牌识别_第7张图片

基于matlab+模板匹配的车牌识别_第8张图片    基于matlab+模板匹配的车牌识别_第9张图片

%腐蚀处理去除边界点
    se1 = [1 ; 1 ; 1];
    pictureErode = imerode(pictureIn, se1);
    figure, imshow(pictureErode), title('边缘检测+腐蚀的图像'); 
%     闭运算,先膨胀后腐蚀去除孔洞,可以平滑图像
    se2 = strel('rectangle', [48, 48]);
    pictureClose = imclose(pictureErode, se2);
    figure, imshow(pictureClose), title('经过腐蚀+开运算后的图像'); 
    pictureCut = bwareaopen(pictureClose, 10000);                    %把小面积去掉
    pictureCut = removeLargeArea(pictureCut, 50000);             %把大面积去掉
    figure, imshow(pictureCut), title('初步裁剪完之后的图像');
    % 定位车牌的区域
    pictureRe = regionprops(pictureCut, 'area', 'boundingbox');
%     areas = [pictureRe.Area];    %将面积对象保存到areas里
    rects = cat(1, pictureRe.BoundingBox);      
   %将面积对象的边界条件链接并保存到rects,顺序为[起始点x坐标, 起始点y坐标, 面积对象长度(x), 面积 
   %对象宽度(y)]      
    figure, imshow(pictureCut), title('红色框标记完之后的图像');  
    rectangle('position', rects(1, :), 'EdgeColor', 'r');   %定位车牌区域,并用红色的框标记
    pictureOut = imcrop(picture, rects(1, :));                      %按照红线框切割车牌区域
    figure, imshow(pictureOut), title('裁剪完之后的图像');
    close all;

 

3.倾斜角度的调整

       对于倾斜角度的修正,这里主要用到了randon变换,当然,除了用这个方法之外还可以用hough变换。这里有一篇关于randon变换的介绍,讲的简单易懂,大家可以前往学习一下,附上链接:https://blog.csdn.net/sinat_26681907/article/details/52277598     

       总结一句来说,randon变换就是在其不倾斜的时候水平轴上的各点的线积分,如下图所示:

                              基于matlab+模板匹配的车牌识别_第10张图片         

      对于水平倾斜角度的调整:

        我们先将图像逆时针旋转90°以便我们进行擦欧总,当我们对于倾斜的图像进行radon变换之后,变换之后的结果在其倾斜角度的位置表现出最大的落差,因此,我们可以通过一阶微分函数对其进行求导然后求出其绝对值的累加和,寻找得到最大值的角度就是我们索要求得角度,再通过旋转变换imrotate得到修正后的图形。

           基于matlab+模板匹配的车牌识别_第11张图片     

           基于matlab+模板匹配的车牌识别_第12张图片   

    pictureGray1 = rgb2gray(pictureIn);
    %水平方向调整
    T=affine2d([0 1 0;1 0 0;0 0 1]);
    pictureTr=imwarp(pictureGray1,T);              % 图像转置,顺时针旋转90°调整水平方向
    theta = -20 : 20;                                       %设置倾斜角度的范围
    r1 = radon(pictureTr, theta);                      %radon变换确定倾斜角
    result1 = sum(abs(diff(r1)), 1);          %求出行倒数绝对值的累加和,最大的对应倾斜角
    rot1 = find(result1==max(result1))-21;
    pictureRo = imrotate(pictureIn, rot1);
    figure, imshow(pictureIn), title('调整之前');
    figure, imshow(pictureRo), title('调整水平角度之后的图像');

 

        对于竖直倾斜角度的调整:                                                                                                  

        对于竖直角度,我们采用和水平角度一样的方式,求radon变换,然后求其一阶导数绝对值的累加和,最大值就是我们所要求的倾斜角度,不过和水平不一样的是,竖直方向其实是同一行的元素之间的错位偏移,如图:

                           

        对于逆时针是一样的道理,这里就不加以赘述,对于这个变换,我们可以生成一个变换向量T,然后用imwarp对图像进行集合变换即可得到我们想要的图像。

        基于matlab+模板匹配的车牌识别_第13张图片 

       基于matlab+模板匹配的车牌识别_第14张图片

%竖直方向调整
    pictureGray2 = rgb2gray(pictureRo);
    r2 = radon(pictureGray2, theta);
    result2 = sum(abs(diff(r2)), 1);
    rot2 = (find(result2==max(result2))-21)/57.3;           %将数值转为角度
    if rot2>0
        T1 = affine2d([1 0 0 ; -tan(rot2) 1 0 ; size(pictureGray2, 1) * tan(rot2) 0 1]);
    else
        T1 = affine2d([1 0 0 ; tan(-rot2) 1 0 ; size(pictureGray2, 1) * tan(-rot2) 0 1]);
    end
    pictureOut = imwarp(pictureRo, T1);
    figure, imshow(pictureOut), title('水平+竖直调整之后的图像');
    close all;

4.车牌的精确定位

        车牌的精确定位实际上就是去除边框的过程,图像只留下字符的部分,这部分我这里采用的方法是计算各个行列的差分的累加和,在变化最大的部分即确认为边框的位置,一般在没有太多干扰的时候这个方法是挺管用的,但是还是存在着切割不准确的问题,因此我把最大值的位置控制在了图像的前四分之一和后四分之一的部分,提高了准确率;除此之外,我还查找了论文中其他的方法,其中切割的方法还可以将图像转为二值化后去判断同一行是否有超过某一数值的连续的1的出现,这样也能确定出边框的大概位置(这个方法我还没有尝试,但是逻辑是挺好的),以下是我的切割后的图像:

  基于matlab+模板匹配的车牌识别_第15张图片  

 基于matlab+模板匹配的车牌识别_第16张图片

5.字符分割及其归一化

       这部分是将精确定位完之后的图像进行切割,从而独立出每个字符,切割之前先将图像进行二值化并且均匀化处理,这里我把图像的长度分成15等分,出去中间的圆点只占一份之外,其余部分的字符都是占用两个位置,这样不仅能去除圆点,还可以顺利的分割出字符,分割完之后的字符进行48*24的归一化处理,方便之后的模板匹配。

   基于matlab+模板匹配的车牌识别_第17张图片 

 基于matlab+模板匹配的车牌识别_第18张图片

% 去除上、下边框以及铆钉
    pictureGray1 = rgb2gray(pictureIn);
    [mY1, nY1] = size(pictureGray1);
    yresult = sum(abs(diff(pictureGray1)), 2);%1为列, 2为行
    yresult = imfilter(yresult, fspecial('average', 6));
    %计算上界坐标
    yTemp1 = yresult(10 : ceil(mY1/4), 1);
    [~, ymin] = max(yTemp1);
    %计算下界坐标
    yTemp2 = yresult(ceil(mY1/4) : (mY1 - 1), 1);
    [~, ymax] = max(yTemp2);
    ymax = ymax + ceil(mY1/4);
    pictureCutY =  imcrop(pictureIn, [1, ymin+5, nY1 , (ymax - ymin)-8]);
    
    % 去除左、右边框
    pictureGray2 = rgb2gray(pictureCutY);
    [mX, nX] = size(pictureGray2);
    xdiff = zeros(mX, nX-1);
    for i = 1:mX
        xdiff(i, :) = abs(diff(pictureGray2(i, :)));            %计算各列之间的差值并累加
        xresult = sum(xdiff, 1);
    end
    xresult = imfilter(xresult, fspecial('average', 6));
    %计算左界坐标
    xTemp1 = xresult( 1, 1 : ceil(nX/5));
    [~, xmin] = max(xTemp1);
    %计算右界坐标
    xTemp2 = xresult( 1, ceil(4*nX/5):(nX - 1));
    [~, xmax] = max(xTemp2);
    xmax = xmax + ceil(4*nX/5);
    pictureOut =  imcrop(pictureCutY, [xmin, 1,  (xmax - xmin) , mX]);
    figure, imshow(pictureOut), title('精确定位之后的图像');
    figure, imshow(pictureIn), title('定位之前');
    close all;

 

6.字符识别

        字符识别部分可以采用模板识别和bp神经网络的方法,因为自己对于神经网络这一块不熟悉,并且车牌字符相对而言比较工整,因此这里采用模板识别的方法,对于切割完之后的图像和模板逐一像素点进行比较,相同则加1,最后看看和哪个的匹配度最高就输出哪个,方便、快捷。

                                             基于matlab+模板匹配的车牌识别_第19张图片  

                                            基于matlab+模板匹配的车牌识别_第20张图片

以汉字为例(这里只用5个汉字):

    result = zeros(1, 5);    
    for i =35:39
        filename = strcat('F:\matlab\shibie\zifu\', int2str(i), '.jpg');
        shuzi = imread(filename);
        level = graythresh(shuzi);          %ostu自动分割阈值法
        shuzi = imbinarize(shuzi, level);
        shuzi = imfilter(shuzi, fspecial('average', 3));
        Num =0;
        for j =1:48
            for k = 1:24
                if ( picture(j, k) == shuzi(j, k))
                    Num = Num+1;
                end
            end
        end
        result(1, i-34) = Num;
    end
    num = find(result == max(result));
    switch num
        case 1
            out = '沪';
        case 2
            out = '晋';
        case 3
            out = '陕';    
        case 4
            out = '粤';    
        case 5
            out = '桂';    
    end

五、总结

       总的来说,在整个过程中通过自己查找资料,认真分析,最后的结果还是比较满意的,但是这个例子仅仅是作为熟悉编程过程,认识图像处理相关函数而言来说的,本身算法的难度比较低,加之自己对于图像这方面还有待加强和学习,因此识别的概率也比较低,追求成功率的童鞋不要喷哦。做完这个设计,就要准备好好复习一下基础知识了,秋招啊秋招,难的一匹,希望之后会有好消息。

完整代码和照片、字符样本、论文下载地址:

https://download.csdn.net/download/j_m_chen/10572194           

参考文献:[1]陈鼎. 基于Matlab的车牌识别系统的研究[D].南昌大学,2018.

     [2]贾晓丹,李文举,王海姣.一种新的基于Radon变换的车牌倾斜校正方法[J].计算机工程与应用,2008(03):245-248. 

     [3]radon变换  https://blog.csdn.net/sinat_26681907/article/details/52277598

     [4]Matlab 插值算法(最邻近、双线性、双三次插值  https://blog.csdn.net/u013146742/article/details/52923864

     [5]matlab的Regionprops详解  https://blog.csdn.net/langb2014/article/details/49886787

     [6]呙润华,苏婷婷,马晓伟.BP神经网络联合模板匹配的车牌识别系统[J].清华大学学报(自然科学版),2013,53(09):1221-1226.

     [7]卢博超. 车牌定位与字符识别的方法研究[D].华北理工大学,2017.

     [8]隋君. 基于数字图像处理技术的车牌识别系统研究[D].吉林大学,2016

 

你可能感兴趣的:(基于matlab+模板匹配的车牌识别)