Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matlab fourier descriptors what's wrong?

I am using Gonzalez frdescp function to get Fourier descriptors of a boundary. I use this code, and I get two totally different sets of numbers describing two identical but different in scale shapes.

So what is wrong?

im = imread('c:\classes\a1.png');
im = im2bw(im);
b = bwboundaries(im);
f = frdescp(b{1}); // fourier descriptors for the boundary of the first object ( my   pic only contains one object anyway )
// Normalization
f = f(2:20); // getting the first 20 & deleting the dc component
f = abs(f) ;
f = f/f(1);

Why do I get different descriptors for identical - but different in scale - two circles?

like image 528
Adham shafik Avatar asked Apr 01 '12 19:04

Adham shafik


People also ask

What are Fourier descriptors?

Fourier descriptors are derived from the Fourier series for the cumulative angular function of the cross-sectional boundary and are used to characterize shape complexity and other geometric attributes. Moreover, image-processing-based methods have been used for identifying different types of fibres in cross-section.

Why we use Fourier transform in Matlab?

The Fourier transform is a mathematical formula that transforms a signal sampled in time or space to the same signal sampled in temporal or spatial frequency. In signal processing, the Fourier transform can reveal important characteristics of a signal, namely, its frequency components.


2 Answers

The problem is that the frdescp code (I used this code, that should be the same as referred by you) is written also in order to center the Fourier descriptors.

If you want to describe your shape in a correct way, it is mandatory to mantain some descriptors that are symmetric with respect to the one representing the DC component.

The following image summarize the concept:

Cut-off of less significant descriptors

In order to solve your problem (and others like yours), I wrote the following two functions:

function descriptors = fourierdescriptor( boundary )
    %I assume that the boundary is a N x 2 matrix
    %Also, N must be an even number

    np = size(boundary, 1);

    s = boundary(:, 1) + i*boundary(:, 2);

    descriptors = fft(s);

    descriptors = [descriptors((1+(np/2)):end); descriptors(1:np/2)];
end

function significativedescriptors = getsignificativedescriptors( alldescriptors, num )
    %num is the number of significative descriptors (in your example, is was 20)
    %In the following, I assume that num and size(alldescriptors,1) are even numbers

    dim = size(alldescriptors, 1);

    if num >= dim
        significativedescriptors = alldescriptors;
    else
        a = (dim/2 - num/2) + 1;
        b = dim/2 + num/2;

        significativedescriptors = alldescriptors(a : b);
    end
end

Know, you can use the above functions as follows:

im = imread('test.jpg');
im = im2bw(im);
b = bwboundaries(im);
b = b{1};

%force the number of boundary points to be even
if mod(size(b,1), 2) ~= 0
    b = [b; b(end, :)];
end

%define the number of significative descriptors I want to extract (it must be even)
numdescr = 20;

%Now, you can extract all fourier descriptors...
f = fourierdescriptor(b);
%...and get only the most significative:
f_sign = getsignificativedescriptors(f, numdescr);
like image 86
Vito Gentile Avatar answered Sep 30 '22 01:09

Vito Gentile


I just went through the same problem with you.

According to this link, if you want invariant to scaling, make the comparison ratio-like, for example by dividing every Fourier coefficient by the DC-coefficient. f*1 = f1/f[0], f*[2]/f[0], and so on. Thus, you need to use the DC-coefficient where the f(1) in your code is not the actual DC-coefficient after your step "f = f(2:20); % getting the first 20 & deleting the dc component". I think the problem can be solved by keeping the value of the DC-coefficient first, the code after adjusted should be like follows:

% Normalization
DC = f(1);
f = f(2:20); % getting the first 20 & deleting the dc component
f = abs(f) ; % use magnitudes to be invariant to translation & rotation
f = f/DC; % divide the Fourier coefficients by the DC-coefficient to be invariant to scale
like image 44
Xiaoting Hong Avatar answered Sep 30 '22 02:09

Xiaoting Hong