% %
% % 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)];