基于形态学处理的指纹识别matlab仿真
1.算法描述
指纹识别的一般步骤为指纹采集、预处理、特征点提取、特征点匹配。指纹分为螺旋形、弓形、环形。指纹的处理效果影响着后面特征点的提取和识别效果,所以图像的预处理占有重要的地位。指纹采集一般有专业的设备,所以这一步骤一搬不关注。
①预处理
因为采集指纹时力度和各种因素所以采集的指纹灰度图会有很大不同,首先对图像进行归一化处理,归一化主要针对两个步骤:大小和灰度值。把采集到的指纹图统一调整到特定大小。灰度值我会根据整幅图的均值方差调整到某一范围内。
归一化处理完毕后会对图像进行分割处理,目的是区分出前景色和背景色。我采用的分割为根据多区域阈值分割。多区域分割的效果取决于区域的大小,而指纹的区域分为一脊一谷最好,所以我选择3x3的区域大小。我会根据对区域多次进行求均值和方差进行分割。采集到的指纹图背景的灰度值大于前景色,背景主要为低频,所以背景的方差小于前景的方差。我分别求得背景和前景的均值和方差然后会得到背景为白色 脊线为黑色。然后保存在矩阵e(二值图)中,我会根据e中位置等于1的点的八邻域点的和小于四得到背景色,达到背景和前景分离(e矩阵)。然后黑白反转让感兴趣的前景色变为白色(保存在Icc中),灰度图(gray)的背景值替换为小区域块的和的均值(G1).但是得到的脊线方向并不能达到准确识别指纹。所以下一步会沿脊线方向增强指纹纹路,采用的方法为基于脊线方向场的增强方法。为了估计脊线的方向场,把脊线的方向场划分为八个方向,然后根据八个方向的灰度值的总和来得到脊线的方向。并对图像进行二值化。此时脊线还是为黑色。因为各种采集原因(油脂水分等)会使指纹粘连断裂,会影响后续的特征提取和识别,接下来会去除指纹中的空洞和毛刺,如果当前位置点值为0(背景)该点的四邻域点(上下左右)的和大于3则为毛刺,空洞的判断方法为该点为白色(背景)的四周为黑色(前景)八领域点两的和为0,则为空洞。我们得到的图像的纹线仍具有一定的宽度,而指纹的识别只与纹线的走向有关。所以我们只需要纹线的宽度为一个像素宽度即可。下面我执行了黑白反转使感兴趣的区域(纹线)变为白色。在执行开操作和闭操作使边界平滑,消除细小的尖刺,断开窄小的连接。执行细化(bwmorph)得到细画图(thin)。
②特征点提取
特征点提取的点为端点和交叉点,遍历细化图的每一个像素点,端点的判别方法为八领域点两两相减取绝对值求和如果值为2则为端点(周围只有一个为1的白色点)和为6时为交叉点(周围有三值为1的白色点)。把找到的端点位置存储在txy(Nx3),第一列存储x的位置,第二列存储y的位置,第三列标识点的类别,如果为交叉点则值为6,如果端点则值为2.然后对纹线再次进行光滑处理。原理:找到每个端点,使其沿着纹线的方向移动五个像素,如果在五个像素之内遇到交叉点则此点为毛刺,去除此点。判断离端点num个距离内是否有另一个端点的函数为walk判断的主要方法先将该点置为0然后根据八领域点和;和为0或大于2则证明该点距离num内有端点,然后循环向前遍历。惊醒光滑处理后的特征点比以前少了。但是我们采集指纹时由于采集器的关系,图像的边缘会有很多端点,这已然会影响后续的识别工作,所以我们需要熊特征点中去除这些端点,cut函数主要做这些工作,边缘的主要特征就是黑色多白色少,也就是均值小,所以我主要里用灰度图的分区域(31*31)求均值如果灰度值小于70则在该区域的特征点去除,然后会得到更少的特征点,但这些点依然不够少说明不够特殊,下面定义了combine(thin,r,txy,num)函数可以找出周围半径为r个像素的圆内没有任何端点和交叉点,沿纹线走num个距离没有交叉点和端点,comine为walk和single_point函数的综合,walk函数上面已经介绍,single_point函数主要是找出独特的点作为特征点,原理是根据两个端点之间的距离。求每个端点距离其他端点的距离,找取距离大于r的端点。执行完combine后会得到更少的端点(实验结果为3个端点)。
(1)中值滤波
利用中值滤波可以对图像进行平滑处理。其算法简单,时间复杂度低,但其对点、线和尖顶多的图像不宜采用中值滤波。很容易自适应化。
(2)开运算
先腐蚀后膨胀的过程称为开运算。用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。
(3)闭运算
先膨胀后腐蚀的过程称为闭运算。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。
2.仿真效果预览
matlab2022a仿真结果如下:
3.MATLAB核心程序
thin1=tuxiangyuchuli('zhiwen.png');
thin2=tuxiangyuchuli('zhiwen.png');
figure;
txy1=point(thin1);
txy2=point(thin2);
[w1,txy1]=guanghua(thin2,txy2);
[w2,txy2]=guanghua(thin2,txy2);
thin1=w1;
thin2=w2;
txy1=cut(thin1,txy1);
txy2=cut(thin2,txy2);
[pxy31,error2]=combine(thin1,8,txy1,60);
[pxy32,error2]=combine(thin2,8,txy2,60);
error=1;
num=20;
cxy1=pxy31;
cxy2=pxy32;
d1=distance(cxy1(1,1),cxy1(1,2),num,thin1);
d2=distance(cxy2(1,1),cxy2(1,2),num,thin2);
f=(sum(abs((d1./d2)-1)));
if(f<0.5)
error=0;
else
error=1;
end
f
c11=find_point(cxy1(1,1),cxy1(1,2),txy1,1);
c12=find_point(cxy1(1,1),cxy1(1,2),txy1,2);
c21=find_point(cxy2(1,1),cxy2(1,2),txy2,1);
c22=find_point(cxy2(1,1),cxy2(1,2),txy2,2);
cxy1(2,:)=c11;
cxy1(3,:)=c12(2,:);
cxy2(2,:)=c21;
cxy2(3,:)=c22(2,:);
x11=cxy1(1,1);y11=cxy1(1,2);
x12=cxy1(2,1);y12=cxy1(2,2);
x13=cxy1(3,1);y13=cxy1(3,2);
x21=cxy2(1,1);y21=cxy2(1,2);
x22=cxy2(2,1);y22=cxy2(2,2);
x23=cxy2(3,1);y23=cxy2(3,2);
dd1(1)=juli(x11,y11,x12,y12);
dd1(2)=juli(x12,y12,x13,y13);
dd1(3)=juli(x13,y13,x11,y11);
dd2(1)=juli(x22,y21,x22,y22);
dd2(2)=juli(x22,y22,x23,y23);
dd2(3)=juli(x23,y23,x21,y21);
ff=sum(sum(abs((d1./d2)-1)))
if ff<1
error=0
else error=1
end
cxy1(2:41,:)=find_point(pxy31(1,1),pxy31(1,2),txy1,40);
cxy2(2:41,:)=find_point(pxy32(1,1),pxy32(1,2),txy2,40);
f11=length(find(cxy1(:,3)==2));
f12=length(find(cxy1(:,3)==6));
f21=length(find(cxy2(:,3)==2));
f22=length(find(cxy2(:,3)==6));
fff=abs(f11-f21)/(f11+f12)
toc