在汽车牌照识别中,主要是将牌照部分突出显示出来,去除其他的无效干扰信息。车牌区域的识别是基于以下思想的:分析图像,使用pixval函数来获得牌照的背景色的红、绿、蓝分量亮度值和坐标;通过统计算法找出车牌的范围;通过修剪得到最终图像。
Matlab代码:
clc
clear
filename='car.jpg'; %图片的路径
I=im2gray(filename);%调用自编函数读取图像,如果为彩色图像自动转化为灰度图象;
tic %计时开始
[height,width]=size(I); %预处理 I_edge=zeros(height,width); %产生h*w的double类零矩阵
for i=1:width-1 %对每一列进行遍历 I_edge(:,i)=abs(I(:,i+1)-I(:,i));%每列的值赋为原图像中左右两列相减的绝对值(即梯度)
end
I_edge=(255/(max(max(I_edge))-min(min(I_edge))))*(I_edge-min(min(I_edge)));
% 归一化处理(0~255)
[I_edge,y1]=select(I_edge,height,width); %%%调用select函数,用以选择图像的某个区域
BW2 = I_edge;%
%%%%%%%%%%%%%%%%一些形态学处理
SE=strel('rectangle',[10,10]);%创建10*10的建构元素
IM2=imerode(BW2,SE);%腐蚀
IM2=bwareaopen(IM2,20);%删除小面积
IM3=imdilate(IM2,SE);%膨胀
%先腐蚀再膨胀,进行了开运算,消除小物体
%%%%%%%%%%%%%%%%%%投影以粗略估计车牌位置
p_h=projection(double(IM3),'h'); %调用projection函数,水平方向
if(p_h(1)>0)
p_h=[0,p_h];
end
p_v=projection(double(IM3),'v'); %调用projection函数,垂直方向
if(p_v(1)>0)
p_v=[0,p_v];
end
%%%%%%
p_h=double((p_h>5));%水平方向
p_h=find(((p_h(1:end-1)-p_h(2:end))~=0));
len_h=length(p_h)/2;
%%%%%
p_v=double((p_v>5));%垂直方向
p_v=find(((p_v(1:end-1)-p_v(2:end))~=0));
len_v=length(p_v)/2;
%%%%%%%%%%%
%%%%%%%%%%%%%%%%%粗略计算车牌候选区
k=1;
for i=1:len_h
for j=1:len_v
s=IM3(p_h(2*i-1):p_h(2*i),p_v(2*j-1):p_v(2*j));
if(mean(mean(s))>0.1)
p{k}=[p_h(2*i-1),p_h(2*i)+1,p_v(2*j-1),p_v(2*j)+1];
k=k+1;
end
end
end
k=k-1;
%%%%%%%%%%%%%%进一步缩小车牌候选区
for i=1:k
edge_IM3=double(edge(double(IM3(p{i}(1):p{i}(2),p{i}(3):p{i}(4))),'canny'));
[x,y]=find(edge_IM3==1);
p{i}=[p{i}(1)+min(x),p{i}(2)-(p{i}(2)-p{i}(1)+1-max(x)),...
p{i}(3)+min(y),p{i}(4)-(p{i}(4)-p{i}(3)+1-max(y))];
p_center{i}=[fix((p{i}(1)+p{i}(2))/2),fix((p{i}(3)+p{i}(4))/2)];
p_ratio(i)=(p{i}(4)-p{i}(3))/(p{i}(2)-p{i}(1));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%对上面参数和变量的说明:p为一胞元,用于存放每个图像块的左上和右下两个点的坐标;
%存放格式为:p{k}=[x1,x2,y1,y2];x1,x2分别为行坐标,y1,y2为列坐标
%p_center为一胞元,用于存放每个图像块的中心坐标,p_center{k}=[x,y];x,y分别为行,列坐标
%p_ratio为一矩阵,用来存放图像块的长宽比例
%%%%%%%%%%合并临近区域%%%%%%%
%如果有多个区域则执行合并
if k>1
n=0;
ncount=zeros(1,k);
for i=1:k-1
%%%需要调整if条件中的比例
%%%需要调整
%检查是否满足合并条件
if(abs(p{i}(1)+p{i}(2)-p{i+1}(1)-p{i+1}(2))<=height/30&&abs(p{i+1}(3)-p{i}(4))0)
d_ncount=ncount(2:n+1)-ncount(1:n); %避免重复记录临近的多个区域。
index=find(d_ncount~=1);
m=length(index);
for i=1:m
pp{i}=p{ncount(index(i))}; %重新记录合并区域的比例
pp_ratio(i)=(pp{i}(4)-pp{i}(3))/(pp{i}(2)-pp{i}(1));
end
p=pp; %更新区域记录
p_ratio=pp_ratio; %更新区域比例记录
clear pp;clear pp_ratio; %清除部分变量
end
end
k=length(p); %更新区域个数
%%%%%%%%%%%%%%合并结束%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%根据区域比例判断是否为车牌区域%%%%%%%%%%%%
m=1;T=0.6*max(p_ratio);
for i=1:k
if(p_ratio(i)>=T&p_ratio(i)=thr*mean(max(ImageData)));
BW2=bwareaopen(y,10); %删除小面积对象
SE=strel('square',15); %创建15*15正方形
IM2=imdilate(BW2,SE); %膨胀灰度,二值,压缩二值图像BW2,返回IM2
IM3=imerode(IM2,SE); %将IM2图像实现图像腐蚀灰度,返回腐蚀图像IM3
%1.开运算(先腐蚀后膨胀的过程):利用它可以消除小物体,在纤细点处分离物体,平滑较大物体边界,但同时并不明显改变原来物体的面积。OPEN(X,B)
%2.闭运算(先膨胀后腐蚀的过程):利用它可以填充物体内细小空洞,连接临近物体、平滑其边界,但同时并不明显改变原来物体的面积。CLOSE(X,B)
average=sum(sum(IM3))/(h*w); %将图像二值化
while(average0.08)
if(average=thr*mean(max(ImageData)));%求向量元素的平均值
BW2=bwareaopen(y,10);%再一次删除小面积
IM2=imdilate(BW2,SE);%膨胀
IM3=imerode(IM2,SE);%腐蚀
average=sum(sum(IM3))/(h*w);%求灰度的平均值
end
y1=y;
y=IM3;
3.y=projection(I,s)用于对图像的水平和垂直方向进行投影。
function y=projection(I,s)
if(s=='h') %水平投影
y=sum(I');
end
if(s=='v') %垂直投影
y=sum(I);
end
图1 彩色图像
图2 灰度处理后的原始图像
图3 腐蚀处理后图像
图4 灰度膨胀后图像
图5 最终处理得到的车牌图像