目录

1.归一化和切割

2.均值滤波和二值化

3.细化

4.找中心点

5.找端点和分叉点

6.匹配(未完待续)

主函数代码

close all
clear all
clc

im1=imread('108_4.tif');
figure
imshow(im1);title('原图像');


I=normalize2(im1);%归一化和切割
figure 
imshow(uint8(I));

im3=derection_bw(I);%二值化
figure
imshow(im3);
 
im4=thin(im3);%细化
figure
imshow(im4);

[x0,y0]=centralizing(double(im4));%找中心点
figure
imshow(im4);
hold on;plot(x0,y0,'go');hold off;

im4=~im4;
[x3,y3,x4,y4]=find_feature2(im4,x0,y0,100);%找特征点
figure
imshow(im4);hold on;
plot(x3,y3,'bo');plot(x4,y4,'ro');hold off ;

原图

在这里插入图片描述

1.归一化和切割

归一化调整的是指纹灰度均值和方差,调整到标准状态,同时可以屏蔽不必要的噪声。
归一化方法如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

函数1:归一化和切割

function y=normalize2(x)
%对指纹图像进行归一化处理
x1=double(x);
[a,b,~]=size(x);
m=20;
a1=a/m;%行分块数
b1=b/m;%列分块数
M0=mean2(x1);
V=std2(x1);
V0=V*V;
M1=80;
V1=6000;
T=60;
a3=1;%块移动的行位置
b3=1;%块移动的列位置
for i=1:a
    for j=1:b
        if x1(i,j)>M0
            result(i,j)=M1+sqrt(V1*((x1(i,j)-M0)*(x1(i,j)-M0))/V0);
        else
            result(i,j)=M1-sqrt(V1*((x1(i,j)-M0)*(x1(i,j)-M0))/V0);
        end
    end
end

for k=1:a1
    for l=1:b1
        M2=mean2(result(a3:(a3+m-1),b3:(b3+m-1)));%均值
        V2=std2(result(a3:(a3+m-1),b3:(b3+m-1)));%方差
        V3=V2*V2;

        if V3<1000
            for i1=a3:a3+m-1
                for j1=b3:b3+m-1
                    result(i1,j1)=255;
                end
            end
        end

        if V2==0
            for i1=a3:a3+m-1
                for j1=b3:b3+m-1
                    result(i1,j1)=255;
                end
            end
        else
            Th=M2/V2;
            if Th>T
                for i1=a3:a3+m-1
                    for j1=b3:b3+m-1
                        result(i1,j1)=255;
                    end
                end
            end
        end
        b3=b3+m;
    end
    b3=1;
    a3=a3+m;
end
y=result;

归一化和切割效果:

在这里插入图片描述

2.二值化
二值化方案一:局部阈值法

由于原始指纹图像不同区域深浅不一, 如对整幅图像用同一阈值进行二值分割, 会造成大量有用信息的丢失。 所以我们可以选用局部阈对图像进行二值化。局部阈值法即选取 N×N的块,求该区域的阈值并对该区域二值化,可以有效地保证信息的可靠性。
二值化方案二:基于方向场的二值化
采集到的指纹图像一般都有比较清晰的方向场,方向场估计得准确与否直接决定了图像二值化算法的效果。
为估计方向场,我们把指纹脊线的走向分为如下 8 个方向
在这里插入图片描述

先进行均值滤波,然后对图像的每一个像素,为确定在该像素处的脊线方向,在以该像素为中心的 99 窗口内,分别计算 8
个方向上的经过处理后的灰度值,即将图中数字 1 到 8 的位置的像素灰度值去除其中最大 summax和最小值 summin, 若满足最大的 summax 和最小的 summin 与 4I(x,y)) 之和大于 (3*summ/8), 则该像素点的脊线方向为summin,否则为 summax。确定完脊线方向后再由该方向场对图像进行二值化。

function im_out=derection_bw(I)
temp=(1/9)*[1 1 1;1 1 1;1 1 1]; % 模板系数、均值滤波
[m,n,~]=size(I);
Im=double(I);
In=zeros(m,n);
Icc=ones(m,n);
for a=2:m-1
    for b=2:n-1
        In(a,b)=Im(a-1,b-1)*temp(1,1)+Im(a-1,b)*temp(1,2)+Im(a-1,b+1)*temp(1,3)+Im(a,b-1)*temp( 2,1)+Im(a,b)*temp(2,2)+Im(a,b+1)*temp(2,3)+Im(a+1,b-1)*temp(3,1)+Im(a+1,b)*temp(3,2)+ Im(a+1,b+1)*temp(3,3);
    end
end
I=In;
Im=zeros(m,n);

