www.gusucode.com > 指纹识别源码(matlab语言编写) > 指纹识别源码(matlab语言编写)/指纹识别源码(matlab语言编写)/FingerPrint/fingerprint.m

    %% FingerPrint Demo
% If manual comparison by a fingerprint expert is always done to say if two 
% fingerprint images are coming from the same finger in critical cases, 
% automated methods are widely used now. 
%
% Among all the biometric techniques, fingerprint-based identification is 
% the oldest method which has been successfully used in numerous applications. 
% Everyone is known to have unique, immutable fingerprints. A fingerprint 
% is made of a series of ridges and furrows on the surface of the finger. 
% The uniqueness of a fingerprint can be determined by the pattern of ridges 
% and furrows as well as the minutiae points. Minutiae points are local ridge 
% characteristics that occur at either a ridge bifurcation or a ridge
% ending.

%%
% Florence Kussener, The MathWorks 
% Application Engineer
% August 2007
%%

clear all,close all,clc
%% Load image
% The general shape of the fingerprint is generally used to pre-process the
% images, and reduce the search in large databases. This uses the general 
% directions of the lines of the fingerprint, and the presence of the core 
% and the delta. Several categories have been defined in the Henry system: 
% whorl, right loop, left loop, arch, and tented arch. 
%
% Most algorithms are using minutiae, the specific points like ridges
% ending, bifurcation... Only the position and direction of these features 
% are stored in the signature for further comparison.
I=imread('Empreinte.bmp');
imshow(I);
set(gcf,'position',[1 1 600 600]);


%% Enhancement
% A critical step in automatic fingerprint matching is to automatically and 
% reliably extract minutiae from the input fingerprint images. However, the 
% performance of a minutiae extraction algorithm relies heavily on the 
% quality of the input fingerprint images. In order to ensure that the 
% performance of an automatic fingerprint identification/verification system 
% would be robust with respect to the quality of the fingerprint images, it 
% xould be essential to incorporate a fingerprint enhancement algorithm in the 
% minutiae extraction module.
%
% In our case, the quality of the image is really good, and we wwon't need
% to enhance our image. 


%% Binarize
% We binarize the image. After the operation, ridges in the fingerprint are
% highlighted with black color while furrow are white.
J=I(:,:,1)>160;
imshow(J)
set(gcf,'position',[1 1 600 600]);

%% Thining
% Ridge thining is to eliminate the redundant pixels of ridges till the 
% ridges are just one pixel wide.  
K=bwmorph(~J,'thin','inf');
imshow(~K)
set(gcf,'position',[1 1 600 600]);
%% Minutiae
% We filter the thinned ridge map by the filter "minutie". "minutie"
% compute the number of one-value of each 3x3 window:
% * if the central is 1 and has only 1 one-value neighbor, then the central 
% pixel is a termination.  
% * if the central is 1 and has 3 one-value neighbor, then the central 
% pixel is a bifurcation. 
% * if the central is 1 and has 2 one-value neighbor, then the central 
% pixel is a usual pixel. 
fun=@minutie;
L = nlfilter(K,[3 3],fun);

%% Termination
LTerm=(L==1);
imshow(LTerm)
LTermLab=bwlabel(LTerm);
propTerm=regionprops(LTermLab,'Centroid');
CentroidTerm=round(cat(1,propTerm(:).Centroid));
imshow(~K)
set(gcf,'position',[1 1 600 600]);
hold on
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro')

%% Bifurcation
LBif=(L==3);
LBifLab=bwlabel(LBif);
propBif=regionprops(LBifLab,'Centroid','Image');
CentroidBif=round(cat(1,propBif(:).Centroid));
plot(CentroidBif(:,1),CentroidBif(:,2),'go')
%% Remarks
% We have a lot of spurious minutae. 
% We are going to process them. 
% process 1: if the distance between a termination and a biffurcation is
% smaller than D, we remove this minutiae
% process 2: if the distance between two biffurcations is
% smaller than D, we remove this minutia
% process 3: if the distance between two terminations is
% smaller than D, we remove this minutia
D=6;
%% Process 1
Distance=DistEuclidian(CentroidBif,CentroidTerm);
SpuriousMinutae=Distance<D;
[i,j]=find(SpuriousMinutae);
CentroidBif(i,:)=[];
CentroidTerm(j,:)=[];

%% Process 2
Distance=DistEuclidian(CentroidBif);
SpuriousMinutae=Distance<D;
[i,j]=find(SpuriousMinutae);
CentroidBif(i,:)=[];


%% Process 3
Distance=DistEuclidian(CentroidTerm);
SpuriousMinutae=Distance<D;
[i,j]=find(SpuriousMinutae);
CentroidTerm(i,:)=[];
%%

hold off
imshow(~K)
hold on
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro')
plot(CentroidBif(:,1),CentroidBif(:,2),'go')
hold off


%% ROI
% We have to determine a ROI. For that, we consider the binary image, and
% we aply an closing on this image and an erosion. 
% With the GUI, I allow the use of ROI tools of MATLAB, to define manually
% the ROI.

Kopen=imclose(K,strel('square',7));

KopenClean= imfill(Kopen,'holes');
KopenClean=bwareaopen(KopenClean,5);
imshow(KopenClean)
KopenClean([1 end],:)=0;
KopenClean(:,[1 end])=0;
ROI=imerode(KopenClean,strel('disk',10));
imshow(ROI)

%% 

