Путаница с алгоритмом FFT - PullRequest
7 голосов
/ 16 февраля 2011

Я пытаюсь понять алгоритм FFT и до сих пор думаю, что понимаю основную концепцию, стоящую за ним.Однако я не совсем понимаю разницу между размерами кадров и окном.

Исходя из моего понимания, кажется, что они избыточны друг с другом?Например, я представляю в качестве входных данных блок выборок с размером кадра 1024. Таким образом, у меня есть байт [1024], представленный в качестве входных данных.

Какова тогда цель оконной функции?С самого начала я думал, что целью оконной функции является выбор блока сэмплов из исходных данных.

Спасибо!

Ответы [ 3 ]

14 голосов
/ 16 февраля 2011

Какова тогда цель оконной функции?

Это имеет дело с так называемой "спектральной утечкой": БПФ предполагает бесконечный ряд, который повторяет данный кадр образца нади снова.Если у вас есть синусоида, которая представляет собой целое число циклов в кадре выборки, то все хорошо, и БПФ дает вам хороший узкий пик на правильной частоте.Но если у вас есть синусоида, которая не является целым числом циклов, существует разрыв между последней и первой выборкой, и БПФ дает вам ложные гармоники.

Функции управления окнами понижают амплитуды в начале иконец выборочного кадра, чтобы уменьшить гармоники, вызванные этим разрывом.

некоторые диаграммы с веб-страницы National Instruments по оконному оформлению :

целое число циклов:

enter image description here

нецелое число циклов:

enter image description here

для дополнительной информации:

http://www.tmworld.com/article/322450-Windowing_Functions_Improve_FFT_Results_Part_I.php

http://zone.ni.com/reference/en-XX/help/371361B-01/lvanlsconcepts/char_smoothing_windows/

http://www.physik.uni -wuerzburg.de / ~ Praktiku / Anleitung / Fremde / ANO14.pdf

7 голосов
/ 17 февраля 2011

Прямоугольное окно длины M имеет частотную характеристику sin(ω*M/2)/sin(ω/2), которая равна нулю, когда ω = 2*π*k/M, для k ≠ 0. Для ДПФ длины N, где ω = 2*π*n/N, есть нули в n = k * N/M.Отношение N / M не обязательно является целым числом.Например, если N = 40 и M = 32, то в DFT появятся нулевые значения, кратные 1,25, но в DFT появятся только целочисленные кратные значения, которые в данном случае равны 5, 10, 15 и 20.

Вот график 1024-точечного ДПФ прямоугольного окна с 32 точками:

M = 32
N = 1024
w = ones(M)
W = rfft(w, N)
K = N/M
nulls = abs(W[K::K])
plot(abs(W))
plot(r_[K:N/2+1:K], nulls, 'ro')
xticks(r_[:512:64])
grid(); axis('tight')

DFT of a 32-point rectangular window

Обратите внимание на нули в каждом N / M = 32 бункеров,Если N = M (т. Е. Длина окна равна длине ДПФ), то во всех бинах будут нулевые значения, кроме n = 0.

Когда вы умножаете окно на сигнал, соответствующая операция в частотной областикруговая свертка спектра окна со спектром сигнала.Например, DTFT синусоиды представляет собой взвешенную дельта-функцию (т.е. импульс с бесконечной высотой, бесконечно малым расширением и конечной площадью), расположенный на положительной и отрицательной частоте синусоиды.Свертывание спектра с дельта-функцией просто смещает его к местоположению дельты и масштабирует по весу дельты.Поэтому, когда вы умножаете окно на синусоиду в области выборки, частотная характеристика окна масштабируется и сдвигается на частоту синусоиды.

Существует несколько сценариев для изучения длины прямоугольного окна.Сначала давайте рассмотрим случай, когда длина окна является целым кратным периода синусоиды, например, прямоугольное окно косинуса с 32 выборками с периодом 32/8 = 4 выборки:

x1 = cos(2*pi*8*r_[:32]/32)    # ω0 = 8π/16, bin 8/32 * 1024 = 256
X1 = rfft(x1 * w, 1024)
plot(abs(X1))
xticks(r_[:513:64])
grid(); axis('tight')

DFT of cosine at w0 = 8π/16 with a 32-point rectangular window

Как и прежде, есть значения NULL при значениях, кратных N / M = 32. Но спектр окна был смещен в корзину 256 синусоиды и масштабирован по ее величине, которая на 0,5 делится между положительной частотойи отрицательная частота (я только строю положительные частоты).Если бы длина DFT была 32, нули были бы выстроены в линию в каждом бункере, подсказывая появление , что нет утечки.Но этот вводящий в заблуждение вид является только функцией длины ДПФ.Если вы добавите в оконный сигнал нули (как указано выше), вы увидите синусоидальный отклик на частотах между нулями.

Теперь давайте рассмотрим случай, когда длина окна не является целым числомкратный периоду синусоиды, например, косинус с угловой частотой 7,5 / 16 (период 64 выборки):

x2 = cos(2*pi*15*r_[:32]/64)    # ω0 = 7.5π/16, bin 15/64 * 1024 = 240
X2 = rfft(x2 * w, 1024)
plot(abs(X2))
xticks(r_[-16:513:64])
grid(); axis('tight')

DFT of cosine at w0 = 7.5π/16 with a 32-point rectangular window

