image thumbnail
from Contour Parameterization by Asad Ali
This function takes as input an image having white background and black foreground and traces the en

affine_contour_trace(BW,row,col,xx1,yy1)
%-------------------------------------------------------------------------
% Programmed by Asad Ali
% Graduate Student, Faculty of Computer Science & Engineering
% GIK Institute of Engineering Sciences & Technology
% Pakistan.
% email :-  asad_82@yahoo.com
% August 2006.
%-------------------------------------------------------------------------

function [sp_x] = affine_contour_trace(BW,row,col,xx1,yy1)


% Contour Tracing of a Black White Image (Binary Image).
%
% This function takes as input an image having white background and black 
% foreground and traces the entire contour and returns the row and column
% coordinate values of all the points which lie on the contour
%
% This can be used in Line Following Algorithms and for parameterizing 
% affine distorted contours. 
%
% Syntax : 
% cpixels = affine_contour_trace(BW,r,c,xx1,yy1)
%
%   Input :
%   BW - Black & White Image (Binary Image).
%   row,col - row, column value of a single pixel on the contour, serves as
%             the starting point of parameterization
%   xx1,yy1 - listing of all the boundary points of the object obtained  
%             using the command:  [xx1,yy1,p] = find(originalImage);
%
%
%   Output : 
%   sp_x  - N x 2 matrix which stores the coordinate values of the contour,
%           column1 gives the rows & column2 the corresponding column.
% 
%   See the SampleUsage file for an example 

xx = xx1; yy = yy1;
k=1;loop=0;
C(1:size(BW,1),1:size(BW,2))=255;      
sp_x(1,1)=row; sp_x(1,2)=col;
C(row,col) = 0;

while(1)
    xxTemp = xx; yyTemp = yy;
    prev_size=size(sp_x,1);

    % check the central pixel
    if BW(sp_x(k,1),sp_x(k,2)) < 255
        index = 0;
        % extract the coordinates of active neighbours in 3x3 + a padded
        % area
        if BW(sp_x(k,1),sp_x(k,2)-1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1);  neighbours(index,2) = sp_x(k,2)-1; %0,-1
        end

        if BW(sp_x(k,1),sp_x(k,2)+1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1);  neighbours(index,2) = sp_x(k,2)+1; %0,+1
        end

        if BW(sp_x(k,1)-1,sp_x(k,2)) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-1;  neighbours(index,2) = sp_x(k,2); %-1,0
        end

        if BW(sp_x(k,1)+1,sp_x(k,2)) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+1;  neighbours(index,2) = sp_x(k,2); %+1,0
        end

        if BW(sp_x(k,1)-1,sp_x(k,2)-1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-1;  neighbours(index,2) = sp_x(k,2)-1; %-1,-1
        end

        if BW(sp_x(k,1)-1,sp_x(k,2)+1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-1;  neighbours(index,2) = sp_x(k,2)+1; %-1,+1
        end

        if BW(sp_x(k,1)+1,sp_x(k,2)-1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+1;  neighbours(index,2) = sp_x(k,2)-1; %+1,-1
        end
        
        if BW(sp_x(k,1)+1,sp_x(k,2)+1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+1;  neighbours(index,2) = sp_x(k,2)+1; %+1,+1        
        end
        
        %neighbours that are two pixels away but have priority
        if BW(sp_x(k,1),sp_x(k,2)-2) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1);  neighbours(index,2) = sp_x(k,2)-2; %0,-2        
        end

        if BW(sp_x(k,1),sp_x(k,2)+2) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1);  neighbours(index,2) = sp_x(k,2)+2; %0,+2        
        end
        
        if BW(sp_x(k,1)-2,sp_x(k,2)) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-2;  neighbours(index,2) = sp_x(k,2); %-2,0        
        end
        
        if BW(sp_x(k,1)+2,sp_x(k,2)) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+2;  neighbours(index,2) = sp_x(k,2); %+2,0        
        end

        if BW(sp_x(k,1)-2,sp_x(k,2)-1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-2;  neighbours(index,2) = sp_x(k,2)-1; %-2,-1        
        end

        if BW(sp_x(k,1)-2,sp_x(k,2)+1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)-2;  neighbours(index,2) = sp_x(k,2)+1; %-2,+1        
        end
        
        if BW(sp_x(k,1)+2,sp_x(k,2)-1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+2;  neighbours(index,2) = sp_x(k,2)-1; %+2,-1        
        end

        if BW(sp_x(k,1)+2,sp_x(k,2)+1) < 255
            index = index + 1;
            neighbours(index,1) = sp_x(k,1)+2;  neighbours(index,2) = sp_x(k,2)+1; %+2,+1        
        end
        
        % add the coordinates which are unique in priority order
        for i=1:index
            if (C(neighbours(i,1),neighbours(i,2))~=0)
                sp_x(k+1,1) = neighbours(i,1);
                sp_x(k+1,2) = neighbours(i,2);                
                k = k+1;
                C(neighbours(i,1),neighbours(i,2)) = 0;
                break; 
            end
        end
    
    end % end of if

    curr_size=size(sp_x,1);
    if curr_size == prev_size
          %-----------------------
          % find unique points
            index = 1; newX = 0; newY = 0;
            for i=1:size(sp_x,1)
                pX = sp_x(i,1); pY = sp_x(i,2);
                count = 0;
                for j=1:size(sp_x,1)
                    if pX == sp_x(j,1) && pY == sp_x(j,2)
                        count = count + 1;
                        if count > 1
                           sp_x(j,1) = -1; sp_x(j,2) = -1;   
                        end
                    end
                end
                if pX ~= -1 && pY ~= -1
                    newX(index) = pX; newY(index) = pY;
                    index = index + 1;
                end    
            end
            clear sp_x;
            sp_x(:,1) = newX'; sp_x(:,2) = newY';
            curr_size=size(sp_x,1); k = size(sp_x,1);
            %------------------------       
          
          if (curr_size + 0) < size(xx,1)            
              % retry to get the boundary
              for i=1:size(xx,1)
                  cX = xxTemp(i);  cY = yyTemp(i);
                  for j=1:size(sp_x,1)
                       if cX == sp_x(j,1) && cY == sp_x(j,2) 
                           xxTemp(i) = 1000; yyTemp(i) = 1000;
                           break;
                       end
                  end
              end
              
              distX = abs(xxTemp - sp_x(k,1));
              distY = abs(yyTemp - sp_x(k,2));
              tDist = abs(distX + distY);           
              minT = tDist(1);
              rIndex = 1;
              for i=1:size(distX,1)
                  if minT > tDist(i)
                        rIndex = i;
                        minT = tDist(i);
                  end          
              end
              sp_x(k+1,1) = xxTemp(rIndex);
              sp_x(k+1,2) = yyTemp(rIndex);                
              k = k+1;             
          else
            break;
        end
    end
    
    neighbours = 0;
end % end of while









Contact us at files@mathworks.com