for x=5:m-5
    for y=5:n-5
        sum1=I(x,y-4)+I(x,y-2)+I(x,y+2)+I(x,y+4); 
        sum2=I(x-2,y+4)+I(x-1,y+2)+I(x+1,y-2)+I(x+2,y-4); 
        sum3=I(x-2,y+2)+I(x-4,y+4)+I(x+2,y-2)+I(x+4,y-4); 
        sum4=I(x-2,y+1)+I(x-4,y+2)+I(x+2,y-1)+I(x+4,y-2); 
        sum5=I(x-2,y)+I(x-4,y)+I(x+2,y)+I(x+4,y); 
        sum6=I(x-4,y-2)+I(x-2,y-1)+I(x+2,y+1)+I(x+4,y+2); 
        sum7=I(x-4,y-4)+I(x-2,y-2)+I(x+2,y+2)+I(x+4,y+4); 
        sum8=I(x-2,y-4)+I(x-1,y-2)+I(x+1,y+2)+I(x+2,y+4); 
        sumi=[sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8];
        summax=max(sumi); summin=min(sumi); summ=sum(sumi);
        b=summ/8;
        if (summax+summin+ 4*I(x,y))> (3*summ/8)
            sumf = summin;
        else
            sumf =summax;
        end
        if sumf > b
            Im(x,y)=128;
        else
            Im(x,y)=255;
        end
    end
end
for i=1:m
    for j =1:n
        Icc(i,j)=Icc(i,j)*Im(i,j);
    end
end
for i=1:m
    for j =1:n
        if (Icc(i,j)==128)
            Icc(i,j)=0;
        else
            Icc(i,j)=1;
        end
    end
end
im_out=Icc;

二值化效果:

在这里插入图片描述

3.细化

细化过程中要根据每个像素的八个相邻点的情况来判断该点是否可以剔除或保留,其实质类似于腐蚀操作

在这里插入图片描述

在这里插入图片描述

代码实现:

function im_out = thin2(I)%有孤岛待去除
I=im3;
[M,N]=size(I);
for i=2:M-1
    for j=2:N-1
        if I(i,j)==0
            if (I(i-1,j)==0&&I(i,j+1)==0)||(I(i-1,j)==0&&I(i,j-1)==0)||(I(i+1,j)==0&&I(i,j-1)==0)||(I(i+1,j)==0&&I(i,j+1)==0)
                I(i,j)=1;
            else
                I(i,j)=0;
            end
        end
    end
end
end

细化算法1结果

在这里插入图片描述

经实验,效果不佳,于是采用MATLAB自带的bwmorph函数进行细化,除此之外,还加上了去除毛刺和空洞的部分

function y=thin(x)
I=ordfilt2(x,5,ones(3,3));%对指纹图像进行3×3滤波
u=I;
[m,n]=size(u) 
for x=2:m-1
    for y=2:n-1
        if u(x,y)==0
            if u(x,y-1)+u(x-1,y)+u(x,y+1)+u(x+1,y)>=3
                u(x,y)=1;
            else
                u(x,y)=u(x,y);
            end
        end
    end
end
for a=2:m-1
    for b=2:n-1
        if u(a,b)==1
            if abs(u(a,b+1)-u(a-1,b+1))+abs(u(a-1,b+1)-u(a-1,b))+abs(u(a-1,b)-u(a-1,b-1))+abs(u(a-1,b-1)-u(a,b-1))+abs(u(a,b-1)-u(a+1,b-1))+abs(u(a+1,b-1)-u(a+1,b))+abs(u(a+1,b)-u(a+1,b+1))+abs(u(a+1,b+1)-u(a,b+1))~=1%寻找端点
                if (u(a,b+1)+u(a-1,b+1)+u(a-1,b))*(u(a,b-1)+u(a+1,b-1)+u(a+1,b))+(u(a-1,b)+u(a-1,b-1)+u(a,b-1))*(u(a+1,b)+u(a+1,b+1)+u(a,b+1))==0 %去除毛刺和空洞
                    u(a,b)=0;
                end
            end
        end
    end
end
v=~u;
w=bwmorph(v,'thin',Inf);%对图像进行细化
for x=2:m-1
    for y=2:n-1
        if w(x,y)==1
            if (w(x-1,y)==1&&w(x,y-1)==1)||(w(x-1,y)==1&&w(x,y+1)==1)||(w(x,y-1)==1&&w(x+1,y)==1)||(w(x+1,y)==1&&w(x,y+1)==1)
                w(x,y)=0;
            end
        end
    end
end
y=w;

细化算法2效果:

在这里插入图片描述

4.中心点提取

提取指纹的中心点有很多作用,比如可以把指纹扇形化后变成特征图,用于指纹匹配。这里求中心点只是为了去除指纹边缘的伪特征点。

在这里插入图片描述

在这里插入图片描述

代码:

