最简单的MATLAB车牌字符分割(附源码)

Binary_GrayScale_Smooth_image (bgs_img)

Binary_GrayScale_Smooth_image (bgs_img)

分析图

叠加sum曲线后的分析图

-

-

-

-

-

-

-

上方左图是二值、灰度化并平滑后的结果,效果还是不错的。

我们分别对二值化结果分别做一个行、列的求和统计,并叠加得出上方右图的结果:

红色代表对各行数值求和结果、蓝色代表对各列求和结。大家已经可以看出些什么名堂来了吧?当值高的时候,代表白色的像素(‘痕迹’)在这里多。

通过红色曲线,我们已经可以轻易地去掉上下区域的直线。

对于水平切割,这里采用了最落后的阀值法,对水平总和数据求数学平均,然后低于数学平均值的那一整行像素将被删除。

而对于蓝色曲线,不能盲目地copy水平切割的方法。仔细观察‘M’、‘0’这两字母与其他字母的曲线。经比较后不难发现,因为M与0这两个字母中间是空心的,所以曲线波动较大。真正应该分割点的是最低的波谷处。

以下是代码摘要:

seg_target=sum_cols <= (sum(sum_cols)/length(sum_cols));
for i=1:length(seg_target)
    if ~seg_target(i)
        preseg_bgs_img = [preseg_bgs_img;bgs_img(i,:)];
    end
end

seg_target = sum_rows <= (floor(min(sum_rows)/10)+1)*10;
nb_char = 0;
seg_flag = 0;
temp_char = zeros(size(preseg_bgs_img,1),1);

for i=1:length(seg_target)
    if ~seg_target(i)
        seg_flag = 1;
        temp_char = [temp_char,preseg_bgs_img(:,i)];
    end

    if seg_target(i) && seg_flag==1
        seg_flag = 0;
        if size(temp_char) > 10
            nb_char = nb_char + 1;
            seg_char{nb_char} = temp_char;
        end
        temp_char = zeros(size(preseg_bgs_img,1),1);
    end

end

以下是水平分割结果(预分割):

水平分割结果

水平分割结果

-

-

-

-

可以看出顶上的螺丝钉与下面的边沿被咔嚓掉了,很好。

接着,我们做最后的分割,在这里我偷了懒,有些时候我们会连垂直方向上的一些边都当成了字符,其实一个很简单的解决方法就是设定一个阀值让体积比较正常的字符通过,过滤掉类似边沿的假结果。其实不应该设定一个固定阈值,而是根据不同图片计算出不同的阀值。

以下是最终的结果:

最终分割结果

最终分割结果

-

-

-

-

-

效果还不错的厄,不作可视化过程显示的话用时0.02秒,就是通用性差,用其他质量没有这么好、分辨率没这么高的车牌做分割惨不忍睹。

下一页将谈到改进的思路以及放出源码下载。

Pages: 1 2 3

8 comments to 最简单的MATLAB车牌字符分割(附源码)

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>