计算机视觉小实例 No.4 车牌定位(一)

车牌识别

分为三个步骤:车牌区域定位、车牌字符分割、车牌字符识别。

车牌区域定位

首先,我们使用Hough变换检测直线来定位车牌边界进而获取车牌区域(还有一种就是用蓝色来进行行列查找,等会会演示,这个方法有一些情况是无法满足要求的)。
但是,在那之前,我们需要对图片进行去噪、二值化处理。

去噪、二值化
f = imread('车牌.jpg');
g = rgb2gray(f);
g = adapthisteq(g);
g = imfilter(g, fspecial('gaussian', [5 5], 0.2));
h1 = edge(g,'sobel', 0.25, 'vertical'); % 使用sobel算子进行边缘检测
h2 = edge(g,'sobel', 0.25, 'horizontal'); % 使用sobel算子进行边缘检测
subplot(1, 3, 1), imshow(g);
subplot(1, 3, 2), imshow(h1);
subplot(1, 3, 3), imshow(h2);

这里写图片描述

接着,再使用Hough检测直线。

f = imread('车牌.jpg');
g = rgb2gray(f);
g = adapthisteq(g);
g = imfilter(g, fspecial('gaussian', [5 5], 0.2));
h1 = edge(g,'sobel', 0.25, 'vertical'); % 使用sobel算子进行边缘检测
h2 = edge(g,'sobel', 0.25, 'horizontal'); % 使用sobel算子进行边缘检测
imshow(f), hold on;
[H theta rho] = hough(h1);
peaks = houghpeaks(H, 50);
lines = houghlines(h1, theta , rho, peaks, 'FillGap', 10, 'MinLength', 25);
len = 0;
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'red');
end
[H theta rho] = hough(h2);
peaks = houghpeaks(H, 50);
lines = houghlines(h2, theta , rho, peaks, 'FillGap', 20, 'MinLength', 50);
len = 0;
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'yellow');
end

这里写图片描述

可以看到,分别用水平、垂直方向的sobel算子来进行边缘检测后进行hough直线检测,可以检测出来牌照的位置。
我们可以按照这样的策略,如果找到二条直线,垂直(水平)方向的长度近似相等,那么这个区域内就是牌照的区域,让我们试一试。

f = imread('车牌.jpg');
g = rgb2gray(f);
g = adapthisteq(g);
g = imfilter(g, fspecial('gaussian', [5 5], 0.2));
h1 = edge(g,'sobel', 0.25, 'vertical'); % 使用sobel算子进行边缘检测
h2 = edge(g,'sobel', 0.25, 'horizontal'); % 使用sobel算子进行边缘检测
[H theta rho] = hough(h1, 'RhoResolution', 0.5);
peaks = houghpeaks(H, 50);
lines = houghlines(h1, theta , rho, peaks, 'FillGap', 10, 'MinLength', 25);
n = 1;
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    LEND(n) = norm(lines(i).point1 - lines(i).point2);
    XYD{n} = xy;
    n = n + 1;
end
[H theta rho] = hough(h2, 'RhoResolution', 0.5);
peaks = houghpeaks(H, 50);
lines = houghlines(h2, theta , rho, peaks, 'FillGap', 20, 'MinLength', 50);
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    LEND(n) = norm(lines(i).point1 - lines(i).point2);
    XYD{n} = xy;
    n = n + 1;
end
imshow(f), hold on;
for i = 1 : n - 1
    for j = 1 : n - 1
        xy1 = XYD{i};
        xy2 = XYD{j};
        k1 = (xy1(2, 2) - xy1(1, 2))/(xy1(2, 1) - xy1(1, 1));
        k2 = (xy2(2, 2) - xy2(1, 2))/(xy2(2, 1) - xy2(1, 1));
        if abs(k1 - k2) < 0.1
            if abs(xy1(1, 1) - xy2(1, 1)) < 5 || abs(xy1(2, 2) - xy2(2, 2)) < 5 || abs(xy1(1, 2) - xy2(1, 2)) < 5 || abs(xy1(2, 1) - xy2(2, 1)) < 5
                plot(xy1(:, 1), xy1(:, 2), 'LineWidth', 2, 'Color', 'red');
                plot([xy1(1, 1), xy2(1, 1)], [xy1(1, 2), xy2(1, 2)], 'LineWidth', 2, 'Color', 'red');
                plot(xy2(:, 1), xy2(:, 2), 'LineWidth', 2, 'Color', 'red');
                plot([xy1(2, 1), xy2(2, 1)], [xy1(2, 2), xy2(2, 2)], 'LineWidth', 2, 'Color', 'red');
            end
        end
    end
end

这里写图片描述

也可以用下面这个方法

function [Plate, bw, Loc] = Pre_Process(Img, parm, flag)

if nargin < 1
    Img = imread(fullfile(pwd, 'images/car.jpg'));
