This is a fingerprint recognition code ,some portion of code is working but whole of it .after the Bifurcation Orientation part of the code it is not showing the output.
6 次查看(过去 30 天)
显示 更早的评论
%% FingerPrint Recog
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));
indTerm=sub2ind([m,n],CentroidTerm(:,1),CentroidTerm(:,2));
Z=zeros(m,n);
Z(indTerm)=1;
ZTerm=Z.*ROI';
[CentroidTermX,CentroidTermY]=find(ZTerm);
indBif=sub2ind([m,n],CentroidBif(:,1),CentroidBif(:,2));
Z=zeros(m,n);
Z(indBif)=1;
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)
rest of the code
% Minutia Match
%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
%( Alignment stage)
function [newXY] = MinuOriginTransRidge(real_end,k,ridgeMap)
theta = real_end(k,3);
if theta <0
theta1=2*pi+theta;
else
theta1=pi/2-theta;
end
rotate_mat=[cos(theta1),-sin(theta1);sin(theta1),cos(theta1)];
%locate all the ridge points connecting to the miniutia
%and transpose it as the form:
%x1 x2 x3...
%y1 y2 y3...
pathPointForK = find(ridgeMap(:,3)== k);
toBeTransformedPointSet = ridgeMap(min(pathPointForK):max(pathPointForK),1:2)';
%translate the minutia position (x,y) to (0,0)
%translate all other ridge points according to the basis
tonyTrickLength = size(toBeTransformedPointSet,2);
pathStart = real_end(k,1:2)';
translatedPointSet = toBeTransformedPointSet - pathStart(:,ones(1,tonyTrickLength));
%rotate the point sets
newXY = rotate_mat*translatedPointS;
end
%(Minutiae matching)
function [newXY] = MinuOrigin_TransAll(real_end,k)
theta = real_end(k,3);
if theta <0
theta1=2*pi+theta;
else
theta1=pi/2-theta;
end
rotate_mat=[cos(theta1),-sin(theta1),0;sin(theta1),cos(theta1),0;0,0,1];
toBeTransformedPointSet = real_end';
tonyTrickLength = size(toBeTransformedPointSet,2);
pathStart = real_end(k,:)';
translatedPointSet = toBeTransformedPointSet - pathStart(:,ones(1,tonyTrickLength));
newXY = rotate_mat*translatedPointSet;
for i=1:tonyTrickLength
if or(newXY(3,i)>pi,newXY(3,i)<-pi)
newXY(3,i) = 2*pi - sign(newXY(3,i))*newXY(3,i);
end
end
end
2 个评论
Walter Roberson
2020-4-27
What is the question??
Did you put in a breakpoint to test the results you were getting?
回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Recognition, Object Detection, and Semantic Segmentation 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!