% LOCATELANDMARKS - locates landmarks on SURF form
%
% Usage:  [tl, tr, bl, br] = locatelandmarks(im)
%
% Argument: im - Image to be processed, assumed binary.
%
% Returns:  tl, tr, bl, br
%              - Coordinates of the centroids of the top-left, top-right,
%                bottom-left and bottom-right landmarks respectively.  
%                These coordinates are returned as column vectors in the
%                form [row; col] for each landmark.
%
% The function should also display the image with the centroids of the 
% landmarks overlayed.
function [tl, tr, bl, br] = locatelandmarks(im)
	
	[rows,cols] = size(im);
	
	% initially define landmark coordinates to extremes
	tl=[rows;cols];
	tr=[rows;0   ];
	bl=[0   ;cols];
	br=[0   ;0   ];
	
	bw = ~im;
    
	% Note: 8 pixels is the minimum space between landmarks and adjacent blobs
	%       (TR landmark, surf10.png with a size of 1128x784 pixels)
	%       Hence SE is proportional to im size, scaled by 8/784
    
    a = 8/784; %scale factor
    
	SE = ones(a*rows, a*cols);
	
	% perform close-open morphology
    % Note: a close-open resulted in the landmarks having strighter sides
    %       compared to open-close 
	closeopen = imopen(imclose(bw,SE),SE);
	
	% Matrix with each pixel set to its x coordinate
	x = ones(rows,1)*[1:cols];
	% Matrix with each pixel set to its y coordinate
	y = [1:rows]'*ones(1,cols);
	
	% label all the blobs
	[L, num] = bwlabel(closeopen);
	
	% search the blobs to find centers, and then landmarks
	for i = 1:num
        img = L==i;
        area(i) = sum(sum(img));
        meanx = sum(sum(double(img).*x))/area(i);
        meany = sum(sum(double(img).*y))/area(i);
        
        % determine tl
        if tl(1)+tl(2) > meanx + meany
            tl = [meanx; meany];
            tlindex = i;
        end
        % determine tr
        if tr(1)-tr(2) > meanx - meany
            tr = [meanx; meany];
            trindex = i;
        end
        % determine br
        if br(1)+br(2) < meanx + meany
            br = [meanx; meany];
            brindex = i;
        end
        % determine bl
        if bl(1)-bl(2) < meanx - meany
            bl = [meanx; meany];
            blindex = i;
        end
	end
	
	% test for upside down form
	% Note: tl > bl and tr > br for correctly orientated forms
	if area(tlindex) < area(blindex) && area(trindex) < area(brindex)
        'warning: upside down form'
        locatelandmarks(imrotate(im,180));
        
	else imshow(im)
        hold;
        landmarks = [tl, tr, br, bl];    
        plot(landmarks(1,:), landmarks(2,:),'+r','MarkerSize',50,'LineWidth',2);
        hold;
end