指纹识别源代码(2)-特征点提取

指纹识别源代码(2)-特征点提取_第1张图片

    上图为上一步拿到的图像预处理之后的细化图。在这个基础之上我们进行下一步操作。
    指纹特征提取的主要目的是计算指纹核心点(Core)和细节点(Minutia)的特征信息。在提取指纹核心点时,采用的是Poincare Index算法,该算法的思路是在指纹图像某像素点区域内,按围绕该点的闭合曲线逆时针方向旋转一周,计算方向角度旋转变化量的和,最后以计算结果来寻找核心点。计算过程中如果某像素点的Poincare Index值为π则判定为核心点,然后便提取该点的坐标与方向场信息,记为P(Cx, Cy, θc)。
    对于指纹的细节点特征,在本设计中只要求提取指纹脊线端点(Ending)和脊线分叉(Bifurcation)两种细节点。在细化的指纹图像中,这两种细节点的形态如图2和图3所示:


指纹识别源代码(2)-特征点提取_第2张图片

    在提取指纹细节点时,首先为细化图像中的每个像素点P建立一个8邻域像素区,如图4所示。其中P1~P8为像素点P周围的邻近环绕像素点。P1~P8中黑色点的值设为1,白色点的值设为0。

指纹识别源代码(2)-特征点提取_第3张图片

图4 8邻域像素图

根据Crossing Number (CN)理论,在8邻域像素图中按照公式1计算像素点的CN值。例如在图2和图3中,8领域像素区域内中心点的CN值分别为1和3。

 
    最后按上述方法对细化指纹图像中的所有像素点进行CN值计算,当CN值为1时,可判定所检测的P点为脊线端点,当CN值为3时,则可判定P点为脊线分叉点。检测到细节点之后返回该点的坐标(x,y),并根据CN的值返回细节点的类型T,然后再读取该点的方向角θ。因此,在本算法中一个指纹细节点的具体特征最后用M(x, y, θ ,T)算子来表征。(请注意,代码中,以及下文没有除以2)

    把找到的端点位置存储在txy(Nx3),第一列存储x的位置,第二列存储y的位置,第三列标识点的类别,如果为交叉点则值为6,如果端点则值为2.然后对纹线再次进行光滑处理。

%找出细化后图像的所有端点
%将一个点的八个邻域依次两两相减并取绝对值,并将所有结果相加,从细化图像的特征来说
%和为2时为端点 和为6时为交叉点
function txy=point(thin)
count=1;
txy(count,:)=[0,0,0];
%取行数和列数的最小值
siz=min(size(thin,1),size(thin,2))
for x=40:siz-40
    for y=40:siz-40
        if(thin(y,x))
            CN=0;
            for i=1:8
                CN=CN+abs(p(thin,y,x,i)-p(thin,y,x,i+1));
            end
            if (CN==2)
                txy(count,:)=[x,y,2];
                count=count+1;
            end
            if(CN==6)
                txy(count,:)=[x,y,6];
                count=count+1;
            end
        end
    end
end

for i=1:count-1
    x(i)=txy(i,1);
    y(i)=txy(i,2);
end
imshow(double(thin));
% hold on 通知后面将要绘图
hold on;
plot(x,y,'.');
指纹识别源代码(2)-特征点提取_第4张图片

    找到每个端点,使其沿着纹线的方向移动五个像素,如果在五个像素之内遇到交叉点则此点为毛刺,去除此点。判断离端点num个距离内是否有另一个端点的函数为walk判断的主要方法先将该点置为0然后根据八领域点和;和为0或大于2则证明该点距离num内有端点,然后循环向前遍历。

function [w,pxy]=guanghua(thin,txy)
%纹线光滑处理.原理:找到每个端点,使其沿着纹线的方向移动5个像素,如果在5个像素之内遇到交叉点,则认为此端点为毛刺,,去除此点
for j=1:5
    txy=point(thin);
    %txy第三列为2的变为1 否则变为0
    pxy=txy(find(txy(:,3)==2),:);
    %求取行数
    n=size(pxy,1);
    for i=1:n
        error=0;
        error=walk(thin,pxy(i,1),pxy(i,2),5);
        if error==1;
            thin(pxy(i,2),pxy(i,1))==0;
        end
    end
