ECG-Kit 1.0
(13,590 bytes)
%IM_HARRIS Fixed mapping executing the Harris corner detector
%
% X = IM_HARRIS(A,N,SIGMA)
% X = A*IM_HARRIS([],N,SIGMA)
% X = A*IM_HARRIS(N,SIGMA)
%
% INPUT
% A Datafile or dataset with images
% N Number of desired Harris points per image (default 100)
% SIGMA Smoothing size (default 3)
%
% OUTPUT
% X Dataset with a [N,3] array with for every image
% x, y and strength per Harris point.
%
% DESCRIPTION
% We use Kosevi's [1] software to find the corner points according to
% Harris [2]. On top of the Kosevi Harris point detector we run
% - multi-feature images (e.g. color images) are averaged
% - only points that are maximum in a K x K window are selected.
% If less points are found, K is iteratively reduced.
% The initial value of K is about 4*SIGMA.
% Although SIGMA can be interpreted as scaling parameter, it might be
% better to appropriately subsample images instead of using a large SIGMA.
%
% If you use this software for publications, please refer to [1] and [2].
%
% REFERENCES
% [1] P. D. Kovesi, MATLAB and Octave Functions for Computer Vision and
% Image Processing, School of Computer Science & Software Engineering,
% The University of Western Australia. Available from:
% <http://www.csse.uwa.edu.au/~pk/research/matlabfns/>.
% [2] C. Harris and M. Stephens, A combined corner and edge detector,
% Proc. 4th Alvey Vision Conf., 1988, pp. 147-151.
%
% EXAMPLE
% delfigs
% a = kimia; % take simple shapesas example
% b = gendat(a,25)*im_gray; % just 25 images at random
% c = data2im(b); % convert dataset to images for display
% x = im_harris(b,15,1); % compute maximum 15 Harris points at scale 1
% y = data2im(x); % unpack dataset with results
% for j=1:25 % show results one by one
% figure(j); imagesc(c(:,:,1,j)); colormap gray; hold on
% scatter(y(:,1,1,j),y(:,2,1,j),'r*');
% end
% showfigs
function x = im_harris(varargin)
argin = shiftargin(varargin,'scalar');
argin = setdefaults(argin,[],100,3,[]);
if mapping_task(argin,'definition')
x = define_mapping(argin,'fixed');
x = setname(x,'Harris points');
else
[a,n,s,k] = deal(argin{:});
if isa(a,'prdataset') % allows datafiles too
isobjim(a);
a = im_gray(a);
x = filtim(a,mfilename,{n,s});
else
a = double(a);
if size(a,3) ~= 1
error('2D gray value image expected');
end
[mr,mc] = size(a); % here we put a border of 15 pixels around the image
aa = bord(a,NaN,15); % mirroring the border to avoid artificial corners
cc = harris(aa,s); % at the image border, finally we take the
c = resize(cc,15,mr,mc); % original image size (bord and resize are in ./private)
fsizes = [25,21,17,13,11,9,7,5,3];
F = find(fsizes < 4*s);
fsizes = fsizes(F);
for fsize = fsizes
shape = ones(fsize,fsize);
cmax = ordfilt2(c,fsize*fsize,shape);
J = find(cmax == c); % are a local maximum
[Iy,Ix] = ind2sub(size(c),J); % second attempt to get rid of image border points
K = find(Iy > 3 & Ix >3 & Iy < (mr-2) & Ix < (mc-2));
J = J(K);
Z = find(cmax(J) > 0); % find non-zeros only
J = J(Z);
if length(J) > n % if we have sufficient points
break; % stop
end % otherwise, get more local maxima
end
cs = cmax(J);
[ss,R] = sort(-cs); % rank Harris points
if length(J) >= n % find x,y coordinates of first n Harris points
[Iy,Ix] = ind2sub(size(c),J(R(1:n)));
x = [Ix, Iy, -ss(1:n)];
else
x = zeros(n,3);
[Iy,Ix] = ind2sub(size(c),J(R));
x(1:length(R),:) = [Ix, Iy, -ss(1:length(R))];
end
end
end
return
% HARRIS - Harris corner detector
%
% Usage: cim = harris(im, sigma)
% [cim, r, c] = harris(im, sigma, thresh, radius, disp)
% [cim, r, c, rsubp, csubp] = harris(im, sigma, thresh, radius, disp)
%
% Arguments:
% im - image to be processed.
% sigma - standard deviation of smoothing Gaussian. Typical
% values to use might be 1-3.
% thresh - threshold (optional). Try a value ~1000.
% radius - radius of region considered in non-maximal
% suppression (optional). Typical values to use might
% be 1-3.
% disp - optional flag (0 or 1) indicating whether you want
% to display corners overlayed on the original
% image. This can be useful for parameter tuning. This
% defaults to 0
%
% Returns:
% cim - binary image marking corners.
% r - row coordinates of corner points.
% c - column coordinates of corner points.
% rsubp - If five return values are requested sub-pixel
% csubp - localization of feature points is attempted and
% returned as an additional set of floating point
% coords. Note that you may still want to use the integer
% valued coords to specify centres of correlation windows
% for feature matching.
%
% If thresh and radius are omitted from the argument list only 'cim' is returned
% as a raw corner strength image. You may then want to look at the values
% within 'cim' to determine the appropriate threshold value to use. Note that
% the Harris corner strength varies with the intensity gradient raised to the
% 4th power. Small changes in input image contrast result in huge changes in
% the appropriate threshold.
% References:
% C.G. Harris and M.J. Stephens. "A combined corner and edge detector",
% Proceedings Fourth Alvey Vision Conference, Manchester.
% pp 147-151, 1988.
%
% Alison Noble, "Descriptions of Image Surfaces", PhD thesis, Department
% of Engineering Science, Oxford University 1989, p45.
% Copyright (c) 2002-2005 Peter Kovesi
% School of Computer Science & Software Engineering
% The University of Western Australia
% http://www.csse.uwa.edu.au/
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% The Software is provided "as is", without warranty of any kind.
% March 2002 - original version
% December 2002 - updated comments
% August 2005 - changed so that code calls nonmaxsuppts
function [cim, r, c, rsubp, csubp] = harris(im, sigma, thresh, radius, disp)
narginchk(2,5);
if nargin == 4
disp = 0;
end
if ~isa(im,'double')
im = double(im);
end
subpixel = nargout == 5;
dx = [-1 0 1; -1 0 1; -1 0 1]; % Derivative masks
dy = dx';
Ix = conv2(im, dx, 'same'); % Image derivatives
Iy = conv2(im, dy, 'same');
% Generate Gaussian filter of size 6*sigma (+/- 3sigma) and of
% minimum size 1x1.
g = fspecial('gaussian',max(1,fix(6*sigma)), sigma);
Ix2 = conv2(Ix.^2, g, 'same'); % Smoothed squared image derivatives
Iy2 = conv2(Iy.^2, g, 'same');
Ixy = conv2(Ix.*Iy, g, 'same');
% Compute the Harris corner measure. Note that there are two measures
% that can be calculated. I prefer the first one below as given by
% Nobel in her thesis (reference above). The second one (commented out)
% requires setting a parameter, it is commonly suggested that k=0.04 - I
% find this a bit arbitrary and unsatisfactory.
cim = (Ix2.*Iy2 - Ixy.^2)./(Ix2 + Iy2 + eps); % My preferred measure.
% k = 0.04;
% cim = (Ix2.*Iy2 - Ixy.^2) - k*(Ix2 + Iy2).^2; % Original Harris measure.
if nargin > 2 % We should perform nonmaximal suppression and threshold
if disp % Call nonmaxsuppts to so that image is displayed
if subpixel
[r,c,rsubp,csubp] = nonmaxsuppts(cim, radius, thresh, im);
else
[r,c] = nonmaxsuppts(cim, radius, thresh, im);
end
else % Just do the nonmaximal suppression
if subpixel
[r,c,rsubp,csubp] = nonmaxsuppts(cim, radius, thresh);
else
[r,c] = nonmaxsuppts(cim, radius, thresh);
end
end
end
return
% NONMAXSUPPTS - Non-maximal suppression for features/corners
%
% Non maxima suppression and thresholding for points generated by a feature
% or corner detector.
%
% Usage: [r,c] = nonmaxsuppts(cim, radius, thresh, im)
% /
% optional
%
% [r,c, rsubp, csubp] = nonmaxsuppts(cim, radius, thresh, im)
%
% Arguments:
% cim - corner strength image.
% radius - radius of region considered in non-maximal
% suppression. Typical values to use might
% be 1-3 pixels.
% thresh - threshold.
% im - optional image data. If this is supplied the
% thresholded corners are overlayed on this
% image. This can be useful for parameter tuning.
% Returns:
% r - row coordinates of corner points (integer valued).
% c - column coordinates of corner points.
% rsubp - If four return values are requested sub-pixel
% csubp - localization of feature points is attempted and
% returned as an additional set of floating point
% coords. Note that you may still want to use the integer
% valued coords to specify centres of correlation windows
% for feature matching.
%
% Note: An issue with integer valued images is that if there are multiple pixels
% all with the same value within distance 2*radius of each other then they will
% all be marked as local maxima.
% Copyright (c) 2003-2013 Peter Kovesi
% Centre for Exploration Targeting
% The University of Western Australia
% peter.kovesi at uwa edu au
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% The Software is provided "as is", without warranty of any kind.
% September 2003 Original version
% August 2005 Subpixel localization and Octave compatibility
% January 2010 Fix for completely horizontal and vertical lines (by Thomas Stehle,
% RWTH Aachen University)
% January 2011 Warning given if no maxima found
function [r,c, rsubp, csubp] = nonmaxsuppts(cim, radius, thresh, im)
subPixel = nargout == 4; % We want sub-pixel locations
[rows,cols] = size(cim);
% Extract local maxima by performing a grey scale morphological
% dilation and then finding points in the corner strength image that
% match the dilated image and are also greater than the threshold.
sze = 2*radius+1; % Size of dilation mask.
mx = ordfilt2(cim, sze^2,ones(sze)); % Grey-scale dilate.
% Make mask to exclude points within radius of the image boundary.
bordermask = zeros(size(cim));
bordermask(radius+1:end-radius, radius+1:end-radius) = 1;
% Find maxima, threshold, and apply bordermask
cimmx = (cim==mx) & (cim>thresh) & bordermask;
[r,c] = find(cimmx); % Find row,col coords.
if subPixel % Compute local maxima to sub pixel accuracy
if ~isempty(r) % ...if we have some ponts to work with
ind = sub2ind(size(cim),r,c); % 1D indices of feature points
w = 1; % Width that we look out on each side of the feature
% point to fit a local parabola
% Indices of points above, below, left and right of feature point
indrminus1 = max(ind-w,1);
indrplus1 = min(ind+w,rows*cols);
indcminus1 = max(ind-w*rows,1);
indcplus1 = min(ind+w*rows,rows*cols);
% Solve for quadratic down rows
rowshift = zeros(size(ind));
cy = cim(ind);
ay = (cim(indrminus1) + cim(indrplus1))/2 - cy;
by = ay + cy - cim(indrminus1);
rowshift(ay ~= 0) = -w*by(ay ~= 0)./(2*ay(ay ~= 0)); % Maxima of quadradic
rowshift(ay == 0) = 0;
% Solve for quadratic across columns
colshift = zeros(size(ind));
cx = cim(ind);
ax = (cim(indcminus1) + cim(indcplus1))/2 - cx;
bx = ax + cx - cim(indcminus1);
colshift(ax ~= 0) = -w*bx(ax ~= 0)./(2*ax(ax ~= 0)); % Maxima of quadradic
colshift(ax == 0) = 0;
rsubp = r+rowshift; % Add subpixel corrections to original row
csubp = c+colshift; % and column coords.
else
rsubp = []; csubp = [];
end
end
if nargin==4 && ~isempty(r) % Overlay corners on supplied image.
figure(1), imshow(im,[]), hold on
if subPixel
plot(csubp,rsubp,'r+'), title('corners detected');
else
plot(c,r,'r+'), title('corners detected');
end
hold off
end
if isempty(r)
warning('No maxima above threshold found\n');
end
return