4
\$\begingroup\$

I'm working on a biometric matching system and I would like to have few suggestions regarding vectorizing the following code:

% tpol and ipol 
% column 1: x co-ordinate of the feature
% column 2: y co-ordinate of the feature
% column 3: angle orientation
% column 4: type of feature

ref_points=size(tpol,1); %number of rows=number of reference image points
   in_points=size(ipol,1); %number of rows=number of input image points
   radsize=7*ones(ref_points,1); %Radius size
   angsize=11* ones(ref_points,1); %Angle size
   radlow=-radsize./2;  % Lower Radius 
   radhigh=radsize./2; % Upper Radius
   anglow=-angsize./2;  % Lower Angle
   anghigh=angsize./2; % Upper Angle
   epsillon=10; 
   mscore=0; % initializing the matching score

   for i=1:ref_points
      for j=1:in_points
        rdiff=tpol(i,1)-ipol(j,1);    % Difference between the x-coordinate
        ediff=tpol(i,2)-ipol(j,2);      % Difference between the y-coordinate
        thetadiff=tpol(i,3)-ipol(j,3);   %Difference between the orientation 
        if ((radlow(i) < rdiff) && (rdiff < radhigh(i)) && (anglow(i) < ediff) && ...
            (ediff < anghigh(i)) && (abs(thetadiff) < epsillon) && ...
            (tpol(i,4)==ipol(j,4)))
            mscore=mscore+1;
            tpol(i,4)=3; %Change type of the feature to know that the line was used
        end
      end
    end
  end

ipol and tpol are the input image and reference image points respectively. They are both a matrix of size (A x 4) each, A being the number of features detected in each image.

I asked this question on Mathworks for which I received the following answer:

    r = [-3.5 3.5];  % Lower Radius and Upper Radius
    a = [-5.5 5.5];  % Lower Angle and Upper Angle
    epsillon=10;

    % Vectorized computation of rdiff,ediff,thetadiff i.e. x,y-co-ordinate
    % and orientation
    pol = bsxfun(@minus,tpol,permute(ipol,[3 2 1])); 
    p = all([bsxfun(@gt,pol(:,1:2,:),[r(1),a(1)]) & bsxfun(@lt,pol(:,1:2,:),[r(2),a(2)]),...
     pol(:,3,:) < ep, pol(:,4,:) == 0],2);
    mscore = nnz(p);
    tpol(any(p,3),4) = 4;

I checked the mscore received from the original code and verified it with the solution provided by plugging in one "if condition" at a time. All the "if conditions" provided me the same mscore except for:

if ((tpol(i,4)==ipol(j,4))

and

p= all ([pol(:,4,:) == 0],2);

It would be very helpful if someone could help me out with this. The for loop takes a long time when the points detected are many.

The input data can be downloaded from Google Drive

\$\endgroup\$
7
\$\begingroup\$

Regarding the vectorized code:

Therefore, it's close to impossible to improve the performance of the vectorized code you've posted.


Now, the question is: Is it correct?

It's hard to tell without knowing the exact data, but just by reading the code and your comments, I would think it is.

The reason why I think it is correct, even though the if conditions didn't return the same result:

You're comparing floating point values using ==. Check out Is floating point math broken?

When checking for equality, you should always use some tolerance. Have a look at the example below, where we are comparing 0.3 with 0.1 + 0.2:

x = 0.1;
y = 0.2;
z = 0.3;
the_same = (z == (x + y))
the_same =
     0
the_same = abs(z - (x + y)) < eps
the_same =
     1
\$\endgroup\$
  • \$\begingroup\$ I agree with the explanation. But, the data on the fourth column is either type 1 feature or type 2 feature. So I do not have any floating values. Sorry, I forgot to upload the data set. The data set is made available now. Please take a look at it. \$\endgroup\$ – shreyas kamath Jun 17 '16 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.