HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Vectorizing a polar coordinate conversion loop in a fingerprint-matching process

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
conversionpolarprocessloopcoordinatefingerprintvectorizingmatching

Problem

I am working on a fingerprint matching technique and it takes a lot of computation time to obtain the result. I am trying to implement the matching process given in A Minutia Matching Algorithm in Fingerprint Verification. I would like to know if there is any method available to reduce the for loop for this code:

[Tdrow,Tdcol]=size(Td);
[Idrow,Idcol]=size(Id);
matchingscore=zeros(Tdrow,Idrow);
rv = bsxfun(@minus,Td(:,3),permute(Id(:,3),[2 1]));
%convert each minutiae point to polar coordinates with respect to the
%reference minutiae in each case
for i=1:Tdrow
    for j=1:Idrow
        Tdp=zeros(Tdrow,Tdcol);
        Idp=zeros(Idrow,Idcol);
        tref=Td(i,:);
        iref=Id(j,:);
        Tdp(:,1)=sqrt((Td(:,1)-tref(1)).^2 + (Td(:,2)-tref(2)).^2);
        Tdp(:,2)=mod(atan2(tref(1)-Td(:,1),Td(:,2)-tref(2)) * 180/pi,360);
        Tdp(:,3)=mod(Td(:,3)-tref(3),360);
        Tdp(:,4)=Td(:,4);
        Idp(:,1)=sqrt((Id(:,1)-iref(1)).^2 + (Id(:,2)-iref(2)).^2);
        Idp(:,2)=mod((atan2(iref(1)-Id(:,1),Id(:,2)-iref(2)) * 180/pi) + rv(i,j),360);
        Idp(:,3)=mod(Id(:,3)-iref(3),360);
        Idp(:,4)=Id(:,4);
        Tdp1 {i,j}= Tdp(:,:);
        Idp1 {i,j}= Idp(:,:);
    end
end


Here, the variable Td is the fingerprint template to be compared and Id is the input fingerprint template. Both Td and Id have four columns, i.e. 1st and 2nd column provide x and y coordinate respectively, 3rd column is the angle and 4th column is the type of minutiae. Tdp and Idp are calculated using the equation provided in the attachment provided in the link.

Can this code be vectorized? I understand that the indexes have hardly been used. But without changing the index i cannot continue to the further steps. It would be very helpful is anyone could provide me with any suggestions.

The data values are available on Google Drive. These has both the input data and output data.

Solution

You said your code works good, as the input isn't too big, so I won't go ahead an try to vectorize this. So, I've provided a general review of the code.

Overall your code looks nice. You should however attempt to have a bit more spaces

[Tdrow, Tdcol] = size(Td);  <-- This
[Tdrow,Tdcol]=size(Td);     <-- Not this


There are only a few things I would do differently in the code:

-
You can speed this up quite a bit even without vectorization: The size of the cells Tdp1 and Idp1 are known, so these cells can be pre-allocated in front of the loop:

[Tdp1{1:Tdrow, 1:Idrow}] = zeros(Tdrow, Tdcol);
[Idp1{1:Tdrow, 1:Idrow}] = zeros(Idrow, Idcol);


This way you avoid creating Tdrow*Idrow arrays inside the loop. That should save you some time.

-
Tdp(:,:) is the same as just Tdp, so you can do:

Tdp1{ii,jj} = Tdp;


-
Note, ii and jj are better than i and j as iterator names in Matlab.

-
You are converting angles from radians to degrees a few places atan2(x,y) * 180 / pi. Instead, use atan2d(x,y). It returns the value in degrees directly.

Code Snippets

[Tdrow, Tdcol] = size(Td);  <-- This
[Tdrow,Tdcol]=size(Td);     <-- Not this
[Tdp1{1:Tdrow, 1:Idrow}] = zeros(Tdrow, Tdcol);
[Idp1{1:Tdrow, 1:Idrow}] = zeros(Idrow, Idcol);
Tdp1{ii,jj} = Tdp;

Context

StackExchange Code Review Q#131910, answer score: 3

Revisions (0)

No revisions yet.