Дескрипторы Matlab Фурье, что не так? - PullRequest
5 голосов
/ 01 апреля 2012

Я использую функцию Гонсалеса 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);

Почему я получаю разные дескрипторы для одинаковых, но разных по масштабу двух кругов?

Ответы [ 2 ]

6 голосов
/ 19 мая 2014

Проблема в том, что код 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 голосов
/ 09 декабря 2014

Я только что прошел через ту же проблему с вами.

В соответствии с этой ссылкой , если вы хотите, чтобы инвариант масштабировался, сделайте коэффициент сравнения подобным, например, разделив каждый Фурьекоэффициент по DC-коэффициенту.f * 1 = f 1 / f [0], f * [2] / f [0] и так далее.Таким образом, вам нужно использовать DC-коэффициент, где f (1) в вашем коде не является фактическим DC-коэффициентом после вашего шага "f = f (2:20);% получения первых 20 и удаления компонента 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
...