Matlab车牌车牌圆点字符分割不准确割

wintone:车牌识别系统的字符分割和识别技术
前面已经详细介绍过车牌识别的采集、预处理、定位等环节,今天来详细解读下分割和识别环节。
1、字符分割
经过前面定位出车牌区域后,由于并不知道车牌中总共有几个字符、字符间的位置关系、每个字符的宽高等信息,所以,为了保证车牌类型匹配和字符识别正确,字符分割是必不可少的一步。字符分割的主要思路是,基于车牌的二值化结果或边缘提取结果,利用字符的结构特征、字符间的相似性、字符间间隔等信息,一方面把单个字符分别提取出来,也包括粘连和断裂字符等特殊情况的处理;另一方面把宽、高相似的字符归为一类从而去除车牌边框以及一些小的噪声。一般采用的算法有:连通域分析、投影分析,字符聚类和模板匹配等。污损车牌和光照不均造成的模糊车牌仍是字符分割算法所面对的挑战,有待更好的算法出现并解决以上问题。
2.字符识别
对分割后的字符的灰度图像进行归一化处理,特征提取,然后经过机器学习或与字符数据库模板进行匹配,最后选取匹配度最高的结果作为识别结果。目前比较流行的字符识别算法有:模板匹配法、人工神经网络法、支持向量机法和Adaboost分类法等。模板匹配法的优点是识别速度快、方法简单,缺点是对断裂、污损等情况的处理有一些困难;人工神经网络法学习能力强、适应性强、分类能力强但比较耗时;支持向量机法对于未见过的测试样本具有更好的识别能力且需要较少的训练样本;Adaboost分类法能侧重于比较重要的训练数据,识别速度快、实时性较高。我国车牌由汉字、英文字母和阿拉伯数字3种字符组成,且具有统一的样式,这也是识别过程的方便之处。但由于车牌很容易受外在环境的影响,出现模糊、断裂、污损字符的情况,如何提高这类字符和易混淆字符的识别率,也是字符识别的难点之一。易混淆字符包括:0与D、0与Q、2与Z、8与B、5与S、6与G、4与A等。
车牌识别技术已经相对成熟,随处可见:小区出入口、停车场出入口、4s店等等。
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
文通快号通车牌识别系统
文通快证通证件识别系统
今日搜狐热点& & &接着上面的工作,接下去就该是进行字符分割了。考虑到为了后面的字符识别,因此在这部分需要实现的目标是需要把车牌的边框全部切除,对重新定位的车牌进行垂直方向水平方向调整,保证字符是正的。最后才是字符的分割。
& & &1.首先上下边框切割。对定位的车牌每行作一次的差分,计算每行的综合,小于某个阈值时候将其舍去。部分代码:
[length height]=size(p);
% 水平方向定位
for i=1:length % 水平一阶差分
for j=1:height-1
revise_row(i,j)=abs(p(i,j)-p(i,j+1));
revise_row(i,height)=revise_row(i,height-1);
for i=1:length
T(i)=sum(revise_row(i,:));
for i=2:length-1
T(i)=1/2*(T(i-1)+T(i)+T(i+1));
T(1)= T(2); T(length)=T(length-1);
% 截取水平区间
left_row=0;right_row=0;
threshold_row=max(T);
for i=1:length
if(T(i)&1/6*threshold_row)
left_row=i;
for i=length:-1:1
if(T(i)&1/6*threshold_row)
right_row=i;
for i=left_row:right_row %截取区间
p_row(temp,:)=p1(i,:);
temp=temp+1;
& 左右切割结果图:
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&
2 &左右边框切割。对定位的车牌每列作一次的差分。考虑到左右边框的一阶总数是两边大,中间小,因此采用获取左右的峰值,当小于峰值的摸个阈值时进行截取。 &部分代码:
% 竖直方向定位
for j=1:height % 一阶差分
for i=1:length-1
revise_column(i,j)=abs(p1(i,j)-p1(i+1,j));
revise_column(length,j)=0;
for j=1:height
T(j)=sum(revise_column(:,j));
for j=2:height-1
T(j)=1/3*(T(j-1)+T(j)+T(j+1));
T(1)= T(2);
T(height)=T(height-1);
[max_peak max_num]=max(T);%求出峰值
threshold=0.25*max_%阈值
left_peak= T(1);
right_peak= T(height);
%找到左峰值
for j=2:height
if(T(j)&=threshold&(T(j)&=T(j-1))&(T(j)&=T(j+1))&(j&=max_num))
left_peak=j;
%找到右峰值
if(max_num&1/2*height)
threshold=1/2*
for j=height-1:-1:2
if(T(j)&=threshold&(T(j)&=T(j-1))&(T(j)&=T(j+1))&(j&=max_num))
right_peak=j;
left_valley=1;%谷底值
right_valley=right_
%找出左边最小值
for j=left_peak:-1:2
if((T(j)&=T(j-1))&(T(j)&=T(j+1)))
left_valley=j;
for j=right_peak:height-1
if((T(j)&=T(j-1))&(T(j)&=T(j+1)))
right_valley=j;
for j=left_valley:right_valley
%截取部分参数分开,否则仍然按照原图大小
p_array(:,temp)=p_row(:,j);
temp=temp+1;
& & &截取图: & & & & & & & & & & & & & & & & & & & &
3 接下来进行车牌的水平校正。matlab里面有现成的函数imrotate,在-20~20角度范围对车牌进行操作,完成水平校正。代码
max_total=0;
sum_abs_angle=zeros(1,41);
angle=-20:0.1:20%旋转角度选择
p_array_temp=edge(p_array,'sobel','horizontal');%水平边缘检测
picbw_temp = imrotate(p_array,angle, 'bicubic','loose');%p_array对灰度图像进行判断操作
sum_xz=sum(picbw_temp'); %计算垂直投影
[sum_hight sum_width]=size(sum_xz);
figure,bar(sum_xz);title('垂直投影(含边框)');%输出垂直投影
% title(['车牌旋转角: ',num2str(angle),'度后图像'] ,'Color','r');%显示车牌的旋转角度
total_xz=0;
for i=1:sum_width-1
total_xz=total_xz+abs(sum_xz(i)-sum_xz(i+1));
if total_xz&max_total %找出一阶导最大值
angle_xz=%调整角度
picbw_xz=picbw_
max_total=total_
sum_abs_angle(count)=total_
count=count+1;
figure,bar(sum_abs_angle);title('每个角度绝对值总和');%输出垂直投影
image_correct=imrotate(p_array,angle_xz,'bicubic','loose');%车牌的水平旋转校正
figure,imshow(mat2gray(image_correct));
title(['车牌旋转角: ',num2str(angle_xz),'度后图像'] ,'Color','r');%显示车牌的旋转角度
& 水平矫正结果: & & & & & & & & & & &&
& & 4 &水平矫正后,我们还需要对车牌上下边框再次进行切割,去除车牌上下边框。与前面直接做一阶差分不同,这里考虑到上下边框水平成分较明显,所以我们在这里先对车牌进行竖直方向的边沿检测,然后计算水平方向的均值进行切割。 部分代码:
%去除上下边框
max_num=max(max(image_correct));
min_num=min(min(image_correct));
thresh=(max_num-min_num)/5;%15
image_correct_row=edge(image_correct,'sobel',thresh,'vertical');%根据所指定的敏感度阈值thresh,在所指定的方向direction上,
% figure,imshow(image_correct_row);
title('竖直边缘检测');%显示车牌的旋转角度
histrow=sum(image_correct_row');
%计算水平投影
histrow_mean=mean(histrow);
histcol=sum(image_correct_row);
%计算竖直投影
histcol_mean=mean(histcol);
[width hight]=size(image_correct_row);
for i=1:width/2
if histrow(i)&=1/3*histrow_mean & histrow(i+1)&1/2*histrow_mean & histrow(i+2)&1/2*histrow_mean & histrow(i+3)&1/2*histrow_mean
%连续有值判断为上边界
rowtop=i; %上边切割
for i=width:-1:width/2
if histrow(i)&=1/4*histrow_mean & histrow(i-1)&histrow_mean & histrow(i-2)&histrow_mean
& histrow(i-3)&histrow_mean & histrow(i-4)&histrow_mean
rowbot=i; %下边切割
& & 结果图:
& & & & & & & & & & & & & & & &
& 可以看到,上下边框基本清除,下面就需要对字符进行垂直校正。
& & 5 & 关于字符垂直校正,这个部分自己也没太明白,只是参考别人的程序,可以交流。代码:
max_total=0;
angle_yz=0;
sum_abs_angle=zeros(1,41);
angle=-10:0.05:10%旋转角度选择
picbw_temp = imrotate(image_correct_x,angle, 'bicubic','crop');%p_array对灰度图像进行判断操作
sum_yz=sum(picbw_temp); %计算垂直投影
[sum_hight sum_width]=size(sum_yz);
total_yz=0;
for i=1:sum_width-1
total_yz=total_yz+abs(sum_yz(i)-sum_yz(i+1));
if total_yz&max_total %找出一阶导最大值
picbw_yz=picbw_
max_total=total_
sum_abs_angle(count)=total_
count=count+1;
Td=maketform('affine',[1 tand(angle_yz) 0;0 1 0;0 0 1]');%切变的参数结构体
image_correct_x_y=imtransform(image_correct_x,Td,'FillValues',255);%实现图像切变
实验结果: & & &
& 6 这样基本要做的都已经完成,剩下字符切割。在测试过程中,发现车牌的上下边框边角好去除,左右边框则无法达到理想的要求,经常是要么没有切割完全,要把把车牌字符也切割了。最后索性就不管左右边框了,直接进行字符分割。自己所用的方法是:设置字符宽为width=1/2*车牌的高度;考虑到车牌的第二位和第三位之间有小点(也可能没有),中间距离更大,所以认为车牌宽度的一半既是第四个字符所在位置或者是第三和第四字符之间,这里最主要是要确定某个参数,来标定车牌位置,便于分割。(实验证明还是有效的)当遇到字符宽度大于默认width时,取大的值。车牌左右第一个和第七个字符则是截取默认宽度,去除边框影响。部分代码:
& 获取第四个字符:
[image_heigth image_length]=size(image_correct_x_y);
character_left=0;%切割字符左右位置
character_right=0;
middle_histcol=uint8(image_length/2);
char_width=image_heigth/2;%默认字符宽度
if binary_histcol(middle_histcol)&0 %垂直投影不为零
%找出车牌的第四个字符
for i=middle_histcol:-1:1 %字符左侧
if binary_histcol(i)==0
character_left=i+1;
for i=middle_histcol:image_length%字符右侧
if binary_histcol(i)==0
character_right=i-1;
result_char_forth(:,:)=binary_image(:,character_left:character_right);
else %认为中间值在 第三、四个字符之间
for i=middle_histcol:image_length%获取第四个字符
if binary_histcol(i)&0 & binary_histcol(i-1)==0 %字符左起点
character_left=i;
if binary_histcol(i)&0 & binary_histcol(i+1)==0 %字符右边界
character_right=i;
result_char_forth(:,:)=binary_image(:,character_left:character_right); %获取字符
if character_right-character_left+1&char_width %比默认字符大
char_width=character_right-character_left+1;%默认字符用于确认车牌左右两侧的宽度
& & 判断中间有无小点:
%判断有无中间小点!!!!! width_dot=4
width_dot=4;%只能是字母,认为宽度小于4即为点,否则认为没有点
for i=current_left_position-1:-1:2
if binary_histcol(i)&0 & binary_histcol(i+1)==0 %字符右起点
character_right_temp=i;
if binary_histcol(i)&0 & binary_histcol(i-1)==0 %字符左边界
character_left_temp=i;
if((character_right_temp-character_left_temp)&width_dot)%不是点
current_left_position=character_%记录当前位置放到下面读取
else %是点
current_left_position=character_left_%记录当前位置
& 切割结果:
& & 可以看到,基本上消除了左右边框的影响。七个工作基本完成!欢迎交流!
阅读(...) 评论()分享:matlab实现车牌字符分割与识别
我喜欢的智慧石资源:
没有更多推荐了, 上传我的文档
 上传文档
 下载
 收藏
粉丝量:234
该文档贡献者很忙,什么也没留下。
 下载此文档
MATLAB在车牌字符分割中的应用
下载积分:1500
内容提示:MATLAB在车牌字符分割中的应用
文档格式:PDF|
浏览次数:6|
上传日期: 20:35:37|
文档星级:
全文阅读已结束,如果下载本文需要使用
 1500 积分
下载此文档
该用户还上传了这些文档
MATLAB在车牌字符分割中的应用
关注微信公众号matlab车牌分割后的字符如何提取? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。1被浏览331分享邀请回答暂时还没有回答,开始写第一个回答}

我要回帖

更多关于 车牌字符分割垂直投影法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信