Skip to content

Instantly share code, notes, and snippets.

@tonyfast
Created October 13, 2014 18:48
Show Gist options
  • Select an option

  • Save tonyfast/ffc1c2966f96f98cae6a to your computer and use it in GitHub Desktop.

Select an option

Save tonyfast/ffc1c2966f96f98cae6a to your computer and use it in GitHub Desktop.
Vectorized Fast Radial Symmetric Transform on Image Data. Adopted from http://www.csse.uwa.edu.au/~pk/Research/MatlabFns/Spatial/fastradial.m
% FASTRADIAL - Loy and Zelinski's fast radial feature detector
%
% An implementation of Loy and Zelinski's fast radial feature detector
%
% Usage: S = fastradial(im, radii, alpha, beta)
%
% Arguments:
% im - Image to be analysed
% radii - Array of integer radius values to be processed
% suggested radii might be [1 3 5]
% alpha - Radial strictness parameter.
% 1 - slack, accepts features with bilateral symmetry.
% 2 - a reasonable compromise.
% 3 - strict, only accepts radial symmetry.
% ... and you can go higher
% beta - Gradient threshold. Gradients below this threshold do
% not contribute to symmetry measure, defaults to 0.
%
% Returns S - Symmetry map. Bright points with high symmetry are
% marked with large positive values. Dark points of
% high symmetry marked with large -ve values.
%
% To localize points use NONMAXSUPPTS on S, -S or abs(S) depending on
% what you are seeking to find.
% Reference:
% Loy, G. Zelinsky, A. Fast radial symmetry for detecting points of
% interest. IEEE PAMI, Vol. 25, No. 8, August 2003. pp 959-973.
% Copyright (c) 2004-2010 Peter Kovesi
% Centre for Exploration Targeting
% The University of Western Australia
% http://www.csse.uwa.edu.au/~pk/research/matlabfns/
%
% 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.
% November 2004 - original version
% July 2005 - Bug corrected: magitude and orientation matrices were
% not zeroed for each radius value used (Thanks to Ben
% Jackson)
% December 2009 - Gradient threshold added + minor code cleanup
% July 2010 - Gradients computed via Farid and Simoncelli's 5 tap
% derivative filters
function [S, So] = fastradial(im, radii, alpha, beta, feedback)
if ~exist('beta','var'), beta = 0; end
if ~exist('feedback','var'), feedback = 0; end
if any(radii ~= round(radii)) || any(radii < 1)
error('radii must be integers and > 1')
end
[rows,cols]=size(im);
% Compute derivatives in x and y via Farid and Simoncelli's 5 tap
% derivative filters
[imgx, imgy] = derivative5(im, 'x', 'y');
mag = sqrt(imgx.^2 + imgy.^2)+eps; % (+eps to avoid division by 0)
% Normalise gradient values so that [imgx imgy] form unit
% direction vectors.
imgx = imgx./mag;
imgy = imgy./mag;
S = zeros(rows,cols,numel(radii)); % Symmetry matrix
So = zeros(rows,cols,numel(radii)); % Orientation only symmetry matrix
[x,y] = meshgrid(1:cols, 1:rows);
for n = radii
M = zeros(rows,cols); % Magnitude projection image
O = zeros(rows,cols); % Orientation projection image
% Coordinates of 'positively' and 'negatively' affected pixels
posx = x + round(n*imgx);
posy = y + round(n*imgy);
negx = x - round(n*imgx);
negy = y - round(n*imgy);
% Clamp coordinate values to range [1 rows 1 cols]
posx( posx<1 ) = 1;
posx( posx>cols ) = cols;
posy( posy<1 ) = 1;
posy( posy>rows ) = rows;
negx( negx<1 ) = 1;
negx( negx>cols ) = cols;
negy( negy<1 ) = 1;
negy( negy>rows ) = rows;
I = sub2ind( [rows,cols], posy, posx);
O(:) = accumarray( I(:), ones(size(I(:))), [prod([rows,cols]),1], @sum);
M(:) = accumarray( I(:), mag(:), [prod([rows,cols]),1], @sum);
I(:) = sub2ind( [rows,cols], negy, negx);
O(:) = O(:) - accumarray( I(:), ones(size(I(:))), [prod([rows,cols]),1], @sum);
M(:) = M(:) - accumarray( I(:), mag(:), [prod([rows,cols]),1], @sum);
% Clamp Orientation projection matrix values to a maximum of
% +/-kappa, but first set the normalization parameter kappa to the
% values suggested by Loy and Zelinski
if n == 1, kappa = 8; else kappa = 9.9; end
O(O > kappa) = kappa;
O(O < -kappa) = -kappa;
% Unsmoothed symmetry measure at this radius value
F = M./kappa .* (abs(O)/kappa).^alpha;
Fo = sign(O) .* (abs(O)/kappa).^alpha; % Orientation only based measure
% Smooth and spread the symmetry measure with a Gaussian proportional to
% n. Also scale the smoothed result by n so that large scales do not
% lose their relative weighting.
S(:,:,n==radii) = gaussfilt(F, 0.25*n) * n;
So(:,:,n==radii) = gaussfilt(Fo, 0.25*n) * n;
end % for each radius
% S = S /length(radii); % Average
% So = So/length(radii);
@tonyfast

Copy link
Copy Markdown
Author

Peter Kovesi has generously provided MATLAB and Octave functions for Computer Vision and Image Processing; there are a lot functions from this toolbox I use frequently especially derivative7. The function is vectorized version of fastradial.m.

Example Use

I have used this function to find the fiber centers in micro-CT datasets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment