【问题标题】:How to extract and recognize the vehicle plate number with matlab?matlab如何提取和识别车牌号?
【发布时间】:2013-08-02 00:15:24
【问题描述】:

我想开发一个matlab程序,可以用模板匹配的方法提取和识别车辆的车牌号。 这是我的代码:

function letters = PengenalanPlatMobil(citra)
%load NewTemplates
%global NewTemplates
citra=imresize(citra,[400 NaN]); % Resizing the image keeping aspect ratio same.
citra_bw=rgb2gray(citra); % Converting the RGB (color) image to gray (intensity).
citra_filt=medfilt2(citra_bw,[3 3]); % Median filtering to remove noise.
se=strel('disk',1);
citra_dilasi=imdilate(citra_filt,se); % Dilating the gray image with the structural element.
citra_eroding=imerode(citra_filt,se); % Eroding the gray image with structural element.
citra_edge_enhacement=imsubtract(citra_dilasi,citra_eroding); % Morphological Gradient for edges enhancement.
imshow(citra_edge_enhacement);
citra_edge_enhacement_double=mat2gray(double(citra_edge_enhacement)); % Converting the class to double.
citra_double_konv=conv2(citra_edge_enhacement_double,[1 1;1 1]); % Convolution of the double image f
citra_intens=imadjust(citra_double_konv,[0.5 0.7],[0 1],0.1); % Intensity scaling between the range 0 to 1.
citra_logic=logical(citra_intens); % Conversion of the class from double to binary.
% Eliminating the possible horizontal lines from the output image of regiongrow
% that could be edges of license plate.
citra_line_delete=imsubtract(citra_logic, (imerode(citra_logic,strel('line',50,0))));
% Filling all the regions of the image.
citra_fill=imfill(citra_line_delete,'holes');
% Thinning the image to ensure character isolation.
citra_thinning_eroding=imerode((bwmorph(citra_fill,'thin',1)),(strel('line',3,90)));

%Selecting all the regions that are of pixel area more than 100.
citra_final=bwareaopen(citra_thinning_eroding,125);
[labelled jml] = bwlabel(citra_final);
% Uncomment to make compitable with the previous versions of MATLAB®
% Two properties 'BoundingBox' and binary 'Image' corresponding to these
% Bounding boxes are acquired.
Iprops=regionprops(labelled,'BoundingBox','Image');

%%% OCR STEP
[letter{1:jml}]=deal([]);
[gambar{1:jml}]=deal([]);
for ii=1:jml
    gambar= Iprops(ii).Image;
    letter{ii}=readLetter(gambar);
    % imshow(gambar);
    %
end

end

但识别出的数字总是错误的,检测到的数字太多或有时太少。 如何解决?

这里是imagesthis one

【问题讨论】:

  • 这是stackoverflow.com/questions/17926768/… 的重复,尽管您在我对您上一篇文章的回答中提出了建议的更改。我的建议是首先将车牌与图像的其余部分隔离开,然后应用您的代码。
  • @Try Hard:我已经制作了隔离板并执行相同的代码,但是分割结果是错误的..如何修复它..任何建议
  • 在什么意义上是错误的?它对我来说表现非常好!
  • 中提取的字符量。

标签: matlab image-processing ocr


【解决方案1】:

对于车牌提取,你必须遵循这个算法(我在我的项目中使用了这个)

1. Find Histogram variation horizontally(by using imhist)
2. Find the part of histogram where you get maximum variation and get x1 and x2 value.
3. crop that image horizontally by using value of x1 and x2.
4. Repeat same process for vertical cropping.

解释:

为了从图像中删除不必要的信息,它只需要图像的边缘即可工作。为了检测边缘,我们使用了内置的 MATLAB 函数。 但首先我们将原始图像转换为灰度图像