imshow(I)
hold on
imshow(ROI)
alpha(0.5)

hold on
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro')
plot(CentroidBif(:,1),CentroidBif(:,2),'go')
hold off

%% Suppress extrema minutiae
% Once we defined the ROI, we can suppress minutiae external to this ROI.
%{
%[m,n]=size(I(:,:,1));
%length=size(CentroidTerm);  %求取末梢点的个数,只取在有效区域的末梢
%for i=1:1:length(CentroidTerm)
%    if (CentroidTerm(i,2)<=n)&&(CentroidTerm(i,1)<=m)
%        indTerm=sub2ind([m,n],CentroidTerm(i,1),CentroidTerm(i,2));
%    end
%end
%}


%
[m,n]=size(I(:,:,1));
indTerm=sub2ind([m,n],CentroidTerm(:,1),CentroidTerm(:,2));
%}
Z=zeros(m,n);
Z(indTerm)=1;
ZTerm=Z.*ROI'; 
%ZTerm=Z.*ROI;  
[CentroidTermX,CentroidTermY]=find(ZTerm);
indBif=sub2ind([m,n],CentroidBif(:,1),CentroidBif(:,2));

%{
%{
%求取末梢点的个数,只取在有效区域的末梢
%for i=1:1:length(CentroidBif)
%    if (CentroidBif(i,2)<=n)&&(CentroidBif(i,1)<=m)
%        indBif=sub2ind([m,n],CentroidBif(i,1),CentroidBif(i,2));
%    end
%end
%}

Z=zeros(m,n);
Z(indBif)=1;
ZBif=Z.*ROI';
%ZBif=Z.*ROI;
[CentroidBifX,CentroidBifY]=find(ZBif);



imshow(I)
hold on
plot(CentroidTermX,CentroidTermY,'ro','linewidth',2)
plot(CentroidBifX,CentroidBifY,'go','linewidth',2)


%% Orientation
% Once we determined the differents minutiae, we have to find the
% orientation of each one
Table=[3*pi/4 2*pi/3 pi/2 pi/3 pi/4 
       5*pi/6 0 0 0 pi/6
       pi 0 0 0 0
      -5*pi/6 0 0 0 -pi/6
      -3*pi/4 -2*pi/3 -pi/2 -pi/3 -pi/4];
%% Termination Orientation 
% We have to find the orientation of the termination. 
% For finding that, we analyze the position of the pixel on the boundary of
% a 5 x 5 bounding box of the termination. We compare this position to the
% Table variable. The Table variable gives the angle in radian.
for ind=1:length(CentroidTermX)
    Klocal=K(CentroidTermY(ind)-2:CentroidTermY(ind)+2,CentroidTermX(ind)-2:CentroidTermX(ind)+2);
    Klocal(2:end-1,2:end-1)=0;
    [i,j]=find(Klocal);
    OrientationTerm(ind,1)=Table(i,j);
end
dxTerm=sin(OrientationTerm)*5;
dyTerm=cos(OrientationTerm)*5;
figure
imshow(K)
set(gcf,'position',[1 1 600 600]);
hold on
plot(CentroidTermX,CentroidTermY,'ro','linewidth',2)
plot([CentroidTermX CentroidTermX+dyTerm]',...
    [CentroidTermY CentroidTermY-dxTerm]','r','linewidth',2)


%% Bifurcation Orientation
%  For each bifurcation, we have three lines. So we operate the same
%  process than in termination case three times.
for ind=1:length(CentroidBifX)
    Klocal=K(CentroidBifY(ind)-2:CentroidBifY(ind)+2,CentroidBifX(ind)-2:CentroidBifX(ind)+2);
    Klocal(2:end-1,2:end-1)=0;
    [i,j]=find(Klocal);
    if length(i)~=3
        CentroidBifY(ind)=NaN;
        CentroidBifX(ind)=NaN;
        OrientationBif(ind)=NaN;
    else
        for k=1:3
            OrientationBif(ind,k)=Table(i(k),j(k));
            dxBif(ind,k)=sin(OrientationBif(ind,k))*5;
            dyBif(ind,k)=cos(OrientationBif(ind,k))*5;

        end
    end
end

plot(CentroidBifX,CentroidBifY,'go','linewidth',2)
OrientationLinesX=[CentroidBifX CentroidBifX+dyBif(:,1);CentroidBifX CentroidBifX+dyBif(:,2);CentroidBifX CentroidBifX+dyBif(:,3)]';
OrientationLinesY=[CentroidBifY CentroidBifY-dxBif(:,1);CentroidBifY CentroidBifY-dxBif(:,2);CentroidBifY CentroidBifY-dxBif(:,3)]';
plot(OrientationLinesX,OrientationLinesY,'g','linewidth',2)
%% Validation
% In this step, we validate the minutiae (cf GUI)

%% Save in a text file
% In this step, we are going to save the minutia in a file
MinutiaTerm=[CentroidTermX,CentroidTermY,OrientationTerm];
MinutiaBif=[CentroidBifX,CentroidBifY,OrientationBif];
saveMinutia('John Doe',MinutiaTerm,MinutiaBif);

%% Minutia Match
% Given two set of minutia of two fingerprint images, the minutia match
% algorithm determines whether the two minutia sets are from the same
% finger or not. 
% two steps:
% 1. Alignment stage
% 2. Match stage
%
% For this step, I would need a database I don't have...

%% GUI
% TODO: cr閑r le GUI associ?
    %}