2016-08-07 4 views
2

Я борюсь с реализацией быстрого преобразования Фурье numpy. Мой сигнал не имеет периодического характера и, следовательно, не является идеальным кандидатом, результат БПФ, однако, далек от того, что я ожидал. Это тот же сигнал, просто растянутый на какой-то фактор. Я графике кривой пазухи, аппроксимирующих мой сигнал рядом с ним, который должен проиллюстрировать, что я использую функцию FFT правильно:Быстрое преобразование Фурье numpy дает неожиданные результаты

import numpy as np 
from matplotlib import pyplot as plt 

signal = array([[ 0.], [ 0.1667557 ], [ 0.31103874], [ 0.44339886], [ 0.50747922], 
    [ 0.47848347], [ 0.64544846], [ 0.67861755], [ 0.69268326], [ 0.71581176], 
    [ 0.726552 ], [ 0.75032795], [ 0.77133769], [ 0.77379966], [ 0.80519187], 
    [ 0.78756476], [ 0.84179849], [ 0.85406538], [ 0.82852684], [ 0.87172407], 
    [ 0.9055542 ], [ 0.90563205], [ 0.92073452], [ 0.91178145], [ 0.8795554 ], 
    [ 0.89155587], [ 0.87965686], [ 0.91819571], [ 0.95774404], [ 0.95432073], 
    [ 0.96326252], [ 0.99480947], [ 0.94754962], [ 0.9818627 ], [ 0.9804966 ], 
    [ 1.], [ 0.99919711], [ 0.97202208], [ 0.99065786], [ 0.90567128], 
    [ 0.94300558], [ 0.89839004], [ 0.87312245], [ 0.86288378], [ 0.87301008], 
    [ 0.78184963], [ 0.73774451], [ 0.7450479 ], [ 0.67291666], [ 0.63518575], 
    [ 0.57036157], [ 0.5709147 ], [ 0.63079811], [ 0.61821523], [ 0.49526048], 
    [ 0.4434457 ], [ 0.29746173], [ 0.13024641], [ 0.17631683], [ 0.08590552]]) 

sinus = np.sin(np.linspace(0, np.pi, 60)) 

plt.plot(signal) 
plt.plot(sinus) 

Синяя линия мой сигнал, зеленая линия пазухи.

raw.pdf

transformed_signal = abs(np.fft.fft(signal)[:30]/len(signal)) 
transformed_sinus = abs(np.fft.fft(sinus)[:30]/len(sinus)) 

plt.plot(transformed_signal) 
plt.plot(transformed_sinus) 

Синяя линия transformed_signal, зеленая линия является transformed_sinus.

fft.pdf

рисования только transformed_signal иллюстрирует поведение, описанное выше:

enter image description here

Может кто-нибудь объяснить мне, что здесь происходит?

UPDATE

Я был действительно проблема вызова FFT. Это правильный вызов и правильный результат:

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 

enter image description here

ответ

3

Nump's fft по умолчанию применяется к строкам. Поскольку ваша переменная signal является вектором столбца, fft применяется к строкам, состоящим из одного элемента и возвращает одноточечный БПФ каждого элемента.

Используйте опцию по оси fft, чтобы указать, что вы хотите FFT применяется по столбцам signal, т.е.

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 
+0

Или, если целью было «сигнал» быть 1D-вектором, преобразуйте его с чем-то вроде «np.array ([x [0] для x в сигнале])' – mtrw

1

[EDIT] я проглядел ключевую вещь высказанную Стелиос! Тем не менее, я оставляю свой ответ здесь, так как, не выявляя основной причины ваших проблем, он по-прежнему верен и содержит вещи, которые вы должны учитывать для использования БПФ.

Как вы говорите, вы транслируете непериодический сигнал. Ваш сигнал имеет некоторую рябь (более высокие гармоники), которые хорошо отображаются в БПФ. Синус имеет гораздо более высокие частоты и состоит в основном из компонента постоянного тока.

Пока все хорошо. Я не понимаю, что ваш сигнал также имеет компонент постоянного тока, который вообще не отображается. Может быть, это вопрос масштаба.

Суть в том, что, хотя синус и ваш сигнал выглядят совершенно одинаково, они имеют совершенно другое гармоническое содержание.

Наиболее заметным ни один из них не имеет частоты, которая соответствует половине синуса. Это объясняется тем, что «половина синуса» не построена путем суммирования целых синусов. Другими словами: лежащая в основе полная синусовая волна не находится в спектральном содержании синуса в течение половины периода.

BTW, имеющий только 60 выборок, немного скуден, Шеннон утверждает, что ваша частота выборки должна быть как минимум в два раза больше частоты сигнала, иначе произойдет сглаживание (отображение частот в неправильном месте). Другими словами: ваш сигнал должен визуально казаться гладким после отбора проб (если, конечно, он не прерывистый или имеет прерывистую производную, такую ​​как волна блока или треугольника). Но в вашем случае это похоже на то, что острые пики являются артефактом недокалибровки.

+0

Я совершенно новой для быстрого преобразования Фурье и не полностью понимаю ваш ответ. Я думаю, я понимаю, что сигналы выглядят совершенно иначе, чем БПФ, и поэтому будут давать совершенно разные результаты. Однако я не уверен, что вы имеете в виду с компонентом постоянного тока. Почему вы думаете, что должен быть один? И что вы предложите сделать, чтобы смягчить эту возможную проблему масштаба? Я попытаюсь найти более длинный сигнал для учета псевдонимов. – Paul

+0

@Paul Jacques ссылается на [теорему выборки Найквиста-Шеннона] (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem). Ваша частота дискретизации должна быть вдвое больше частоты самого высокочастотного компонента в сигнале, который вы хотите захватить. –

+0

В качестве индикатора: используйте как минимум 20 полных периодов наименьшей частоты, которые вы хотите обнаружить, и по меньшей мере 2 отсчета за полный период максимальной частоты. И постепенно ослабляйте свой сигнал в начале и в конце, чтобы предотвратить разрывы в сигнале и его производные (поэтому отрезание при нуле не будет работать, потому что производные будут делать прыжок тогда) –

Смежные вопросы