% %
% % HISTORY
%   2001 Philip Torr (philtorr@microsoft.com, phst@robots.ac.uk) at Microsoft
%   Created.
% 
%  Copyright © Microsoft Corp. 2002
%
%
% REF:	"A combined corner and edge detector", C.G. Harris and M.J. Stephens
%	Proc. Fourth Alvey Vision Conf., Manchester, pp 147-151, 1988.
%
%%to do: we might want to make this so it can either take a threshold or a fixed number of corners...
% 
% c_coord is the n x 2 x,y position of the corners
% im is the image as a matrix
% width is the width of the smoothing function
% sigma is the smoothing sigma
% subpixel = 1 for subpixel results (not implemented yet)

%%%%%bugs fixed Jan 2003
    
function [c_coord] = torr_charris(im, ncorners, width, sigma, subpixel)


if (nargin < 2)
    error('not enough input in  charris');
elseif (nargin ==2)
    width = 3; %default
    sigma = 1;
end

if (nargin < 5)
    subpixel = 0;
end

mask = [-1 0 1; -1 0 1; -1 0 1] / 3;

% compute horizontal and vertical gradients
%%note because of the way Matlab does this Ix and Iy will be 2 rows and columns smaller than im
Ix = conv2(im, mask, 'valid');
Iy = conv2(im, mask', 'valid');

% compute squares amd product
Ixy = Ix .* Iy;
Ix2 = Ix.^2;
Iy2 = Iy.^2;
Ixy2 = Ixy .^2;

% smooth them
gmask = torr_gauss_mask(width, sigma);

%gim = conv2(im, gmask, 'valid');
%%note because of the way Matlab does this Ix and Iy will be width*2 rows and columns smaller than Ix2,
% for a total of (1 + width)*2 smaller than im.
GIx2 = conv2(Ix2, gmask, 'valid');
GIy2 = conv2(Iy2, gmask, 'valid');
GIxy2 = conv2(Ixy2, gmask, 'valid');

% computer cornerness
% c = (GIx2 + GIy2) ./ (GIx2 .* GIy2 - GIxy2 + 1.0);
  
 %%%one problem is that this could be negative for certain images.
c = (GIx2 + GIy2) - 0.04 * (GIx2 .* GIy2 - GIxy2.^2);
%figure
%imagesc(c);
%figure
%c is smaller than before got border of 2 taken off all round
%size(c)

%compute max value around each pixel
%cmin = imorph(c, ones(3,3), 'min');
%assuming that the values in c are all positive,
%this returns the max value at that pixel if it is a local maximum,
%otherwise we return an arbitrary negative value
cmax = torr_max3x3(double(c));

%
% if pixel equals max, it is a local max, find index, 
ci3 = find(c == cmax);
cs3 = c(ci3);

[cs2,ci2] = sort(cs3); %ci2 2 is an index into ci3 which is an index into c


%put strongest ncorners corners in a list cs together with indices ci

l = length(cs2)
lb = max(1,l-ncorners+1);

cs = cs2(lb:l);
ci2s = ci2(lb:l);

ci = ci3(ci2s);

corn_thresh = cs(1);

disp(corn_thresh);


%row and column of each corner

[nrows, ncols] = size(c);

%plus four for border
%   c_row = rem(ci,nrows) +4;
%   c_col = ( ci - c_row )/nrows + 1 +4;
border = 1 + width;
c_row = rem(ci,nrows) + border;
c_col = ( ci - c_row  +2)/nrows + 1 + border;

%   %to convert to x,y we need to convert from rows to y
c_coord = [c_col c_row];


%see Nister's thesis page 19.
if subpixel
    disp('subpixel not done yet')
end















%display corners....
%hold on

%		plot(c_col, c_row, '+');
%		plot(c_coord(:,1), c_coord(:,2), '+');
% hold off
%index runs
% 1 4 
% 2 5\
% 3 6 

%ci = ci + 4 * nrows + 4;
%ci = (nrows + 4) * 4 + 4 + ci;
%c_patches = [gim(ci - nrows) gim(ci - nrows-1) gim(ci - nrows+1) gim(ci-1) gim(ci) gim(ci+1) gim(ci+nrows) gim(ci+nrows+1) gim(ci+nrows-1)];


%   hold on
%   	imagesc(im);
%		plot(c_col, c_row, 'sw')
%  hold off


%  	size(im)
% 		size(cp)

%		imr =   im2col(im, [5,5])';
%		im_corr = imr(ci);
%  	im(c_row(:)-1, c_col(:)-1) 
%		each row is a 3x3 matrix
%    	c_patches = [ im(c_row-1, c_col-1) im(c_row-1, c_col) im(c_row-1, c_col+1) ...
%          im(c_row, c_col-1) im(c_row, c_col) im(c_row, c_col+1) ...
%          im(c_row+1, c_col-1) im(c_row+1, c_col) im(c_row+1, c_col+1) ];

%c_patches = [im(ci-1) im(ci) im(ci+1)];

%c_patches = [im(ci)];

