[37] | 1 | % %
|
---|
| 2 | % % HISTORY
|
---|
| 3 | % 2001 Philip Torr (philtorr@microsoft.com, phst@robots.ac.uk) at Microsoft
|
---|
| 4 | % Created.
|
---|
| 5 | %
|
---|
| 6 | % Copyright © Microsoft Corp. 2002
|
---|
| 7 | %
|
---|
| 8 | %
|
---|
| 9 | % REF: "A combined corner and edge detector", C.G. Harris and M.J. Stephens
|
---|
| 10 | % Proc. Fourth Alvey Vision Conf., Manchester, pp 147-151, 1988.
|
---|
| 11 | %
|
---|
| 12 | %%to do: we might want to make this so it can either take a threshold or a fixed number of corners...
|
---|
| 13 | %
|
---|
| 14 | % c_coord is the n x 2 x,y position of the corners
|
---|
| 15 | % im is the image as a matrix
|
---|
| 16 | % width is the width of the smoothing function
|
---|
| 17 | % sigma is the smoothing sigma
|
---|
| 18 | % subpixel = 1 for subpixel results (not implemented yet)
|
---|
| 19 |
|
---|
| 20 | %%%%%bugs fixed Jan 2003
|
---|
| 21 |
|
---|
| 22 | function [c_coord] = torr_charris(im, ncorners, width, sigma, subpixel)
|
---|
| 23 |
|
---|
| 24 |
|
---|
| 25 | if (nargin < 2)
|
---|
| 26 | error('not enough input in charris');
|
---|
| 27 | elseif (nargin ==2)
|
---|
| 28 | width = 3; %default
|
---|
| 29 | sigma = 1;
|
---|
| 30 | end
|
---|
| 31 |
|
---|
| 32 | if (nargin < 5)
|
---|
| 33 | subpixel = 0;
|
---|
| 34 | end
|
---|
| 35 |
|
---|
| 36 | mask = [-1 0 1; -1 0 1; -1 0 1] / 3;
|
---|
| 37 |
|
---|
| 38 | % compute horizontal and vertical gradients
|
---|
| 39 | %%note because of the way Matlab does this Ix and Iy will be 2 rows and columns smaller than im
|
---|
| 40 | Ix = conv2(im, mask, 'valid');
|
---|
| 41 | Iy = conv2(im, mask', 'valid');
|
---|
| 42 |
|
---|
| 43 | % compute squares amd product
|
---|
| 44 | Ixy = Ix .* Iy;
|
---|
| 45 | Ix2 = Ix.^2;
|
---|
| 46 | Iy2 = Iy.^2;
|
---|
| 47 | Ixy2 = Ixy .^2;
|
---|
| 48 |
|
---|
| 49 | % smooth them
|
---|
| 50 | gmask = torr_gauss_mask(width, sigma);
|
---|
| 51 |
|
---|
| 52 | %gim = conv2(im, gmask, 'valid');
|
---|
| 53 | %%note because of the way Matlab does this Ix and Iy will be width*2 rows and columns smaller than Ix2,
|
---|
| 54 | % for a total of (1 + width)*2 smaller than im.
|
---|
| 55 | GIx2 = conv2(Ix2, gmask, 'valid');
|
---|
| 56 | GIy2 = conv2(Iy2, gmask, 'valid');
|
---|
| 57 | GIxy2 = conv2(Ixy2, gmask, 'valid');
|
---|
| 58 |
|
---|
| 59 | % computer cornerness
|
---|
| 60 | % c = (GIx2 + GIy2) ./ (GIx2 .* GIy2 - GIxy2 + 1.0);
|
---|
| 61 |
|
---|
| 62 | %%%one problem is that this could be negative for certain images.
|
---|
| 63 | c = (GIx2 + GIy2) - 0.04 * (GIx2 .* GIy2 - GIxy2.^2);
|
---|
| 64 | %figure
|
---|
| 65 | %imagesc(c);
|
---|
| 66 | %figure
|
---|
| 67 | %c is smaller than before got border of 2 taken off all round
|
---|
| 68 | %size(c)
|
---|
| 69 |
|
---|
| 70 | %compute max value around each pixel
|
---|
| 71 | %cmin = imorph(c, ones(3,3), 'min');
|
---|
| 72 | %assuming that the values in c are all positive,
|
---|
| 73 | %this returns the max value at that pixel if it is a local maximum,
|
---|
| 74 | %otherwise we return an arbitrary negative value
|
---|
| 75 | cmax = torr_max3x3(double(c));
|
---|
| 76 |
|
---|
| 77 | %
|
---|
| 78 | % if pixel equals max, it is a local max, find index,
|
---|
| 79 | ci3 = find(c == cmax);
|
---|
| 80 | cs3 = c(ci3);
|
---|
| 81 |
|
---|
| 82 | [cs2,ci2] = sort(cs3); %ci2 2 is an index into ci3 which is an index into c
|
---|
| 83 |
|
---|
| 84 |
|
---|
| 85 | %put strongest ncorners corners in a list cs together with indices ci
|
---|
| 86 |
|
---|
| 87 | l = length(cs2)
|
---|
| 88 | lb = max(1,l-ncorners+1);
|
---|
| 89 |
|
---|
| 90 | cs = cs2(lb:l);
|
---|
| 91 | ci2s = ci2(lb:l);
|
---|
| 92 |
|
---|
| 93 | ci = ci3(ci2s);
|
---|
| 94 |
|
---|
| 95 | corn_thresh = cs(1);
|
---|
| 96 |
|
---|
| 97 | disp(corn_thresh);
|
---|
| 98 |
|
---|
| 99 |
|
---|
| 100 | %row and column of each corner
|
---|
| 101 |
|
---|
| 102 | [nrows, ncols] = size(c);
|
---|
| 103 |
|
---|
| 104 | %plus four for border
|
---|
| 105 | % c_row = rem(ci,nrows) +4;
|
---|
| 106 | % c_col = ( ci - c_row )/nrows + 1 +4;
|
---|
| 107 | border = 1 + width;
|
---|
| 108 | c_row = rem(ci,nrows) + border;
|
---|
| 109 | c_col = ( ci - c_row +2)/nrows + 1 + border;
|
---|
| 110 |
|
---|
| 111 | % %to convert to x,y we need to convert from rows to y
|
---|
| 112 | c_coord = [c_col c_row];
|
---|
| 113 |
|
---|
| 114 |
|
---|
| 115 | %see Nister's thesis page 19.
|
---|
| 116 | if subpixel
|
---|
| 117 | disp('subpixel not done yet')
|
---|
| 118 | end
|
---|
| 119 |
|
---|
| 120 |
|
---|
| 121 |
|
---|
| 122 |
|
---|
| 123 |
|
---|
| 124 |
|
---|
| 125 |
|
---|
| 126 |
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 |
|
---|
| 130 |
|
---|
| 131 |
|
---|
| 132 |
|
---|
| 133 |
|
---|
| 134 | %display corners....
|
---|
| 135 | %hold on
|
---|
| 136 |
|
---|
| 137 | % plot(c_col, c_row, '+');
|
---|
| 138 | % plot(c_coord(:,1), c_coord(:,2), '+');
|
---|
| 139 | % hold off
|
---|
| 140 | %index runs
|
---|
| 141 | % 1 4
|
---|
| 142 | % 2 5\
|
---|
| 143 | % 3 6
|
---|
| 144 |
|
---|
| 145 | %ci = ci + 4 * nrows + 4;
|
---|
| 146 | %ci = (nrows + 4) * 4 + 4 + ci;
|
---|
| 147 | %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)];
|
---|
| 148 |
|
---|
| 149 |
|
---|
| 150 | % hold on
|
---|
| 151 | % imagesc(im);
|
---|
| 152 | % plot(c_col, c_row, 'sw')
|
---|
| 153 | % hold off
|
---|
| 154 |
|
---|
| 155 |
|
---|
| 156 | % size(im)
|
---|
| 157 | % size(cp)
|
---|
| 158 |
|
---|
| 159 | % imr = im2col(im, [5,5])';
|
---|
| 160 | % im_corr = imr(ci);
|
---|
| 161 | % im(c_row(:)-1, c_col(:)-1)
|
---|
| 162 | % each row is a 3x3 matrix
|
---|
| 163 | % c_patches = [ im(c_row-1, c_col-1) im(c_row-1, c_col) im(c_row-1, c_col+1) ...
|
---|
| 164 | % im(c_row, c_col-1) im(c_row, c_col) im(c_row, c_col+1) ...
|
---|
| 165 | % im(c_row+1, c_col-1) im(c_row+1, c_col) im(c_row+1, c_col+1) ];
|
---|
| 166 |
|
---|
| 167 | %c_patches = [im(ci-1) im(ci) im(ci+1)];
|
---|
| 168 |
|
---|
| 169 | %c_patches = [im(ci)];
|
---|
| 170 |
|
---|