2012-04-01 27 views
5

Tôi đang sử dụng hàm Gonzalez frdescp để lấy các mô tả Fourier của một đường biên. Tôi sử dụng mã này và tôi nhận được hai tập hợp số hoàn toàn khác nhau mô tả hai giống hệt nhau nhưng khác nhau về hình dạng tỷ lệ.Matlab fourier descriptors có gì sai?

Vậy có gì sai?

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

Tại sao tôi nhận được các trình mô tả khác nhau cho giống hệt nhau - nhưng khác về quy mô - hai vòng kết nối?

+0

bạn lấy frdescp từ đâu? nó có thể là nguồn gốc của vấn đề – Rasman

+0

Tôi nhận được nó từ xử lý hình ảnh kỹ thuật số của Gonzaelz bằng cách sử dụng cuốn sách MATLAB, thực sự tôi nghĩ rằng bwboundaries là vấn đề! –

+0

Tôi đã chỉnh sửa [câu trả lời trước của tôi] (http://stackoverflow.com/a/23741097/738017), tôi hy vọng nó có thể hữu ích cho bạn và những người dùng khác. –

Trả lời

6

Vấn đề là mã frdescp (tôi đã sử dụng this code, phải giống như được bạn giới thiệu) cũng được viết để căn giữa các bộ mô tả Fourier.

Nếu bạn muốn mô tả hình dạng của mình một cách chính xác, bắt buộc phải bảo đảm một số bộ mô tả đối xứng đối với mô tả đại diện cho thành phần DC.

Những hình ảnh sau đây tóm tắt các khái niệm:

Cut-off of less significant descriptors

Để giải quyết vấn đề của bạn (và những người khác như của bạn), tôi đã viết hai chức năng sau:

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 

Know, bạn có thể sử dụng các chức năng trên như sau:

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

Tôi vừa trải qua cùng một vấn đề với bạn.

Theo điều này link, nếu bạn muốn bất biến để chia tỷ lệ, hãy thực hiện tỷ lệ so sánh, ví dụ bằng cách chia mọi hệ số Fourier theo hệ số DC. f * 1 = f 1/f [0], f * [2]/f [0], v.v. Vì vậy, bạn cần phải sử dụng hệ số DC trong đó f (1) trong mã của bạn không phải là hệ số DC thực tế sau bước "f = f (2:20);% nhận được 20 & đầu tiên xóa thành phần dc" . Tôi nghĩ rằng vấn đề có thể được giải quyết bằng cách giữ giá trị của hệ số DC trước, mã sau khi điều chỉnh phải như sau:

% 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