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

蓝色区域切割

继续使用上节的Pre_Process来获得蓝色区域,并对蓝色区域进行判断。
流程如下

  • 获得蓝色区域
  • 对蓝色区域进行Hough直线检测并进行校正
  • 分析蓝色区域
  • 分析失败则返回第一步,并将此蓝色区域置为0。

我们先模拟一下如果第一次获取失败,进行第二次的过程。

hsv = rgb2hsv(f);
v = hsv(:, :, 3);
v = imfilter(v, fspecial('gaussian', [5 5], 0.2));
f = hsv2rgb(cat(3, hsv(:, :, 1), hsv(:, :, 2), adapthisteq(v)));
f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
g = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
subplot(1, 2, 1), imshow(g), title('第一次分割');
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
g = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
subplot(1, 2, 2), imshow(g), title('第二次分割');

这里写图片描述

结果是可行的。

接着,我们进行校正,这里先假设第二次成功找到。

f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
g = rgb2gray(area);
g = adapthisteq(g); % 对比度增强
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
h = bwmorph(h, 'dilate', 1);
subplot(1, 2, 1), imshow(h), hold on;
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'red');
    x1 = xy(:, 1);
    y1 = xy(:, 2);
    K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
    angle = atan(K1)*180/pi;
    area = imrotate(area, 90 - angle, 'bilinear');
end
subplot(1, 2, 2), imshow(area);

这里写图片描述

接着在进行字符提取

f = imread('车牌2.jpg');
[P B L] = Pre_Process(f);
f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
[P B L] = Pre_Process(f);
area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
g = rgb2gray(area);
g = adapthisteq(g); % 对比度增强
h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
h = bwmorph(h, 'dilate', 1);
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    x1 = xy(:, 1);
    y1 = xy(:, 2);
    K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
    angle = atan(K1)*180/pi;
    area = imrotate(area, 90 - angle, 'bilinear');
end


area = rgb2gray(area);

g_max=double(max(max(area)));
g_min=double(min(min(area)));

T=round(g_max-(g_max-g_min)/3);
area = im2bw(area, T/256);
area = bwareaopen(area, 20);

