Pull to refresh

Comments 32

Вы бы добавили, как фильтром убрать шум, для полноты картины.
И добавьте пожалуста что х — это свертка а не умножение.
а вот х это всё-таки умножение, самое простое и всем известное, или я чего-то не понимаю?
Ой, да, извините. В прошлом году был курс по обработке сигналов — вылетело из головы.
Всё в порядке, ошибиться может каждый.
это я дополню, но боюсь только завтра) спасибо за совет
А у вас конечный кадр данных? То есть вы кладете все в огромный массив, потом фильтрует? Я это к тому, что если прием данных происходит непрерывно и вы его искуственно нарезаете на части, то в местах стыков у вас будут проблемы…
Да кадр конечный, согласен, если сбор данных непрерывный этот вариант будет не очень приемлем.
А как тогда осуществлять фильтрацию, если идет тот же непрерывный поток данных с АЦП, а надо ослабить 50 Гц помеху? Сейчас делаю обычным усреднением, но подозреваю, что это крайне не эффективно.
Такого я ещё не делал, но могу посоветовать рекурсивную реализацию цифрового фильтра (есть в книге Айфичера (см. подвал статьи)), ещё видел реализацию непрерывной фильтрации через обратную связь (измеряется шум, далее из получаемого сигнала вычитается шум, и изменение шума подается снова на вход, ссылки под рукой нет, но кажется довольно быстро это можно найти в гугле), и есть шум довольно маленький по сравнению с сигналом — можно попробовать метод «скользящего среднего».
При программной реализации в случае покадровой обработки самое простое — подавать данные в функцию фильтрации описанную выше «в нахлест». То есть к основному кадру данных пристегивать кусочек данных впереди и кусочек позади. Размер этого «кусочка» взять равным половине порядка фильтра. Естественно, что эффективно это будет только для случаев, когда размер кадра значительно больше размера фильтра, иначе большие накладные расходы.
Другой способ — поштучная обработка пришедших данных. То есть в рабочем массиве храните только число отсчетов равное порядку фильтра. На каждом новом сэмпле новый отсчет в массив добавляете, самый старый выкидываете и запускаете процедуру однократно (для одного сэмпла). Так чаще делается в DSP. Ну и подобная же архитектура используется в аппаратной реализации фильтра (ASIC/FPGA).
По первому способу — после обработки эти «приклеенные кусочки» нужно выкинуть, т.к. они содержат некорректные результаты, ну а сами «ядра» кадров можно склеивать и отдавать дальше.
Мне нравится подход с построением модели в пространстве состояний (пример построения). Получается по сути система дискретных линейных уравнений, которую легко использовать в режиме реального времени. К тому же строится эта модель может на основе элементарных динамических звеньев. К примеру звено вида 1/Ts-1, где Т — постоянная интегрирования (1/Т — частота среза), а s — оператор Лапласса, является простейшим звеном задержки (простейший ФНЧ). Перемножая несколько элементарных звеньев можно управлять частотами среза, нелинейностями в и во вне полос пропускания и т.д.
Для завершенности статьи как-то не хватает достоинств и недостатков FIR-фильтров, а также описания, как на основе ФНЧ построить остальные типы фильтров. В принципе могу и сам написать в комментарии, если у вас нет времени на доработку или кому-то не терпится. Там не много.
Я когда начал тоже подумал добавить ещё и это, но потом решил что статья будет великовата. Если вас не затруднит — добавьте, буду признателен, время на доработку раньше чем завтра не появится уж точно.
Достоинства:
— простота теоретического анализа;
— простота практической реализации;
— наглядная связь коэффициентов фильтра с отсчетами его импульсной характеристики;
— устойчивость фильтра;
— при условии симметричности ИХ фильтра, фазовая характеристика линейная, что позволяет уменьшить искажения фронтов
Недостатки:
— для обеспечения хорошей АЧХ необходим высокий порядок фильтра (доходит до тысяч)

Расчет остальных типов фильтров базируется на теореме суммирования преобразований Фурье. За основу берется всепропускающий фильтр, который пропускает без ослабления все частоты. Такой фильтр имеет лишь один коэффициент, который не равен нулю (a0=1). В итоге расчет ФВЧ сводится к разнице:

ak, ФВЧ = ak, ВФ — ak, ФНЧ

image
Получаем ФВЧ с такой же частотой среза, какая была у рассчитанного ранее ФНЧ.
Подход к расчету полосового фильтра аналогичный, только берется разница двух ФНЧ:

ak, ПФ = ak, ФНЧ1 — ak, ФНЧ2

И последнее — режекторный фильтр:

ak, РФ = ak, ВФ — ak, ПФ
> — для обеспечения хорошей АЧХ необходим высокий порядок фильтра (доходит до тысяч)
Почему?.. Есть полиномы (многочлены) Баттерворта, дающие гладкие АЧХ даже для порядков знаменателя передаточной функции в пределах пятого.
Здесь имеется ввиду то, что при высоких порядках АЧХ будет приближаться к идеальной — прямоугольной функции, т.е. строго убирать все шумы и пропускать то что надо, в таком фильтре полоса перехода равна 0 (ну это идеал конечно же).
> в таком фильтре полоса перехода равна 0
Имеется в виду крутизна фронта/спада, как я понял. В общем случае да, крутизна повышается с увеличением порядка, но на мой взгляд порядок модели 1000+ это уже очень много. Возможно просто потому, что я не сталкивался с задачами где это необходимо.
Посмотрел графики полиномов Баттерворта, впечатляет, как же здорово комментарии на Хабре расширяют кругозор, спасибо.
Хорошей крутизной отличаются полиномы Чебышева, если мне не изменяет память.
А также Кайзера. Его методика мне почему-то больше нравится.
Спасибо! Пробежал пока поверхностно. Пока кажется сложнее того что я использую, но там синтез ведется из критерия линейности смещения фаз. Мне пока в этом не было необходимости (гарантировать отсутствие смещения фаз в некоторой полосе). При использовании простых моделей (асимптотически устойчивых заведомо) итак это гарантирует. На досуге изучу потщательнее.
Алгоритм Ремеза
MatLab, octave: функция (g)remez.
И, да: Рабинер и Голд «Теория и практика цифровой обработки сигналов». С третьей главы и далее о КИХ фильтрах и весовых функциях подробно и с картинками.
Спасибо огромное за ссылку на алгоритм Ремеза, не мог нигде найти достаточно подробное описание по нему (по крайней мере такое, чтобы я его ещё и понял). Насчет картинок — я вообще думаю подробно написать про весовые функции отдельно, а то когда видишь много-много вариантов — глаза разбегаются.
Да не за что, мне частенько приходится реализовывать цифровые фильтры на железе (на FPGA или на DSP TI), работа такая. Доедаю не первую собаку, связанную с нелинейностью, эффектом Гиббса и прочим. Обычно для реализации хватает алгоритма из octave функция remez (там, кажется, частный случай Ремеза — Parks-McClellan algorithm и исходники есть). Но бывают и фейлы: например, если попробовать посчитать ФНЧ скажем 1024 порядка с частотой среза 0.5w, то remez из octave выдаёт ошибочные результаты (впрочем причины вроде понятны). А вот MatLab'овский gremez не чудит, по-крайней мере не встречались такие условия.

Ещё интересный момент связан с конечной точностью вычислений. В частности, если фильтр реализуется в целочисленной арифметике (по очевидным причинам это быстрее и менее затратно по ресурсам на FPGA к примеру), выбор разрядности конечных и промежуточных результатов, метода округления — тоже целая наука.
Мне тоже скоро надо будет разбираться в нелинейностях и эффекте Гиббса, потому как первый этап — написать хоть какой-нибудь работающий цифровой фильтр (а пару-тройку недель назад я о их существовании и не знал) вроде бы пройден успешно.
Ещё раз спасибо, пойду-ка я изучать исходники функции remez.
Внимание: в формуле коэффициентов Блэкмена — ошибка (и в картинке и в программе), вместо исходного плюса (перед вторым слагаемым) указан минус.
Правильный вариант:
W [i] = 0.42 + 0.5 * cosl((2*M_PI*i) /( N-1)) + 0.08 * cosl((4*M_PI*i) /( N-1));
У Айчифера в источниках — все правильно.
Sign up to leave a comment.

Articles