====== Radial Frequency Contours ======
===== Radial Frequency Contour (RFC) Theory =====
Radial Frequency Contours (RFCs, or sometimes termed Fourier Descriptors (FDs)) allows for the parameterization of any closed contour. They were first described here:
* Zahn, C. T., Roskies, R. Z., March 1972. Fourier descriptors for plane closed curves. IEEE Transactions on Computers C-21 (3), 269-281.
RFCs allow you to describe any closed contour shape with a series of values which progressively define the shape, by interpreting the outline of the shape as a waveform which is then broken down into [[http://en.wikipedia.org/wiki/Fourier_Transform | Fourier components]].
To do this, one first normalizes the arc length of the shape to 2π. You choose an (arbitrary) starting point on the contour, and plot //t// vs. //Φ//, where //t// is ranging from 0 to 2π as you progress around the shape, and //Φ// is the curve direction at each point. This creates a function relating cumulative arc length to local contour orientation.
{{public:stimuli:bendfunction.png}}
This function is then expanded into a Fourier series. Each of the terms in this expansion represent the amplitude and phase of a particular frequency. The resulting RFCs completely (in the limit) describe the shape - but is invariant over changes in position and size. By looking at only high-order vs. low-order terms, one can break the shape down into low and high frequency details.
An alternative (and often computationally easier) method is to create a function of the radius as a function of angle:
{{public:stimuli:rfcanim.gif|}}
===== Drawing RFCs =====
RFCs are useful for generation of parameterized shapes. Given a RFC series, one can reconstruct the original shape:
function theta = cumubend(t, FD)
% THETA = CUMUBEND(T,FD)cumulative angular bend function.
% FD rows are frequency components 1, 2, 3...; column 1 is amplitude, 2 is phase
% returns the THETA value of the cumulative angular bend function at T
% Feb 2007 dmd, as described by Zahn et al.
theta = -t;
for freq = 1:length(FD(:,1)),
amp = FD(freq,1);
phase = FD(freq,2) /180*pi;
theta = theta + amp * (cos(freq * t - phase));
end
function points = cumubend2points(FD,steps)
% POINTS = CUMUBEND2POINTS(FD,STEPS)
% FD rows are frequency components 1, 2, 3...; column 1 is amplitude, 2 is phase
% STEPS corresponds to the precision with which to calculate the shape
% returns POINTS, a vector of complex numbers representing the position of each point
points = [0];
thispoint = [0];
for t = linspace(0,2*pi,steps)
bendangle = cumubend(t,FD);
nextpoint = cos(bendangle) + sqrt(-1) * sin(bendangle) + thispoint;
points = [points nextpoint];
thispoint = nextpoint;
end
//note that i use sqrt(-1) above because there's something wacky with the syntax highlighter on this wiki that breaks when I say 'i' //
==== Example ====
>> f = [0 0; 0.5 0; 0 0; 0.5 0; 0 0; 1 90];
>> plot(cumubend2points(f,2000));
>> axis off; axis equal;
{{public:stimuli:demofd.png?400 }}
==== non-integer frequencies ====
|{{:public:stimuli:dioctodb-10.png?125x125}}|The 'popcorn' style RFC shapes that [[http://www.ncbi.nlm.nih.gov/pubmed/19176637|Drucker and Aguirre (2009)]] used were created using [[https://github.com/dmd/thesis/|code]] modified from [[http://ppw.kuleuven.be/~odbeeckh/|Op de Beeck]]. It's a fair bit more complex than the above, as it uses non-integer frequencies to make the list of necessary frequencies shorter.|
====== RFCs in vision ======
* [[http://www.citeulike.org/user/dmd/tag/fourierdescriptors | various papers using RFCs]]