我正在使用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);
为什么我会得到相同的不同描述符 - 但规模不同 - 两个圆圈?
答案 0 :(得分:6)
问题是frdescp
代码(我使用this code,应该与你引用的相同)也是为了使傅里叶描述符居中而写的。
如果你想以正确的方式描述你的形状,必须保留一些与代表DC分量的描述符对称的描述符。
下图总结了这个概念:
为了解决你的问题(和其他人一样),我写了以下两个函数:
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);
答案 1 :(得分:2)
我刚刚遇到了同样的问题。
根据这个link,如果你想要不变缩放,可以进行比较比例,例如将每个傅立叶系数除以DC系数。 f * 1 = f 1 / f [0],f * [2] / f [0],依此类推。因此,您需要使用直流系数,其中代码中的f(1)不是步骤“f = f(2:20)之后的实际直流系数;%得到前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