[H theta rho] = hough(area);
peaks = houghpeaks(H, 1);
lines = houghlines(area, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    x1 = xy(:, 1);
    y1 = xy(:, 2);
    area(y1(1) : y1(2), x1(1):x1(2)) = 0;
end

area2 = imfill(area, 'holes'); % 先将空洞删除


X=[];
z=0;
flag=0;

for j=1:size(area ,2)
    sum_y=sum(area(:,j));
    if logical(sum_y)~=flag          %列和有变化时,记录下此列
        if(j-z > 3)
            X=[X j];
            flag=logical(sum_y);
            z=j;                        %用z记录上一个j的值,防止两个列坐标间隔太小
        end
    end
end

[y x] = size(area2);

X = [X y];

for n=1:7
    res = area(:, X(2 * n - 1):X(2 * n));     %进行粗分割
    for i=1:size(res,1)                  %这两个for循环对分割字符的上下进行裁剪
        if sum(res(i,:))~=0
            top=i;
            break
        end
    end
    for i=1:size(res,1)
        if sum(res(size(res,1)-i,:))~=0
            bottom=size(res,1)-i;
            break
        end
    end
    res=res(top:bottom,:);
    subplot(2, 4, n), imshow(res);
end

这里写图片描述

接着对字符进行分析。

获取传入的二维图的车牌信息

function rec = getCarPlate(g)
    g = adapthisteq(g); % 对比度增强
    h = edge(g,'canny', 0.25); % 使用sobel算子进行边缘检测
    h = bwmorph(h, 'dilate', 1);
    [H theta rho] = hough(h);
    peaks = houghpeaks(H, 1);
    lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
    for i = 1 : length(lines)
        xy = [lines(i).point1; lines(i).point2];
        x1 = xy(:, 1);
        y1 = xy(:, 2);
        K1 = (x1(2)-x1(1))/(y1(2)-y1(1));
        angle = atan(K1)*180/pi;
        area = imrotate(area, 90 - angle, 'bilinear');
    end


    area = rgb2gray(area);

    g_max=double(max(max(area)));
    g_min=double(min(min(area)));

    T=round(g_max-(g_max-g_min)/3);
    area = im2bw(area, T/256);
    area = bwareaopen(area, 20);

    area2 = imfill(area, 'holes'); % 先将空洞删除


    X=[];
    z=0;
    flag=0;

    for j=1:size(area ,2)
        sum_y=sum(area(:,j));
        if logical(sum_y)~=flag          %列和有变化时,记录下此列
            if(j-z > 3)
                X=[X j];
                flag=logical(sum_y);
                z=j;                        %用z记录上一个j的值,防止两个列坐标间隔太小
            end
        end
    end

    [y x] = size(area2);

    X = [X y];

    for n=1:7
        res = area(:, X(2 * n - 1):X(2 * n));     %进行粗分割
        for i=1:size(res,1)                  %这两个for循环对分割字符的上下进行裁剪
            if sum(res(i,:))~=0
                top=i;
                break
            end
        end
        for i=1:size(res,1)
            if sum(res(size(res,1)-i,:))~=0
                bottom=size(res,1)-i;
                break
            end
        end
        res=res(top:bottom,:);
        res = imresize(res,[40,20],'nearest');    %归一化为40*20的大小,以便模板匹配
        imgchar{n}=res;
    end

    res=[];
    store1=strcat('贵','豫','粤','湘','鄂','皖','鲁','藏','京','苏','黑','吉','冀','晋','辽','浙','津','闽','云','陕','琼');  %创建汉字识别模板库
    for j=1:21
        Im=imgchar{1};
        Template=imread(strcat('车牌汉字库\',num2str(j),'.jpg'));
        Template=im2bw(Template);
        Differ=Im-Template;
        Compare(j)=sum(sum(abs(Differ)));
    end
    index=find(Compare==(min(Compare)));
    res=[res store1(index)];
    store2=strcat('A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9'); %创建字母与数字识别模板库
    for i=2:7
        for j=1:34
            Im=imgchar{i};
            Template=imread(strcat('车牌字符库\',num2str(j),'.jpg'));
            Template=im2bw(Template);
            Differ=Im-Template;
            Compare(j)=sum(sum(abs(Differ)));
        end
        index=find(Compare==(min(Compare)));
        res=[res store2(index)];
    end
end

主函数

clear;
clear all;
f = imread('车牌.jpg');
real = f;
n = 1;
while n < 5
    [P B L] = Pre_Process(f);
    area = f(L.row(1):L.row(2), L.col(1):L.col(2), :);
    try
        res = getCarPlate(area);
        n = 999;
    catch err
        disp(err);
        disp('截取失败,进行下一次截取');
        f(L.row(1):L.row(2), L.col(1):L.col(2), :) = 0;
        figure, imshow(f);
        n = n + 1;
    end
end
imshow(real), title(res);

这里写图片描述

我们还需要去除一些因为反光而白色的线。

h = imread('车牌8.jpg');
subplot(1, 2, 1), imshow(h), hold on;
[H theta rho] = hough(h);
peaks = houghpeaks(H, 1);
lines = houghlines(h, theta , rho, peaks, 'FillGap', 25, 'MinLength', 25);
for i = 1 : length(lines)
    xy = [lines(i).point1; lines(i).point2];
    plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'red');
    x1 = xy(:, 1);
    y1 = xy(:, 2);
    h(y1(1) : y1(2), x1(1):x1(2)) = 0;
end
subplot(1, 2, 2), imshow(h);

这里写图片描述

接着再按照上面的过程执行即可。


传说中的人形大宝宝今天来看我打码了- -

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值