5

ゴンザレスfrdescp関数を使用して、境界のフーリエ記述子を取得しています。このコードを使用すると、まったく異なる 2 つの数値セットが得られ、2 つの同一であるがスケール形状が異なります。

では、何が問題なのですか?

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

同一の、しかし縮尺が異なる 2 つの円に対して異なる記述子を取得するのはなぜですか?

4

2 に答える 2

6

問題は、フーリエ記述子を中央に配置するためにfrdescpコード(私はこのコードを使用しました。これはあなたが参照したものと同じはずです)も書かれていることです。

形状を正しい方法で記述したい場合は、DC コンポーネントを表す記述子に対して対称な記述子をいくつか維持することが必須です。

次の図は、概念をまとめたものです。

重要度の低い記述子のカットオフ

あなたの問題 (およびあなたの問題) を解決するために、次の 2 つの関数を作成しました。

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);
于 2014-05-19T15:01:40.713 に答える
2

私はあなたと同じ問題を経験しました。

このリンクによると、スケーリングに不変が必要な場合は、たとえば、すべてのフーリエ係数を DC 係数で除算して、比較を比率のようにします。f* 1 = f 1 /f[0]、f*[2]/f[0] など。したがって、コード内の f(1) が実際の DC 係数ではない DC 係数を使用する必要があります。 . 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
于 2014-12-09T18:53:07.527 に答える