end
if nargin < 2 || isempty(parm)
    if size(Img, 2) > 900
        parm = [0.35 0.9 90 0.35 0.7 90 2];
    end
    if size(Img, 2) > 700 && size(Img, 2) < 900
        parm = [0.6 0.9 90 0.6 0.8 90 0.5];
    end
    if size(Img, 2) > 500 && size(Img, 2) < 700
        parm = [0.5 0.54 50 0.6 0.7 50 3];
    end
    if size(Img, 2) < 500
        parm = [0.8 0.9 150 0.8 0.9 150 3];
    end
end
if nargin < 3
    flag = 1;
end
I = Img;
[y, ~, ~] = size(I); 
if y > 800
    rate = 800/y;
    I = imresize(I, rate);
end
[y, x, ~] = size(I); 

myI = double(I); 
bw1 = zeros(y, x);
bw2 = zeros(y, x);
Blue_y = zeros(y, 1);
for i = 1 : y
    for j = 1 : x
        rij = myI(i, j, 1)/(myI(i, j, 3)+eps);
        gij = myI(i, j, 2)/(myI(i, j, 3)+eps);
        bij = myI(i, j, 3);
        if (rij < parm(1) && gij < parm(2) && bij > parm(3)) ...
                || (gij < parm(1) && rij < parm(2) && bij > parm(3))
            Blue_y(i, 1) = Blue_y(i, 1) + 1; 
            bw1(i, j) = 1;
        end
    end
end

[~, MaxY] = max(Blue_y);
Th = parm(7);
PY1 = MaxY;
while ((Blue_y(PY1,1)>Th) && (PY1>1))
    PY1 = PY1 - 1;
end
PY2 = MaxY;
while ((Blue_y(PY2,1)>Th) && (PY2<y))
    PY2 = PY2 + 1;
end
PY1 = PY1 - 2;
PY2 = PY2 + 2;
if PY1 < 1
    PY1 = 1;
end
if PY2 > y
    PY2 = y;
end
IY = I(PY1:PY2, :, :);

Blue_x = zeros(1,x);
for j = 1:x
    for i = PY1:PY2
        rij = myI(i, j, 1)/(myI(i, j, 3)+eps);
        gij = myI(i, j, 2)/(myI(i, j, 3)+eps);
        bij = myI(i, j, 3);
        if (rij < parm(4) && gij < parm(5) && bij > parm(6)) ...
                || (gij < parm(4) && rij < parm(5) && bij > parm(6))
            Blue_x(1,j) = Blue_x(1,j) + 1; 
            bw2(i, j) = 1;
        end
    end
end

PX1 = 1;
while (Blue_x(1,PX1)<Th) && (PX1<x)
    PX1 = PX1 + 1;
end
PX2 = x;
while (Blue_x(1,PX2)<Th) && (PX2>PX1)
    PX2 = PX2 - 1;
end
PX1 = PX1 - 2;
PX2 = PX2 + 2;
if PX1 < 1
    PX1 = 1;
end
if PX2 > x
    PX2 = x;
end

IX = I(:, PX1:PX2, :);
Plate = I(PY1:PY2, PX1:PX2, :);
Loc.row = [PY1 PY2];
Loc.col = [PX1 PX2];
bw = bw1 + bw2;
bw = logical(bw);
bw(1:PY1, :) = 0;
bw(PY2:end, :) = 0;
bw(:, 1:PX1) = 0;
bw(:, PX2:end) = 0;
if flag
    figure;       
    subplot(2, 2, 3); imshow(IY); title('行过滤结果', 'FontWeight', 'Bold');
    subplot(2, 2, 1); imshow(IX); title('列过滤结果', 'FontWeight', 'Bold');
    subplot(2, 2, 2); imshow(I); title('原图像', 'FontWeight', 'Bold');
    subplot(2, 2, 4); imshow(Plate); title('分割结果', 'FontWeight', 'Bold');
end

这里写图片描述

但是下面这个方法,如果背景有蓝色,还有白色的字,你看。

这里写图片描述

用Hough的结果
这里写图片描述

写到这,测试了第二张图,发现根本找不到边缘,改用canny算子来进行边缘检测。

f = imread('车牌2.jpg');
g = rgb2gray(f);
g = adapthisteq(g);
g = imfilter(g, fspecial('gaussian', [5 5], 0.2));
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
subplot(1, 2, 1), imshow(g);
subplot(1, 2, 2), imshow(h);

这里写图片描述

但是可以看到,这边的线不是直线,我需要将它变成直线。

f = imread('车牌2.jpg');
g = rgb2gray(f);
g = adapthisteq(g);
g = imfilter(g, fspecial('gaussian', [5 5], 0.2));
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
subplot(1, 2, 1), imshow(h);
h = bwmorph(h, 'dilate', 1);
subplot(1, 2, 2), imshow(h);

这里写图片描述

试了好多方法,还是不行,无法正确的找到直线,等明天再写。


你听说了么,传说中的人形大宝宝又来了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值