function [xc,yc]=contour(Ib)
%[xc,yc]=contour(Ib)
%
%Searches the boundary for an object in the binary image Ib.
%(where 1 is considered as object pixel), starting at the 
%first object pixel by scanning downwards each column from
%the left.
%
%xc and yc are the output boundary coordinates.
%

% Mats Kvarström 010110 modified 020123
% Modified 030121 by John Gustafsson

%%% Notation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (xc,yc): coordinates of boundary in image
% xx     : single index notation (i.e. xx = (xc-1)*Ny+yc)
% d      : denotes the position of a boundary pixel in relation to
%          the last boundary pixel in a counterclockwise manner,
%          such that
%                 d = | 0     | 1     | 2    | 3       
%          --------------------------------------------
%           came from | right | above | left | below
% i      : a counting index

[Ny,Nx] = size(Ib);

%%% Main program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% First Point
tmp    = find(Ib==1); % look up the positions of the 1's
xx(1)  = tmp(1);      % take the first element in this vector as start
d(1)   = 1; % ...as if we came from above   

% Second point
[xxnew,dnew] = next_cand(xx(1),d(1),Ib,Ny);
xx(2) = xxnew;
d(2)  = dnew;

% Third point
[xxnew,dnew] = next_cand(xx(2),d(2),Ib,Ny);

% And iterate...
i = 2;
while xx(i)~=xx(1) | xxnew~=xx(2)
  i  = i+1;
  xx(i) = xxnew;
  d(i)  = dnew;
  % next candidate
  [xxnew,dnew]=next_cand(xx(i),d(i),Ib,Ny);
end

% Convert from single index to ordinary coordinates
yc = mod(xx-1,Ny)+1;
xc = (xx-yc)/Ny+1;


%%% Subfunctions %%%%%%%%%%%%%%%%%%%d%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
function [xnew,dnew] = next_cand(x,d,I,Ny)
% find the next candidate for boundary pixel
dnew = mod(d+1,4);
xnew = move(x,dnew,Ny);
while I(xnew)~=1 
  % If xnew is not a part of the object then try 
  % the next neighbour:
  dnew = mod(dnew-1,4);
  xnew = move(x,dnew,Ny);
end

%%%
function xnew = move(x,d,Ny)
% Moves from x to xnew according to d
%
if d==0     % came from neigbour above: move to the right
  xnew = x+Ny;
elseif d==1 % came from neighbour to the right: move below
  xnew = x+1;
elseif d==2 % came from neighbour below: move to the left
  xnew = x-Ny;
else        % came form neighbour to the left: move up
  xnew = x-1;
end




