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

目录

1 处理流程

2 结果展示

3 核心要点解读

4 matlab代码


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

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

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

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

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

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

转载请注明出处,谢谢!

1 处理流程

基于matlab的蓝色车牌识别(车牌字符分割)_第1张图片

2 结果展示

基于matlab的蓝色车牌识别(车牌字符分割)_第2张图片

基于matlab的蓝色车牌识别(车牌字符分割)_第3张图片

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

 

你可能感兴趣的:(车牌识别)