如何用matlab提取和识别车牌数?

时间:2013-08-01 07:37:42

标签: matlab image-processing ocr

我想开发一个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

2 个答案:

答案 0 :(得分:4)

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

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'。经过广泛的测试,我们的应用似乎是最好的。然后确定车牌区域我们做了水平和垂直边缘处理。首先,通过遍历图像的每一列来计算水平直方图。该算法开始遍历来自图像矩阵的每列顶部的第二像素。计算第二和第一像素之间的差异。如果差异超过某个阈值,则将其添加到差异的总和。它遍历到列的末尾,并计算相邻像素之间的差异总和。最后,创建列式和的矩阵。对垂直直方图执行相同的过程。在这种情况下,处理行而不是列。

Horizontal and Vertical Histogram

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

Number Plate Extraction

对于识别使用模板匹配相关(在matlab中使用corr2())

答案 1 :(得分: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

这是边缘检测后的图像:

edges

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

extracted