Wyświetlenie rezultatu transformaty w oknie

0

Witam,
Mam problem ze zrozumieniem działania FFT w c++ z biblioteki fftw3.
Otóż wkładam do funkcji sinusa i nie wiem dokładnie jak mam go wyświetlić w oknie w Qt.
Wykres x: czas, y: amplituda.
Oto jak to robię, ale nie podoba mi się to co pokazuje mi się w oknie.
Pytanie o poprawność działania umieszczone w kodzie.

int f = 100; //częstotliwość
int N = x/f; //ilość próbek   x-czas trwania sygnału
QSplineSeries *FFTW = new QSplineSeries;
QSplineSeries *FFTW1 = new QSplineSeries;

fftw_complex signal[N];
fftw_complex result[N];

fftw_plan plan = fftw_plan_dft_1d(N, signal, result, FFTW_FORWARD, FFTW_ESTIMATE);

for(int i=0; i<N; i++)
{
     signal[i-54][0] = sinus[i]; //RE  sinus[i] to tablica sinusa
     signal[i-54][1] = 0.0; //IM
 }

fftw_execute(plan);

for(int i=0; i<N; i++)
{
      FFTW->append(1/f*i, result[i][0]); //czy tak poprawnie wyświetlać wykres otrzymanego wyniku FFT?
}

fftw_destroy_plan(plan);

Robiłem kiedyś FFT w matlabie, ale tam od razu wypluwał wynik, który można było wyświetlić, a tutaj po prostu nie wiem jak to zrobić.

0
for(int i=0; i<N; i++)
{
     signal[i-54][0] = sinus[i]; //RE  sinus[i] to tablica sinusa
     signal[i-54][1] = 0.0; //IM
 }

Piszesz po zmiennych definiowanych przed zmienną signal (ujemne indeksy -54, -53). Java od razu by Ci zasygnalizowała ArrayIndexOutOfBoundsException, a C/C++ to można sobie "ziazi" zrobić. Trudno zatem ocenić jaki sygnał poddajesz FFT.

0

A tak przekopiowałem to z przykładu innego.
Ale chodzi mi dokładnie o wyświetlenie wyniku. Jak mam go poprawnie interpretować, aby mieć poprawny wykres.

1

Rezultat FFT to dyskretne prążki widma w postaci liczb zespolonych, czyli jeśli w signal[i] masz funkcję harmoniczną A*sin(2*PI*i/N+fi) dla i = 0..N-1 czyli dokładnie jeden okres sinusa to w result[1] powinna być liczba zespolona opisująca tę harmoniczną czyli moduł i fazę, dla pozostałych i w result będziesz miał śmieci tzn. małe wartości, które w teorii powinny być równe zero ( trzeba jednak sprawdzić w dokumentacji bo funkcje FFT umieszczają także widmo w zakresie częstotliwości od -N/2 do N/2). Najczęściej robi się wykres widma amplitudowego (moduł w funkcji częstotliwości) czyli dla prążka i będzie to sqrt(result[i][0]*result[i][0]+result[i][1]*result[i][1]). Widmo fazowe to argument liczby zespolonej. Najlepiej skorzystać z jakiejś biblioteki, która robi transformacje z układu biegunowego na kartezjański.

0

No tak. Zgodnie z twoim opisem dla

for(int i=0; i<N; i++)
{
      signal[i][0] = (4*sin(4*2*3.14*i) + sin(100*2*3.14*i + 1))+10;
      signal[i][1] = 0.0;
}
...

fftw_execute(plan);
...

for(int i=0; i<N; i++)
{
      FFTW->append(1/f*i, std::sqrt(result[i][0]*result[i][0] + result[i][1]*result[i][1])); 
}

Powinienem widzieć na wykresie widzieć prążek dla sinusa i cosinusa.

Dobrze zrozumiałem, że tłumaczysz zasadę powstawania takiego wykresu?
https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/FFT_of_Cosine_Summation_Function.png/800px-FFT_of_Cosine_Summation_Function.png

Bo właśnie o coś takiego mi chodzi, ale czytając dokumentację FFTW nie mogę do tego dojść, coś źle rozumuję.
https://upload.wikimedia.org/wikipedia/commons/6/61/FFT-Time-Frequency-View.png

1

Oba rysunki pokazują to samo w sensie zasady, tylko w innej formie. Dla tego sygnału z Twojego ostatniego posta dostaniesz składową stałą (result[0]), 4 i 100 harmoniczną, po warunkiem, że N >= 200 (częstotliwość próbkowania musi być co najmniej 2 razy większa od największej częstotliwości harmonicznych w sygnale - twierdzenie Kotielnikowa-Shanona). Na wykresie amplitudowym nie zobaczysz różnicy miedzy sinusem i cosinusem, różnią się tylko fazą, więc trzeba popatrzeć na fazę. Jeśli 100 harmoniczna miała być cosinusem to powinno być sin(100*2*PI*i+PI/2). No i żeby wyszły takie ładne wykresy to trzeba jeszcze dobrać N, aby było potęgą dwójki, wszystkie FFT pracują na takich długościach i jeśli N sygnału nie jest potęgą dwójki to dopełniają zerami.

0

No okej, wydaje mi się że wszystko rozumiem.
Ale otrzymuję coś takiego:

1

Masz ujemne amplitudy, a powinny być dodatnie, coś nie tak z liczeniem modułu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1