Автор |
Сообщение |
|
Дата: 27 Авг 2012 15:51:41
#
Есть вопрос практической реализации фильтра на основе FFT.
Реализовал алгоритм: hann() -> FFT() -> изменить спектр -> IFFT() -> sum().
Перекрытие - пол-окна (или 1/4 или 1/8 - регулируемо), окно Ханна (cos(-pi/2 ... pi/2)) (с коэффициентом, соответствующим степени перекрытия).
Например, win = 2048, нужно подавить bin = 10. Я обнуляю Re и Im этого бина, учитывая, что по индексу номер 0 и индексу номер win/2 лежит "постоянка" и что вторая часть зеркально развёрнута.
Практическая проблема в том, что аккуратно затухающий к краям окна сигнал (после hann()) после изменения его спектра и обратного FFT имеет право поменяться так, что перестанет аккуратно затухать к краям (-; Стыки окон портятся и щёлкают.
Есть мысль (не реализована) сделать расширение спектра - к пропущенному через hann() окну с двух сторон добавить какое-то кол-во нулей (например по win/2) и после обратного FFT() накладывать эти широкие окна. Почему это может помочь - я не знаю.
|
|
Дата: 27 Авг 2012 16:19:18
#
Практическая проблема в том, что аккуратно затухающий к краям окна сигнал (после hann()) после изменения его спектра и обратного FFT имеет право поменяться так, что перестанет аккуратно затухать к краям (-; Стыки окон портятся и щёлкают.
а как так получается? он же на 0 сводится. На самих краях значит 0 и остается, а дальше плавно, если не было разрвов в "изменить спектр".
Очевидных рекомендаций наверное две: "изменить спектр" должна быть без разрывов и ограничить её усиление какими-то разумными пределами, видимо просто динамического диапазона нехватает. Усилить можно потом. Можно в несколько этапов попробовать, если хочется уж очень круто.
|
Реклама Google
|
|
|
Дата: 27 Авг 2012 16:29:23
#
Рекомендация может быть только одна - делать правильно, либо быструю свёртку, либо oversampled банк фильтров. Окно это импульсная характеристика ваших полосовых фильтров, а вот децимируете вы не по котельникову(перекрытие блоков), отсюда и щелчки, если соблюдать котельникова то почти скользящее FFT получится, что не выгодно по вычислительным затратам.
|
|
Дата: 27 Авг 2012 16:32:28
#
а как так получается? он же на 0 сводится. На самих краях значит 0 и остается, а дальше плавно, если не было разрвов в "изменить спектр".
Очевидных рекомендаций наверное две: "изменить спектр" должна быть без разрывов и ограничить её усиление какими-то разумными пределами, видимо просто динамического диапазона нехватает. Усилить можно потом. Можно в несколько этапов попробовать, если хочется уж очень круто.
1. Я не усиливаю, а убираю. Возможно моё тупое обнуление - это слишком жестоко.
Как получается не ноль?
Ноль существовал потому, что сумма некоторых гармонических функций суммировалась так, что в данных точках получался ноль. Обнулив некоторые бины, я выключил какие-то из гармонических функций, в результате сумме стало чего-то недоставать для формирования старого сигнала, в том числе и нулей. Это моё грубое понимание.
|
|
Дата: 27 Авг 2012 23:05:04 · Поправил: Programmist (27 Авг 2012 23:19:11)
#
pavelkolodin
Здесь готовое решение и тема соответствующая.
Чтобы было по Котельникову, petr0v прав, нужно скользящее FFT делать, а там двойное перекрытие Ханном, ну и еще пара "фокусов".
Для большинства задач качество фильтрации и скорость работы получается вполне приемлемым. |
|
Дата: 29 Авг 2012 01:23:52
#
Двойное перекрытие Ханном - это как? У меня сейчас реализовано перекрытие окон по 50%. Ханн.
|
|
Дата: 29 Авг 2012 09:14:49 · Поправил: Programmist (29 Авг 2012 09:41:38)
#
перекрытие окон по 50%. Ханн. Оно самое, игра слов, иначе не получится. Только обнулять бины на краях спектра при фильтрации нужно не полностью, а тоже по Ханну, умножив на половинку окна результат прямого FFT. Чем шире эта половинка, тем лучше картина на стыках блоков и хуже крутизна среза. У меня в программе это обозначено как "Fade" (на краях спектра в Герцах). Здесь можно попробовать и другие оконные функции.
|