Расположение центральной ячейки нетбольше на целое число, кратное 32, но смещено вдвое к бину 240. Итак, давайте посмотрим, как будет выглядеть соответствующий 32-точечный ДПФ (выводя прямоугольное окно из 32 точек).Я вычислю и нарисую 32-точечное ДПФ x2 [n], а также наложу 32-кратную десятичную копию 1024-точечного ДПФ:

X2_32 = rfft(x2, 32)
X2_sample = X2[::32]
stem(r_[:17],abs(X2_32))
plot(abs(X2_sample), 'rs')    # red squares
grid(); axis([0,16,0,11])

32-point DFT of cosine at w0 = 7.5π/16

Как выКак видно на предыдущем графике, нулевые значения больше не выровнены с кратными 32, поэтому величина 32-точечного ДПФ не равна нулю в каждом бине.В 32-точечном DFT нулевые значения окна по-прежнему расположены через каждые N / M = 32/32 = 1 бин, но, поскольку ω0 = 7.5π / 16, центр находится в «bin» 7.5, что устанавливает нули в 0.5, 1.5и т. д., поэтому они отсутствуют в 32-точечном DFT.

Общее сообщение состоит в том, что спектральная утечка оконного сигнала всегда присутствует , но может быть замаскирована в DFT, еслиСпектр сигнала, длина окна и длина DFT объединяются в едином правильном порядке, чтобы выровнять нули.Кроме того, вы должны просто игнорировать эти артефакты DFT и сконцентрироваться на DTFT вашего сигнала (т. Е. Заполнить нулями пробу DTFT с более высоким разрешением, чтобы вы могли четко изучить утечку).

Спектральная утечка, вызванная свертыванием со спектром окна, всегда будет существовать, поэтому искусство изготовления окон особой формы так важно.Спектр каждого типа окна был адаптирован для конкретной задачи, такой как динамический диапазон или чувствительность.

Вот пример, сравнивающий выходные данные прямоугольного окна с окном Хемминга:

from pylab import *
import wave

fs = 44100
M = 4096
N = 16384
# load a sample of guitar playing an open string 6
# with a fundamental frequency of 82.4 Hz
g = fromstring(wave.open('dist_gtr_6.wav').readframes(-1),
               dtype='int16')
L = len(g)/4
g_t = g[L:L+M]
g_t = g_t / float64(max(abs(g_t)))
# compute the response with rectangular vs Hamming window
g_rect = rfft(g_t, N)
g_hamm = rfft(g_t * hamming(M), N)

def make_plot():
    fmax = int(82.4 * 4.5 / fs * N)  # 4 harmonics
    subplot(211); title('Rectangular Window')
    plot(abs(g_rect[:fmax])); grid(); axis('tight')
    subplot(212); title('Hamming Window')
    plot(abs(g_hamm[:fmax])); grid(); axis('tight')

if __name__ == "__main__":
    make_plot()

rectangular vs hamming window

2 голосов
/ 16 февраля 2011

Если вы не изменяете значения выборки и выбираете ту же длину данных, что и длина БПФ, это эквивалентно использованию прямоугольного окна, в этом случае рамка и окно идентичны. Однако умножение ваших входных данных на прямоугольное окно во временной области аналогично свертыванию спектра входного сигнала с функцией Sinc в частотной области, которая распространит любые спектральные пики для частот, которые не являются точно периодическими в апертуре БПФ, по весь спектр.

Часто используются непрямоугольные окна, поэтому результирующий спектр БПФ свернут с чем-то более "сфокусированным", чем функция Sinc.

Вы также можете использовать прямоугольное окно, размер которого отличается от длины или диафрагмы БПФ. В случае более короткого окна данных кадр FFT может быть дополнен нулями, что может привести к более гладкому виду спектра интерполированных результатов FFT. Вы можете даже использовать прямоугольное окно, которое длиннее, чем длина БПФ, оборачивая данные вокруг апертуры БПФ суммированным круговым способом для получения некоторых интересных эффектов с частотным разрешением.

ДОБАВЛЕНО по запросу:

Умножение на окно во временной области дает тот же результат, что и свертывание с преобразованием этого окна в частотной области.

Как правило, более узкое окно во временной области обеспечивает более широкое преобразование в частотной области. Это причина того, что заполнение нулями дает более плавный частотный график. Более узкое окно во временной области дает более широкий Sinc с более полными и более плавными кривыми по отношению к ширине кадра, чем окно на всю ширину кадра FFT, что делает результаты интерполированной частоты более гладкими, чем FFT с ненулевым дополнением того же самого длина кадра.

Обратное также в некоторой степени верно. Более широкое прямоугольное окно создаст более узкий Sinc, с нулями ближе к вершине. Таким образом, вы можете использовать тщательно выбранное более широкое окно, чтобы получить более узкий Sinc для обнуления частоты, которая ближе к интересующей ячейке, чем одна ячейка частоты. Как вы используете более широкое окно? Оберните данные вокруг и суммируйте, что идентично использованию базисных векторов FT, которые не усекаются до 1 кадра FFT в длину. Однако, поскольку при этом вектор результата FFT короче, чем данные, это процесс с потерями, который будет вводить артефакты и вводить некоторые новые новые псевдонимы. Но это даст вам более резкий пик выбора частоты в каждом бине и режекторные фильтры, которые можно разместить на расстоянии менее 1 бина, скажем, на полпути между бинами и т. Д.

...