飞道的博客

【数字图像处理】大作业 基于模式匹配的车牌识别

407人阅读  评论(0)

1 课程设计任务

应用数字图像处理相关知识和技术实现某一应用,如人脸识别、动物识别、水果识别等综合性任务,题目自选。
本文在matlab R2018b开发环境下,实现基于模板匹配的汽车牌照识别。
车牌识别在现代交通管理系统中起着至关重要的作用,具有广阔的应用前景,例如红灯抓拍、超速抓拍、小区记录、公路管理等。如何高效快速地准确识别出汽车牌照成为发展趋势,现如今,随着卷积神经网络的不断改进和壮大,其在车牌识别领域发挥着主要作用。但传统识别作为基础而言,是必须理解并能应用的技术,也是为发展神经网络的奠基石,因此,本文采用传统识别模式匹配技术,进行车牌识别。

2 设计框图

3 准备工作

  • 开发环境:
    windows 10
    matlab R2018b
  • 制图软件:
    visio 2013
  • 素材示意:
    汽车图像素材(来源:百度图片)

    模板字符库(来源:CSDN)

    模板字符库不含字母“I”、“O”。

4 任务流程

4.1 图像预处理

  1. 首先将彩色原始图像image_init读入,利用matlab函数rgb2gray转换成灰度图像image_gray。
  2. 接着利用matlab函数imopen对image_gray进行背景image_bgd的提取并过滤,得到车牌增强后的图像image_enhance。
  3. 然后利用自定义函数iterationSeg对image_enhance进行迭代阈值选择,得到二值图像image_bw,此时的二值图像可能含有噪声。
  4. 最后利用自定义函数average_filter对image_bw进行均值滤波,阈值选择当目标点邻域的8个像素中有3个为白像素时,对目标点予以保留,否则删除。

4.2 图像分割

4.2.1 车牌定位

(1) 上下定界——水平扫描

确定车牌的上边界up和下边界down,,得到分割后的车牌图像image_seg1。

%step5-1 水平扫描确定上下车牌边界
[image_scan1,result1]=projection(image_fill,0);%水平扫描
[width,height]=size(image_fill);%获得图像尺寸
temp1=1; %暂存的上边界
temp2=1; %暂存的下边界
T_max=0; %暂存的车牌宽度
result1_mean=mean(result1);%求水平投影的平均值
result1_min=min(result1);%求水平投影的最小值
result1_level=(result1_mean+result1_min)/2;%求水平投影的平均值
for row=1:width-1
    if result1(row)>result1_level
        temp2=temp2+1;
    else
        if(abs(temp2-temp1)>T_max)
            up=temp1;
            down=temp2;
            T_max=abs(temp2-temp1);
        end
        temp1=row;
        temp2=temp1;
    end
end

(2) 左右定界——垂直扫描

确定车牌的左边界left和右边界right,得到分割后的车牌图像image_seg2。

%step5-2 垂直扫描确定左右车牌边界
[image_scan2,result2]=projection(image_seg1,1);%垂直扫描
[width,height]=size(image_seg1);%获得图像尺寸
result2_mean=mean(result2);%求垂直投影的平均值
result2_min=min(result2);%求垂直投影的最小值
result2_level=(result2_mean+result2_min)/2;%求垂直投影的平均值
temp1=1;%暂存的左边界
temp2=1;%暂存的第一个字符的右边界
left=temp1;%左边界
T_char=45/140*width;%实际字符宽度
for col=1:height
    if result2(col)>result2_level
        temp2=temp2+1;
    else
        if (abs(temp2-temp1)>=T_char&&abs(temp2-temp1)/width<=2*T_char)
            left=temp1;
            break;
        end
            temp1=col;
            temp2=temp1;
    end
end

<1> 方法一:根据垂直扫描确定的车牌左边界,由车牌标准计算右边界。

right=left+ceil((down-up)/2*7+(6*10+12));%右边界

<2> 方法二:垂直扫描分别确定车牌的左右边界。

% temp1=height;%暂存的右边界
% temp2=height;%暂存的最后一个字符的左边界
% right=temp1;
% for col=height:-1:1
%     if result2(col)>result2_level
%         temp2=temp2-1;
%     else
%         if (abs(temp2-temp1)/width>=T_char&&abs(temp2-temp1)/width<=2*T_char)
%             right=temp1;
%             break;
%         end
%             temp1=col;
%             temp2=temp1;
%     end
% end

4.2.2 车牌字符分割

垂直扫描确定字符的左右边界,得到左边界数组temp1和右边界数组temp2。

