基于matlab的蓝色车牌定位与识别---分割
接着上面的工作,接下去就该是进行字符分割了。考虑到为了后面的字符识别,因此在这部分需要实现的目标是需要把车牌的边框全部切除,对重新定位的车牌进行垂直方向水平方向调整,保证字符是正的。最后才是字符的分割。
1.首先上下边框切割。对定位的车牌每行作一次的差分,计算每行的综合,小于某个阈值时候将其舍去。部分代码:
[length height]=size(p);
% 水平方向定位
for i=:length % 水平一阶差分
for j=:height-
revise_row(i,j)=abs(p(i,j)-p(i,j+));
end
revise_row(i,height)=revise_row(i,height-);
end
for i=:length
T(i)=sum(revise_row(i,:));
end
for i=:length-
T(i)=/*(T(i-)+T(i)+T(i+));
end
T(1)= T(2);
T(length)=T(length-1);
% 截取水平区间
left_row=;right_row=;
threshold_row=max(T);
for i=:length
if(T(i)>/*threshold_row)
left_row=i;
break;
end
end
for i=length:-:
if(T(i)>/*threshold_row)
right_row=i;
break;
end
end
temp=;
for i=left_row:right_row %截取区间
p_row(temp,:)=p1(i,:);
temp=temp+;
end
左右切割结果图:
2 左右边框切割。对定位的车牌每列作一次的差分。考虑到左右边框的一阶总数是两边大,中间小,因此采用获取左右的峰值,当小于峰值的摸个阈值时进行截取。 部分代码:
% 竖直方向定位
for j=:height % 一阶差分
for i=:length-
revise_column(i,j)=abs(p1(i,j)-p1(i+,j));
end
revise_column(length,j)=;
end for j=:height
T(j)=sum(revise_column(:,j));
end
for j=:height-
T(j)=/*(T(j-)+T(j)+T(j+));
end
T()= T();
T(height)=T(height-);
[max_peak max_num]=max(T);%求出峰值
threshold=0.25*max_peak;%阈值
left_peak= T();
right_peak= T(height); %找到左峰值
for j=:height
if(T(j)>=threshold&(T(j)>=T(j-))&(T(j)>=T(j+))&(j<=max_num))
left_peak=j;
break;
end
end
%找到右峰值
if(max_num</*height)
threshold=/*threshold;
end
for j=height-:-:
if(T(j)>=threshold&(T(j)>=T(j-))&(T(j)>=T(j+))&(j>=max_num))
right_peak=j;
break;
end
end
left_valley=;%谷底值
right_valley=right_peak;
%找出左边最小值
for j=left_peak:-:
if((T(j)<=T(j-))&(T(j)<=T(j+)))
left_valley=j;
break;
end
end
for j=right_peak:height-
if((T(j)<=T(j-))&(T(j)<=T(j+)))
right_valley=j;
break;
end
end
temp=;
for j=left_valley:right_valley %截取部分参数分开,否则仍然按照原图大小
p_array(:,temp)=p_row(:,j);
temp=temp+;
end
截取图:
3 接下来进行车牌的水平校正。matlab里面有现成的函数imrotate,在-20~20角度范围对车牌进行操作,完成水平校正。代码
%水平校正
max_total=;
sum_abs_angle=zeros(,);
count=;
for angle=-:0.1:%旋转角度选择
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=;
for i=:sum_width-
total_xz=total_xz+abs(sum_xz(i)-sum_xz(i+));
end
if total_xz>max_total %找出一阶导最大值
angle_xz=angle;%调整角度
picbw_xz=picbw_temp;
max_total=total_xz;
end
sum_abs_angle(count)=total_xz;
count=count+;
end
% 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)/;%
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);
rowtop=;
for i=:width/
if histrow(i)>=/*histrow_mean & histrow(i+)>/*histrow_mean & histrow(i+)>/*histrow_mean & histrow(i+)>/*histrow_mean %连续有值判断为上边界
rowtop=i; %上边切割
break;
end
end
rowbot=;
for i=width:-:width/
if histrow(i)>=/*histrow_mean & histrow(i-)>histrow_mean & histrow(i-)>histrow_mean & histrow(i-)>histrow_mean & histrow(i-)>histrow_mean
rowbot=i; %下边切割
break;
end
end
结果图:
可以看到,上下边框基本清除,下面就需要对字符进行垂直校正。
5 关于字符垂直校正,这个部分自己也没太明白,只是参考别人的程序,可以交流。代码:
max_total=;
angle_yz=;
sum_abs_angle=zeros(,);
count=;
for angle=-:0.05:%旋转角度选择
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=;
for i=:sum_width-
total_yz=total_yz+abs(sum_yz(i)-sum_yz(i+));
end
if total_yz>max_total %找出一阶导最大值
angle_yz=angle;
picbw_yz=picbw_temp;
max_total=total_yz;
end
sum_abs_angle(count)=total_yz;
count=count+;
end
Td=maketform('affine',[ tand(angle_yz) ; ; ]');%切变的参数结构体
image_correct_x_y=imtransform(image_correct_x,Td,'FillValues',);%实现图像切变
实验结果:
6 这样基本要做的都已经完成,剩下字符切割。在测试过程中,发现车牌的上下边框边角好去除,左右边框则无法达到理想的要求,经常是要么没有切割完全,要把把车牌字符也切割了。最后索性就不管左右边框了,直接进行字符分割。自己所用的方法是:设置字符宽为width=1/2*车牌的高度;考虑到车牌的第二位和第三位之间有小点(也可能没有),中间距离更大,所以认为车牌宽度的一半既是第四个字符所在位置或者是第三和第四字符之间,这里最主要是要确定某个参数,来标定车牌位置,便于分割。(实验证明还是有效的)当遇到字符宽度大于默认width时,取大的值。车牌左右第一个和第七个字符则是截取默认宽度,去除边框影响。部分代码:
获取第四个字符:
%切割字符
[image_heigth image_length]=size(image_correct_x_y);
character_left=;%切割字符左右位置
character_right=;
middle_histcol=uint8(image_length/);
char_width=image_heigth/;%默认字符宽度 if binary_histcol(middle_histcol)> %垂直投影不为零
%找出车牌的第四个字符
for i=middle_histcol:-: %字符左侧
if binary_histcol(i)==
character_left=i+;
break;
end
end
for i=middle_histcol:image_length%字符右侧
if binary_histcol(i)==
character_right=i-;
break;
end
end
result_char_forth(:,:)=binary_image(:,character_left:character_right);
else %认为中间值在 第三、四个字符之间
for i=middle_histcol:image_length%获取第四个字符
if binary_histcol(i)> & binary_histcol(i-)== %字符左起点
character_left=i;
end
if binary_histcol(i)> & binary_histcol(i+)== %字符右边界
character_right=i;
break;
end
end
result_char_forth(:,:)=binary_image(:,character_left:character_right); %获取字符
if character_right-character_left+>char_width %比默认字符大
char_width=character_right-character_left+;%默认字符用于确认车牌左右两侧的宽度
end
end
判断中间有无小点:
%判断有无中间小点!!!!! width_dot=
width_dot=;%只能是字母,认为宽度小于4即为点,否则认为没有点
for i=current_left_position-:-:
if binary_histcol(i)> & binary_histcol(i+)== %字符右起点
character_right_temp=i;
end
if binary_histcol(i)> & binary_histcol(i-)== %字符左边界
character_left_temp=i;
break;
end
end
if((character_right_temp-character_left_temp)>width_dot)%不是点
current_left_position=character_left;%记录当前位置放到下面读取
else %是点
current_left_position=character_left_temp;%记录当前位置
end
切割结果:
可以看到,基本上消除了左右边框的影响。七个工作基本完成!欢迎交流!
基于matlab的蓝色车牌定位与识别---分割的更多相关文章
- 【原】基于matlab的蓝色车牌定位与识别---绪论
本着对车牌比较感兴趣,自己在课余时间摸索关于车牌的定位与识别,现将自己所做的一些内容整理下,也方便和大家交流. 考虑到车牌的定位涉及到许多外界的因素,因此有必要对车牌照的获取条件进行一些限定: 一.大 ...
- 基于matlab的蓝色车牌定位与识别---识别
接着昨天的工作,把最后一部分识别讲完. 关于字符识别这块,一种最省事的办法是匹配识别,将所得的字符和自己的标准字符库相减,计算所得结果,值最小的即为识别的结果.不过这种方法是在所得字符较为标准的情况, ...
- 基于matlab的蓝色车牌定位与识别---定位
接着昨天的工作继续.定位的过程有些是基于车牌的颜色进行定位的,自己则根据数字图像一些形态学的方法进行定位的. 合着代码进行相关讲解. 1.相对彩色图像进行灰度化,然后对图像进行开运算.再用小波变换获取 ...
- 车牌识别LPR(四)-- 车牌定位
第四篇:车牌定位 车牌定位就是采用一系列图像处理或者数学的方法从一幅图像中将车牌准确地定位出来.车牌定位提取出的车牌是整个车牌识别系统的数据来源,它的效果的好坏直接影响到整个系统的表现,只有准确地定位 ...
- 数字图像处理:基于MATLAB的车牌识别项目 标签: 图像处理matlab算法 2017-06-24 09:17 98人阅读 评论(0)
学过了数字图像处理,就进行一个综合性强的小项目来巩固一下知识吧.前阵子编写调试了一套基于MATLAB的车牌识别的项目的代码.今天又重新改进了一下代码,识别的效果好一点了,也精简了一些代码.这里没有使用 ...
- 基于MATLAB的手写公式识别(2)
基于MATLAB的手写公式识别 图像的预处理(除去噪声.得到后续定位分割所需的信息.) 预处理其本质就是去除不需要的噪声信息,得到后续定位分割所需要的图像信息.图像信息在采集的过程中由于天气环境的影响 ...
- 基于MATLAB的人脸识别算法的研究
基于MATLAB的人脸识别算法的研究 作者:lee神 现如今机器视觉越来越盛行,从智能交通系统的车辆识别,车牌识别到交通标牌的识别:从智能手机的人脸识别的性别识别:如今无人驾驶汽车更是应用了大量的机器 ...
- 基于MATLAB的手写公式识别(3)
基于MATLAB的手写公式识别 图像的膨胀化,获取边缘(思考是否需要做这种处理,初始参考样本相对简单) %膨胀 imdilate(dilate=膨胀/扩大) clc clear A1=imread(' ...
- 基于MATLAB的手写公式识别(9)
基于MATLAB的手写公式识别(9) 1.2图像的二值化 close all; clear all; Img=imread('drink.jpg'); %灰度化 Img_Gray=rgb2gray(I ...
随机推荐
- Oracle GoldenGate部署系列
在之前,为了某个项目,研究ogg 如何安装部署,已经对接大数据产品. 因为网上的很多资料都讲得不仔细,或者是版本对应不上,所以在部署时,遇到了非常多的困难. 作者根据自己的经验,录制了OGG整套部署和 ...
- WEB安全字体(Web Safe Fonts)-网页设计用什么字体兼容性好?
效果:http://sandbox.runjs.cn/show/qgdljvh4 1 Arial微软公司的网页核心字体之一,最常用的sans serif字体,当字号很小时不容易阅读.但是,大写的“I” ...
- CentOS与Ubuntu修改主机名
CentOS 1.执行hostname查看主机名 2.hostname + 主机名 使需要修改的主机名立即生效,但是下次重启会失效,故需要执行第三步 3.vim /etc/sysconfig/net ...
- python进阶10 MySQL补充 编码、别名、视图、数据库修改
python进阶10 MySQL补充 编码.别名.视图.数据库修改 一.编码问题 #MySQL级别编码 #修改位置: /etc/mysql/mysql.conf.d/mysqld.cnf def ...
- ngnix集群产生的问题
还可使用zookeper解决
- Java 面向对象,封装,继承
1相关概念的理解 1.1面向过程.面向对象 面向过程与面向对象都是编程中,编写程序的一种思维方式. 面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.(职员思想) 面向 ...
- 洛谷 P1690 贪婪的Copy
题目 本题难度较低,操作比较简单,首先对于范围较小的N(<=100),我们可以先跑一遍floyd,求出任意两点之间的最短路.对于很小的p(<=15),我们可以直接考虑全排列,运用到next ...
- Kendo 单页面应用(一)概述
Kendo 单页面应用(一)概述 Kendo 单页面应用(Single-Page Application,缩写为 SPA)定义了一组类用于简化 Web 应用(Rich Client)开发,最常见的单页 ...
- struts2 ognl表达式访问值栈
1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱. ...
- git remote add 用法
前一阵子,对于git remote add 的内容一直调错,现在明确一下: 这里是gitStack的用法:git remote add gitServerName http://ip/name(这里没 ...