end
w=thin;
imshow(w);
%判断离端点num距离内是否有另一端点
function [error,a,b]=walk(thin,x0,y0,num)
error=0;
thin(x0,y0)=0;
t1=0;
for n=1:num
    if error==1
        break
    else
        x=x0;
        y=y0;
        %判断该点八邻域点和该点的和 来找出想要的点
        for x=x0-1:x0+1
            if error==1
                break;
            else
                for y=y0-1:y0+1
                    t1=(sum(sum(thin(y0-1:y0+1,x0-1:x0+1))));
                    %=0代表一个断点(独立的点) dayu2代表不是端点
               
                    if(t1==0||t1>2)
                        error=1;
                        a=x0;
                        b=y0;
                        break;
                    else
                        % x,y还是y,x
                        if (thin(y,x)==1&&(x-x0)^2+(y-y0)^2~=0)
                            if(t1>2)
                                error=1;
                                break;
                            else thin(y,x)=0;
                                x0=x;
                                y0=y;
                                a=x0;
                                b=y0;
                                plot(x0,y0,'r.');
                            end
                        end
                    end
                end
            end
        end
    end
end

    光滑处理后的特征点比以前少了。但是我们采集指纹时由于采集器的关系,图像的边缘会有很多端点,这已然会影响后续的识别工作,所以我们需要在特征点中去除这些端点,cut函数主要做这些工作,边缘的主要特征就是黑色多白色少,也就是均值小,所以我主要里用灰度图的分区域(31*31)求均值如果灰度值小于70则在该区域的特征点去除,然后会得到更少的特征点.

%去除图像边缘的端点

function txy=cut(thin,txy)
% thin=thin1;
% txy=txy1;
%声明一个8*8的矩阵
s(8,8)=0;
delta(8,8)=0;
n=size(txy,1);
for i=1:8
    for j=1:8
        %声明一个数组集合 m{1,2}=3   m=[] [3]
%          m{2,5}=6
% 
% m = 
% 
%     [1,2,3]    [3]    []    []     []
%     []     []    []    []    [6]

% 每次取31*31 先从上到下 再从做到右
        mp{i,j}=thin(1+31*(i-1):31+31*(i-1),1+31*(j-1):31+31*(j-1));
        s(i,j)=sum(sum(mp{i,j}))/(31*31);
        mp{i,j}=(mp{i,j}-s(i,j)).^2
        delta(i,j)=sum(sum(mp{i,j}));
%         边缘 黑色多 白色少
        if delta(i,j)<=70
            for k=1:n
                if (txy(k,1)>=1+31*(i-1)&&txy(k,1)<31+31*(i-1)&&txy(k,2)>=1+31*(j-1)&&txy(k,2)<=31+31*(j-1)&&txy(k,3)==2)
                    txy(k,:)=[0,0,0];
                end
            end
        end
    end
end
% find()查询非零元素所在的位置
txy=txy(find(txy(:,1)),:);
plot(txy(:,1),txy(:,2),'ro');

    但这些点依然不够少说明不够特殊,下面定义了combine(thin,r,txy,num)函数可以找出周围半径为r个像素的圆内没有任何端点和交叉点,沿纹线走num个距离没有交叉点和端点,comine为walk和single_point函数的综合,walk函数上面已经介绍,single_point函数主要是找出独特的点作为特征点,原理是根据两个端点之间的距离。求每个端点距离其他端点的距离,找取距离大于r的端点。执行完combine后会得到更少的端点(实验结果为3个端点)。

% 综合walk和single_point函数,通过执行[pxy3,error2]=combine(thin,r,txy,num)可以找出周围半径为r个像素的院内没有任何交叉点或端点,并且沿纹线走num个
% 距离内没有任何哟个交叉点或端点
function [pxy3,error2]=combine(thin,r,txy,num)
error=0;
[pxy2,error]=single_point(txy,r);
n=size(pxy2,1);
k=1;
erroe2=0;
for i=1:n
    [error,a,b]=walk(thin,pxy2(i,1),pxy2(i,2),num);
    if error~=1
        pxy3(k,1)=pxy2(i,1);
        pxy3(k,2)=pxy2(i,2);
        pxy3(k,3)=pxy2(i,3);
        k=k+1;
        error2=0;
        plot(pxy2(i,1),pxy2(i,2),'r+');
    end
end

指纹识别源代码(2)-特征点提取_第5张图片


你可能感兴趣的:(生物识别,指纹识别,生物模式识别)