[image_scan3,result3]=projection(image_seg2,1);%垂直扫描
[width,height]=size(image_seg2);%获得图像尺寸
temp1=ones(1,7); %存放每个字符的左边界
temp2=ones(1,7); %存放每个字符的右边界
for pos=1:7
    for col=temp1(pos):height
        if result3(col)>T_char/2
            temp2(pos)=temp2(pos)+1;
        else
            if temp1(pos)~=temp2(pos)
                temp1(pos+1)=temp2(pos);
                temp2(pos+1)=temp2(pos);
                break;
            end
            temp1(pos)=temp1(pos)+1;
            temp2(pos)=temp1(pos);
        end
    end
end
temp2=temp2-1;%多读一列位置,回退

4.3 图像识别

4.3.1 字符细化

  • 根据字符细化的4个条件实现了自定义函数j=thin(i),即对输入图像i进行细化,并将结果送至j。
  • 可以使用系统函数bwmorph(image_seg2,‘thin’,Inf)或thin(image_seg2)对已定位的车牌进行整体细化。再根据字符左边界数组temp1和右边界数组temp2进行字符分割,从而得到每个字符的细化图像〖image_char〗_i (i=1,2,⋯,7)。

4.3.2 字符归一化

  • 实现自定义函数j=normalChar(i),即对输入图像i进行归一化,并将结果送至j。函数实现包括对输入图像i多余黑色边框的切割,以及利用matlab函数imresize对切割黑边后的i进行缩放至宽45,高90的标准尺寸。
  • 对每一个细化后的字符图像进行归一化normalChar(image_char_i)得到图像image_normal_char_i。其中,i=1,2,⋯,7。
  • 设置一个90×45×7的矩阵image_normal_char存放归一化后的图像组。

4.3.3 模板匹配

建立模板库字符索引,对待识别字符进行模板匹配。

char_code=char(['0':'9' 'A':'H' 'J':'N' 'P':'Z' '浙豫苏陕鲁辽京']);%部分字符
char_length=36-2+7;
Y=zeros(7,1);
result=zeros(7,1);
for point=1:7
    %判断待识别字符所处位置
    if point==1
        start=36-2+1;
        ending=36-2+7;
    elseif point==2
        start=10+1;
        ending=10+26-2;
    else
        start=1;
        ending=36-2;
    end
    %获取待识别字符图像
    imageU=image_normal_char(:,:,point);
    [width,height]=size(imageU);
    U=sum(sum(imageU==1));
    %遍历模板库
    for k=start:ending
        fname=strcat('D:\1、数字图像处理\2、习题\大作业\字符模板\',char_code(k),'.jpg');
        imageT=imread(fname);
        imageT=im2bw(imageT);
        imageT=imresize(imageT,[90 45]);
        imageV=imageU&imageT;
        imageX=xor(imageV,imageU);
        imageW=xor(imageV,imageT);
        T_char=sum(sum(imageT==1));
        V=sum(sum(imageV==1));
        X=sum(sum(imageX==1));
        W=sum(sum(imageW==1));
        TUV=(T_char+U+V)/3;
        temp=V/((W/T_char)*(X/U)*sqrt(((T_char-TUV)^2+(U-TUV)^2+(V-TUV)^2)/2));
        if temp>Y(point)
            Y(point)=temp;
            result(point)=k;
        end
    end
end

4.4 调试与运行

  • 由于字符中,字母“Q”和数字“0”、字母“B”和数字“8”、字母“U”和字母“V”之间十分相似,必须根据它们的字符组成特征,单独进行进一步的区分。定义字符高度小于宽度。
  • 可以看出,“Q”和“0”之间的主要区别在于右下角那一块的像素。逐列扫描待识别字符右下角的白像素个数,若细化后的字符仍存在某列的白像素大于3个,即判断这个字符是“Q”,否则为“0”。
  • “B”和“8”的主要区别在于,“B”的最左像素是一条直线,而“8”的最左像素是类似于“ε”的形状,有一定的凹弧。逐列扫描待识别字符的前5列白像素个数,若存在某列白像素个数超过1/4的字符高度,即判断这个字符是“B”,否则为“8”。
  • “U”和“V”的主要区别在于,“U”的左右构造是直线,而“V”的左右构造是斜线。因此逐列扫描待识别字符的前1/2宽度的白像素个数,若存在某列白像素个数超过1/2字符高度,则判断这个字符是“U”,否则为“V”。

5 结果

5.1 图像预处理结果

灰度处理后的图像

过滤背景后的图像

二值化——迭代法

去噪——均值滤波

5.2 图像分割结果


车牌字符定界——垂直扫描

5.3 图像识别结果

图像细化

分割细化后的车牌字符

字符归一化,同时显示识别结果

进一步调整识别


转载:https://blog.csdn.net/qq_44714521/article/details/117255128
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场