Matlab傅里叶描述符有什么问题?

5

我正在使用Gonzalez的frdescp函数来获取边界的傅里叶描述符。我使用了这段代码,但是我得到了两组完全不同的数字来描述两个相同但比例不同的形状。

那么问题出在哪里呢?

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

为什么我拥有两个圆,它们的尺寸不同,但值却相同,却得到了不同的描述符?

你从哪里得到了frdescp?它可能是问题的源头。 - Rasman
我从Gonzaelz的使用MATLAB进行数字图像处理的书中得到了它,实际上我认为bwboundaries是问题所在! - Adham shafik
我编辑了我的先前回答,希望它对你和其他用户有用。 - Vito Gentile
2个回答

6
问题在于frdescp代码(我使用了此代码,应该与您所指的相同)也是为了将傅立叶描述符居中而编写的。
如果想要正确地描述形状,则必须保持一些关于表示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

我刚和你遇到同样的问题。

根据这个链接,如果想要保持不变性,可以将比较关系类似于比率,例如通过将每个傅里叶系数除以直流系数。f* 1 = f1/f[0],f*[2]/f[0],以此类推。因此,在你的代码中,当f(1)不是实际直流系数时,需要使用直流系数。在“f = f(2:20);%获取前20个并删除直流分量”的步骤之后。我认为问题可以通过先保留直流系数的值来解决,调整后的代码应该像下面这样:

% 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接