通过确定图像中不同强度的阈值,将此灰度图像转换为二值图像。仅在二值化之后,可以使用边缘检测算法。在这里,我们使用了“ROBERTS”。经过广泛的测试,我们的应用程序似乎是最好的。然后为了确定车牌的区域,我们做了水平和垂直边缘处理。首先,通过遍历图像的每一列来计算水平直方图。该算法从图像矩阵每列顶部的第二个像素开始遍历。计算第二个和第一个像素之间的差异。如果差异超过某个阈值,则将其添加到差异总和中。它遍历到列的末尾,并计算相邻像素之间的差异总和。最后,创建了一个按列求和的矩阵。对垂直直方图执行相同的处理。在这种情况下,将处理行而不是列。

在计算水平和垂直直方图后,我们计算了一个阈值,它是最大水平直方图值的 0.434 倍。我们提取的下一步是裁剪感兴趣的区域,即车牌区域。对于裁剪,我们首先水平裁剪原始图像,然后垂直裁剪。在水平裁剪中,我们逐列处理图像矩阵并将其水平直方图值与预定义的阈值进行比较。如果水平直方图中的某个值大于阈值,我们将其标记为裁剪的起点并继续直到我们找到阈值 - 小于该阈值是我们的终点。在这个过程中,我们得到许多值超过阈值的区域,因此我们将所有起点和终点存储在一个矩阵中并比较每个区域的宽度,宽度是计算起点和终点的差。之后,我们找到一组映射最大宽度的起始点和结束点。然后我们使用该起点和终点水平裁剪图像。这个新的水平裁剪图像被处理为垂直裁剪。在垂直裁剪中,我们使用相同的阈值比较方法,但唯一的区别是这次我们逐行处理图像矩阵并将阈值与垂直直方图值进行比较。我们再次获得不同的垂直起点和终点集,我们通过使用垂直起点和终点找到映射最大高度和裁剪图像的集。经过垂直和水平裁剪后,我们可以从 RGB 格式的原始图像中得到准确的车牌区域。

为了识别,使用具有相关性的模板匹配(在 matlab 中使用 corr2())

【讨论】:

  • 很好,你有没有在 mathworks 或 github 上分享过你的代码?
【解决方案2】:

我会将字符检测后的循环更改为

[gambar{1:jml}]=deal([]);

for ii=1:jml
    gambar{ii}= Iprops(ii).Image;
    %letter{ii}=readLetter(gambar);
    imshow(gambar{ii});
end

我认为你现在想要做的是

(1)在应用字符提取和ocr之前提前选择roi。

(2) 对整个图像中的所有字符应用ocr,然后使用邻近规则或其他规则来识别车牌号。

编辑:

如果您在字符提取后运行以下循环,您就会明白我所说的“接近度”是什么意思:

[xn yn]=size(citra); % <-- citra is the original image matrix
figure, hold on 
[gambar{1:jml}]=deal([]);
for ii=1:jml
    gambar{ii}= double(Iprops(ii).Image)*255;
    bb=Iprops(ii).BoundingBox;
    image([bb(1) bb(1)+bb(3)],[yn-bb(2) yn-bb(2)-bb(4)],gambar{ii});
end

这是边缘检测后的图像:

在字符提取之后(运行上面的循环之后):

【讨论】:

  • 什么是“yn”变量?
  • 我错过了:它是图像 y 维度的大小。
  • 从字符提取中,我们如何将其与模板匹配并知道字符的确切值?因为提取的字符形状太粗了。
  • 你的意思是 ocr 对某些字符不起作用是因为它们太厚了吗?我会调查它,但我建议你发布另一个问题专门询问这个问题。最好发布从车牌中提取的字符之一,并解释为什么您尝试对其执行 ocr 不起作用。
  • 顺便问一下,你的意思是一个特定的字符太粗了吗?例如我可以看到 B 太粗了,但是“4”和“J”字符看起来还可以。
猜你喜欢
  • 2019-06-22
  • 1970-01-01
  • 2014-11-04
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2013-10-16
  • 2016-07-24
相关资源
最近更新 更多