基于matlab的蓝色车牌识别(车牌字符分割)

目录

1 处理流程

2 结果展示

3 核心要点解读

4 matlab代码


整套方案还包括以下博客:

(1)基于matlab的蓝色车牌识别(绪论)

(2)基于matlab的蓝色车牌识别(车牌定位)

(3)基于matlab的蓝色车牌识别(车牌倾斜矫正)

(4)基于matlab的蓝色车牌识别(车牌字符分割)

(5)基于matlab的蓝色车牌识别(车牌字符识别)

转载请注明出处,谢谢!

1 处理流程

2 结果展示

3 核心要点解读

去掉上下边框和铆钉:通过统计车牌水平方向的像素跳变次数来定位字符的起始行和结束行。铆钉所在行有6次像素跳变(2个铆钉4次+左右边框2次),字符所在行至少16次跳变(7个字符至少14次+左右边框2次),在行的1/3处往上扫描,在行的2/3处往下扫描,设定一定的跳变阈值,来确定字符的起始行和结束行;

车牌字符分割:首先计算牌照字符的垂直投影,利用投影直方图得到局部最小值,然后再结合车牌字符固定宽度、间距的比例关系等先验知识来分割字符,最后将车牌规整为高宽比为2:1输出。

4 matlab代码

clear;clc;
close all;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 1.预处理图片
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[fn,pn,fi]=uigetfile('矫正后的车牌\*.jpg','选择图片');%(打开文件选择对话框)
img=imread([pn fn]);%输入原始图像
subplot(331);imshow(img);title('原始图像');
I = rgb2gray(img);
subplot(332);imshow(I);title('灰度图像');
I1 = imbinarize(I);
subplot(333);imshow(I1);title('二值图像');
I2 = bwareaopen(I1,20);
subplot(334);imshow(I2);title('去除孤立噪声');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 2.水平和垂直投影(去掉车牌以外的区域)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I3=remove_extra_region(I2);
subplot(335);imshow(I3);title('去除车牌以外的区域');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 3.去掉上下边框和铆钉(统计跳变次数)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% 定位行的起始位置(从1/3处先上扫描行)
%%% 定位行的结束位置(从2/3处先下扫描行)
diff_row = diff(I3,1,2);  % 前一列减后一列
diff_row_sum = sum(abs(diff_row), 2);  
[rows, columns] = size(I3);
trows = ceil(rows*(1/3));
j = trows;
for i=1:trows
    if diff_row_sum(j,1)<10
        plate.rowa = j;
        break;
    end
    j = trows-i;
end

for i=2*trows:size(diff_row_sum,1)
    if diff_row_sum(i,1)<10
        plate.rowb = i;
        break;
    end
end
I4 = I3(plate.rowa:plate.rowb, :);
I4=remove_extra_region(I4);
subplot(336);imshow(I4);title('去除上下边框和铆钉');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 4.去除左右边框(投影法)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
plate_projection_v = sum(I4,1);
for i=1:size(plate_projection_v, 2)
    if plate_projection_v(1,i) == 0
        plate.cola = i;
        break;
    end
end

for i=1:size(plate_projection_v, 2)
    j = size(plate_projection_v, 2) - i + 1;
    if plate_projection_v(1,j) == 0
        plate.colb = j;
        break;
    end
end
I5 = I4(:,plate.cola:plate.colb);
subplot(337);imshow(I5);title('去除左右边框');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 5.去除字符左右背景(投影法)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ppv1 = sum(I5,1);
for i=1:size(ppv1, 2)
    if ppv1(1,i) ~= 0
        pl.cola = i;
        break;
    end
end

for i=1:size(ppv1, 2)
    j = size(ppv1, 2) - i + 1;
    if ppv1(1,j) ~= 0
        pl.colb = j;
        break;
    end
end
I6 = I5(:,pl.cola:pl.colb);
subplot(338);imshow(I6);title('字符车牌');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%% 6.分割字符(垂直投影法)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[height, Twidth] = size(I6);
Cwidth = Twidth*45/409;  % 单一字符宽度
Cspace = Twidth*12/409;  % 字符间距
SecThspace = Twidth*34/409;  % 第二个和第三个字符间距
projection = sum(I6, 1);
subplot(339);stem(projection,'.',...
    'MarkerFaceColor','w',...
    'MarkerEdgeColor','w');
title('字符垂直方向投影');

figure;
for i=1:7
    if i == 1
        k = uint8(floor(Twidth - Cwidth )); % 切换到最后一个字符起始列
    else  % 自右向左逐列扫描
        k = uint8(floor(k - Cwidth - Cspace)); % 切换字符的起始列
    end
    
    % 对特殊情况置一处理
    if k <= 0
        k=1;
    end
    
    % 取当前字符
    fprintf("第%d字符起始列的大概位置:%d \n", i,k);
    fprintf("列投影值:%d \n", projection(1, k));
    character = I6(:, k:ceil(k+Cwidth)+1);
    subplot(178-i);imshow(character);
    
    % 保存当前字符
    j = 8-i;
    cn = strcat(fn(j), '.jpg');
    fprintf('%s \n', cn);
    char = imresize(character,[32, 16],'bilinear');
    imwrite(char,['字符/',cn]);
    
    % 第二个和第三个字符之间的空格特殊处理
    if i == 5
        k = k - SecThspace + Cspace;
    end
end


function I=remove_extra_region(I2)
projection_h = sum(I2,1);
projection_v = sum(I2,2);
for i=1:size(projection_v,1)
    if projection_v(i,1) >= 1
        new.rowa = i;
        break;
    end
end

for i=1:size(projection_v,1)
    j = size(projection_v,1) - i+1;
    if projection_v(j,1) >= 1
        new.rowb = j;
        break;
    end
end

for i=1:size(projection_h ,2)
    if projection_h(1,i) >= 1
        new.cola = i;
        break;
    end
end

for i=1:size(projection_h ,2)
    j = size(projection_h ,2)-i+1;
    if projection_h(1,j) >= 1
        new.colb = j;
        break;
    end
end
I = I2(new.rowa:new.rowb, new.cola:new.colb);
end

 

评论 56
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值