====== 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]]