【问题标题】:How to extract licence plate from black and white picture如何从黑白图片中提取车牌
【发布时间】:2015-02-09 21:53:57
【问题描述】:

我得到了这个作业,我必须从汽车图片中提取车牌。我不必识别车牌号和字母(这是同事的工作)。我必须在 Matlab 中完成。我已经做了车牌识别部分,但是现在我不明白如何从图片中正确提取车牌部分。

您可以在下图中看到我到目前为止所做的事情:

现在我不知道如何裁剪白色部分,而且应该是这样的:

我的意思是它应该被旋转到水平位置。

这是一个需要两个人完成的项目。第一个(我)必须从任何类型的图像中只给第二个车牌,第二个必须使用 OCR。这是教授问的。

我没有想法。答案可能很简单,但我工作了一天,也没有找到解决办法。

【问题讨论】:

  • 我已经解决了!我不敢相信它是多么简单。黑白图像是一个矩阵,其中黑色为 0,白色为 1。所以解决方案只是一些 0 和 1 搜索。我保证会在所有代码都完成并清理后在此处发布完整代码:)
  • 所以,呃,我猜代码还不干净? :)
  • :)) 为 "erm" 。是的,我明天必须提交它,所以从那天起我就没有工作过。我发布了代码,比那天干净了很多,但它仍然需要工作:)

标签: matlab image-processing


【解决方案1】:

