2012-04-01 107 views
5

我使用Gonzalez frdescp函数来获得边界的傅里叶描述符。我使用这个代码,并且我得到了两组完全不同的数字,它们描述了两个相同但不同的比例形状。Matlab fourier描述符有什么问题?

那又怎么了?

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); 

为什么我会得到不同的描述符为相同 - 但规模不同 - 两个圆?

+0

您从哪里得到了frdescp?它可能是问题的根源 – Rasman 2012-04-02 16:38:44

+0

我从冈萨雷斯的数字图像处理MATLAB书中得到它,其实我认为bwboundaries是问题! – 2012-04-09 08:40:03

+0

我编辑了[我以前的答案](http://stackoverflow.com/a/23741097/738017),我希望它对你和其他用户有用。 – 2014-05-22 17:08:13

回答

6

问题是frdescp代码(我使用this code,应该与您所提到的相同)也是为了使傅立叶描述符居中。

如果要以正确的方式描述形状,必须保留一些与表示DC分量的描述符相对称的描述符。

下图总结了概念:

Cut-off of less significant descriptors

为了解决你的问题(和其他像你),我写了下面两种功能:

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 

知道,你可以使用上述功能如下:

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); 
2

我刚刚和你一起经历过同样的问题。

根据这个link,如果你想要不变的比例,比如通过将每个傅立叶系数除以DC系数。 f * 1 = f 1/f [0],f * [2]/f [0]等等。因此,您需要使用DC系数,其中代码中的f(1)不是在步骤“f = f(2:20)之后的实际DC系数;获得第一个删除直流分量的第一个20” 。我认为问题可以通过首先保持DC系数的值来解决,调整后的代码应该如下所示:

% 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