function [XofCenter,YofCenter]=centralizing(fingerprint)
imgN=size(fingerprint,1);
imgM=size(fingerprint,2);
image=wiener2(fingerprint,[3 3]);
[Gx,Gy]=gradient(image);
orientnum=wiener2(2.*Gx.*Gy,[3 3]);
orientden=wiener2((Gx.^2)-(Gy.^2),[3 3]);
W=8;
l1=9;
orient=zeros(imgN/W,imgM/W);
points=(imgN/W)* (imgM/W);
for i=1:1:points
    x=floor((i-1)/(imgM/W))* W+1;
    y=mod(i-1,(imgN/W))* W+1;
    numblock=orientnum(y:y+W-1,x:x+W-1);
    denblock=orientden(y:y+W-1,x:x+W-1);
    somma_num=sum(sum(numblock));
    somma_denom=sum(sum(denblock));
    if somma_denom~=0
        inside = somma_num/somma_denom;
        angle=0.5*atan(inside);
    else
        angle=pi/2;
    end
 %each block
 if angle<0
     if somma_num<0
         angle=angle+pi/2;
     else
         angle=angle+pi;
     end
 else
     if somma_num>0
         angle=angle+pi/2;
     end
 end
 orient(1 +(y-1)/W,1+(x-1)/W)=angle;
end
binarize=(orient<pi/2);
[bi,bj]=find(binarize);
xdir=zeros(W,W);
ydir=zeros(W,W);
for k=1:1:size(bj,1)
    i=bj(k);
    j=bi(k);
    if orient(j,i)<pi/2
        x=fix(l1*cos(orient(j,i)-pi/2)/(W/2));
        y=fix(l1*sin(orient(j,i)-pi/2)/(W/2));
        xdir(j,i)=i-x;
        ydir(j,i)=j-y;
    end
end
binarize2=zeros(imgN/W,imgM/W);
for i=1:1:size(bj,1)
    x=bj(i);
    y=bi(i);
    if~(xdir(y,x)<1||ydir(y,x)<1||xdir(y,x)>imgM/W||ydir(y,x)>imgN/W)
        while binarize(ydir(y,x),xdir(y,x))>0
            xtemp=xdir(y,x);
            ytemp=ydir(y,x);
            if xtemp<1||ytemp<1||xtemp>imgM/W||ytemp>imgN/W
                break;
            end
            x=xtemp;
            y=ytemp;
            if xdir(y,x)<1||ydir(y,x)<1||xdir(y,x)>imgM/W||ydir(y,x)>imgN/W
                if x-1>0
                    while binarize(y,x-1)>0
                        x=x-1;
                        if x-1<1
                            break;
                        end
                    end
                end
                break;
            end
        end
    end
    binarize2(y,x)=binarize2(y,x)+1;
end
[temp,y]=max(binarize2(1:end-7,:));
[temp2,x]=max(temp);
angle=orient(y(x),x)-pi/2;
XofCenter=round(x*W-(W/2)-(l1/2)*cos(angle));
YofCenter=round(y(x)*W-(W/2)-(l1/2)*sin(angle));
%Outputprint=binarize2;
end

求中心点效果:

在这里插入图片描述

5.求特征点

这里我们用最常用的两类特征点:端点和分叉点
找点方法是模板匹配法。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

若细化不完全,会有很多点会误识别为特征点

在这里插入图片描述

去除伪特征点:
因为采集、预处理过程中的空因素和提取算法的原因,提取到的特征点中会存在很多为特征点。 为了不影响后续的识别, 必须进行剔除。 本程序中剔除的伪特征点主要有两种:指纹边缘点,断点,并根据这三种伪特征点的特征进行剔除。两类伪特征点如下(红色为伪特征点)

在这里插入图片描述

在这里插入图片描述

代码

function [X1,Y1,X2,Y2]=find_feature2(I,x0,y0,radius)
[M,N]=size(I);
t=0;
k=0;
for i=2:M-1
    for j=2:N-1
        if I(i,j)==0
            n=I(i-1,j-1)+I(i-1,j)+I(i-1,j+1)+I(i,j-1)+I(i,j+1)+I(i+1,j-1)+I(i+1,j)+I(i+1,j+1);
            if (n==5)%分叉点
                t=t+1;
                x1(t)=j;
                y1(t)=i;
            end
            if (n==7)%端点
                k=k+1;
                x2(k)=j;
                y2(k)=i;
            end
        end
    end
end
%去除距离较近的特征点
for i=1:t-1
    for j=i+1:t
        d=sqrt((x1(i)-x1(j))^2+(y1(i)-y1(j))^2);
        if d<20 
            x1(i)=-1;y1(i)=-1;x1(j)=-1;y1(j)=-1;
        end
    end
end
for i=1:k-1
    for j=i+1:k
        d=sqrt((x2(i)-x2(j))^2+(y2(i)-y2(j))^2);
        if d<10 
            x2(i)=-1;y2(i)=-1;x2(j)=-1;y2(j)=-1;
        end
    end
end
%保留中心点半径之内的点
c=1;
for i=1:t
    d(i)=sqrt((x1(i)-x0)^2+(y1(i)-y0)^2);
    if(d(i)<radius)
    X1(j)=x1(i);
    Y1(j)=y1(i);
    j=j+1;
    end
end
j=1;
for i=1:k
    d(i)=sqrt((x2(i)-x0)^2+(y2(i)-y0)^2);
    if(d(i)<radius)
    X2(j)=x2(i);
    Y2(j)=y2(i);
    j=j+1;
    end
end
end

求特征点效果:(红色为端点,蓝色为分叉点)

在这里插入图片描述

7.匹配(未完待续)