注意:变量使用不同的语言,但我相信代码是可读的。很抱歉,但我现在没有时间处理它:(

现在这个算法不是最好的,而是一个起点。我现在没有时间研究它,但它肯定可以改进。例如,从底部的图像中可以看出,车牌位置填充得非常好,但在某些图片中,最后一行白色像素的长度与上面的不一样,所以你可以结束只有一半的车牌。一种解决方案可以是:在拿到车牌的角之前使所有白线的长度相同(最长线的长度)

BW = edge(rgb2gray(imagine), 'canny');

    %# hough transform
    [H T R] = hough(BW);
    P  = houghpeaks(H, 4, 'threshold',ceil(0.75*max(H(:))));
    lines = houghlines(BW, T, R, P);

    % shearing transformata
    slopes = vertcat(lines.point2) - vertcat(lines.point1);
    slopes = slopes(:,2) ./ slopes(:,1);
    TFORM = maketform('affine', [1 -slopes(1) 0 ; 0 1 0 ; 0 0 1]);
    imagine2 = imtransform(imagine, TFORM);

    %# show image with lines overlayed, and the aligned/rotated image
    axes(handles.ImagineRotita)
    imshow(imagine2); 

    imagineGrey = rgb2gray(imagine2);

%-----------------------------------------------------------------

    axes(handles.ImaginePrel1)
    imshow(imagineGrey);

    imagineFiltrata = medfilt2(imagineGrey,[3 3]);
    axes(handles.ImagineFilt)
    imshow(imagineFiltrata);

    SE = strel('disk',1);
    GrayDil = imdilate(imagineGrey,SE);
    GrayEr = imerode(imagineGrey,SE);
    gdiff = imsubtract(GrayDil,GrayEr);
    gdiff = mat2gray(gdiff);
    gdiff = conv2(gdiff,[1 1;1 1]);
    gdiff = imadjust(gdiff,[0.5 0.7],[0 1],0.1);

    B = logical(gdiff);
    er = imerode(B,strel('line',50,0));
    out1 = imsubtract(B,er);

    imagineSobel = imfill(out1,'holes');

    H = bwmorph(imagineSobel,'thin',1);
    H = imerode(H,strel('line',3,90));

    final = bwareaopen(H,100);

    Iprops = regionprops(final,'BoundingBox','Image');

    axes(handles.ImagineSobel)
    imshow(final);

    imagineCuratata = imclearborder(final,18);
    imagineCuratata = bwareaopen(imagineCuratata,200);
    axes(handles.ImagineSobelEd)
    imshow(imagineCuratata);

    fileID = fopen('ImagineRezultata.txt','wb');
    dlmwrite('ImagineRezultata.txt',imagineCuratata);
    fclose('all');

    imagineCuratata2 = imagineCuratata;

    [dimX,dimY] = size(imagineCuratata2);

%-----------------------------------------------------------------
%-----------The licence plate is filled with white pixels---------
PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;

for i = 1:dimX
    for j = 1:dimY
        if Flag == 0
            if imagineCuratata2(i,j) == 1
                PrimPixelAlbStanga = j;
                Flag = 1;
            end
        end
        if Flag == 1
            if imagineCuratata2(i,j) == 1
                PrimPixelAlbDreapta = j;
            end
        end
    end
    if PrimPixelAlbStanga > 0
        for k = PrimPixelAlbStanga:PrimPixelAlbDreapta
            imagineCuratata2(i,k) = 1;
        end
    end
    PrimPixelAlbStanga = 0;
    PrimPixelAlbDreapta = 0;
    Flag = 0;
end

%-----------------------------------------------------------------

%-----------------------------------------------------------------
%----------The smaller lines with white pixels are removed--------
%----------this is to eliminate all the smaller lines that--------
%--------------remained for example the logo sometimes------------

PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;

for i = 1:dimX
    for j = 1:dimY
        if Flag == 0
            if imagineCuratata2(i,j) == 1
                PrimPixelAlbStanga = j;
                Flag = 1;
            end
        end
        if Flag == 1
            if imagineCuratata2(i,j) == 1
                PrimPixelAlbDreapta = j;
            end
        end
    end
    if PrimPixelAlbStanga > 0
        if (PrimPixelAlbDreapta - PrimPixelAlbStanga) < 40
            for k = PrimPixelAlbStanga:PrimPixelAlbDreapta
                imagineCuratata2(i,k) = 0;
            end
        end
    end
    PrimPixelAlbStanga = 0;
    PrimPixelAlbDreapta = 0;
    Flag = 0;
end

axes(handles.ImagineCropata)
imshow(imagineCuratata2);

%-----------------------------------------------------------------

%-----------------------------------------------------------------
%---------the corners of the licence plate are determined---------

imagineCuratata2 = bwareaopen(imagineCuratata2,500);

PrimaCoordX = 0;
PrimaCoordY = 0;
UltimaCoordX = 0;
UltimaCoordY = 0;
determinat = 0;

for i = 1:dimX
    for j = 1:dimY
        if imagineCuratata2(i,j) == 1
            if determinat == 0
                PrimaCoordX = j;
                PrimaCoordY = i;
                determinat = 1;
            else
                            UltimaCoordX = j;
                            UltimaCoordY = i;
            end            
        end
    end
end

PrimaCoordColX = 0;
PrimaCoordColY = 0;
UltimaCoordColX = 0;
UltimaCoordColY = 0;
determinatCol = 0;

for j = 1:dimY
    for i = 1:dimX
        if imagineCuratata2(i,j) == 1
            if determinatCol == 0
                PrimaCoordColX = j;
                PrimaCoordColY = i;
                determinatCol = 1;
            else                
                    UltimaCoordColX = j;
                    UltimaCoordColY = i;
            end            
        end
    end
end

    xmin = 0;
    ymin = 0;
    width = 0;
    height = 0;

    if PrimaCoordX < dimX/2
        xmin = PrimaCoordX;
        ymin = PrimaCoordY;
    else 
        xmin = PrimaCoordColX;
        ymin = PrimaCoordY;
    end

    xmin = xmin - xmin * 0.1;
    ymin = ymin * 1.1;

    if PrimaCoordX < dimX/2
        width = UltimaCoordX - PrimaCoordX;
        height = UltimaCoordY - PrimaCoordY;
    else
        width = UltimaCoordColX - PrimaCoordColX;
        height = UltimaCoordY - PrimaCoordY;
    end

    rect = [xmin ymin abs(width) abs(height)];

    RezultatCropat = imcrop(imagine2, rect);

    axes(handles.ImagineCropataSiFilt)
    imshow(RezultatCropat);

end

我所做的结果可以在这些图片中看到:

【讨论】:

  • 感谢分享,结果看起来很不错。我只能建议将代码分成逻辑部分,例如一个用于图像预处理的功能,另一个用于在预处理图像处搜索车牌角的功能,用于区域提取和后处理的单独方法。一般而言,这是一种很好的做法,特别是稍后,如果 OCR 失败,您可能希望重新尝试提取参数变化较小的车牌区域。
【解决方案2】:

如果您尝试对图像进行物理操作以从任意数量的有角度的原件创建最终的扁平表示,那么这可能不是继续进行的方法。

如果您已经定义了识别车牌边界的逻辑,那么您应该能够捕捉它,然后通过 OCR 应用程序运行它。这将为您提供文本,然后您可以使用该文本创建一个平面图像。

现在,如果您还必须从车牌中捕获任何图形,则需要跟踪所有可能的图形图像的数据库,然后编写比较/匹配例程,以便您可以识别车牌图形,但随后使用数据库中的“平面”版本创建平面图像,然后将 OCR 文本输出到该图像上。

例如,我只刮下了车牌,并在 images.google.com 上进行了搜索(使用他们的“按图片搜索”功能,我发现了很多 "flattened" versions of the image,您可以将其用作模板。

【讨论】:

  • 感谢您的回答。问题是我不必做 OCR 部分。我要做的是从我提供的第一个链接中的图像中获取我需要获取的图像,例如我提供的第二个链接中的图像。没有 OCR
  • 更好的说法是:如何仅提取图像的白色部分以及如何旋转它以获得与您在链接中提供的图像类似的图像?
  • 通过 OCR 是一种比尝试开发某种图像处理器更好的方法,该处理器将消除任何倾斜/基数/透视并将其转换为“可读”图像。另一方面,OCR 软件正是这样做的,但使用的是信息,而不是图像处理。
  • 是的,但问题是这是一个需要两个人完成的项目。第一个(我)必须从任何类型的图像中只给第二个车牌,第二个必须使用 OCR。这是教授问的……
  • 我将首先获取一组扁平的欧盟车牌here,使用图像编辑器去除所有实际文本然后您应该能够找到一些进行图像比较的代码,确定将哪个车牌交给 OCR 人员。
猜你喜欢
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 2011-07-13
  • 2017-08-04
  • 2010-11-02
  • 2013-11-27
相关资源
最近更新 更多