Зачем нужны фильтры и какие они бывают
Знакомимся с фильтрами — инструментом, который пропускает нужные частоты и душит лишние.
Цифровой фильтр — LTI-система, которая по-разному пропускает разные частоты: одни усиливает или оставляет, другие ослабляет. Задаётся импульсной характеристикой (ядром).
Зачем фильтровать? Чтобы убрать то, что мешает, и оставить то, что нужно. Шум в записи голоса, наводка 50 Гц в ЭКГ, высокочастотная «рябь» в показаниях датчика — всё это лишние частоты. Фильтр — это «частотное сито»: настраиваешь, какие частоты пропустить, и сигнал очищается. Это самая практичная тема DSP.
Четыре базовых типа
| Тип | Что пропускает | Пример применения |
| ФНЧ (низких частот, lowpass) | низкие, душит высокие | сглаживание, антиалиасинг, убрать шум |
| ФВЧ (высоких частот, highpass) | высокие, душит низкие | убрать дрейф нуля, выделить фронты |
| Полосовой (bandpass) | только полосу частот | выделить радиоканал, тон, ноту |
| Режекторный (notch, bandstop) | всё, кроме узкой полосы | убрать наводку 50 Гц, свист |
ФНЧ на практике: сглаживание
Простейший ФНЧ — скользящее среднее. Оно пропускает медленные изменения (низкие частоты) и душит быстрые скачки (высокие). Покажем: постоянный сигнал проходит без изменений, а быстрая «дрожь» гасится.
def convolve_same(x, h):
M = len(h); pad = M // 2
out = []
for i in range(len(x)):
s = 0.0
for j in range(M):
idx = i - pad + j
if 0 <= idx < len(x):
s += x[idx] * h[j]
out.append(round(s, 2))
return out
ma3 = [1/3, 1/3, 1/3] # ядро ФНЧ
slow = [5, 5, 5, 5, 5, 5] # постоянный (низкая частота)
fast = [5, -5, 5, -5, 5, -5] # дрожь (высокая частота)
print("ФНЧ медленного:", convolve_same(slow, ma3))
print("ФНЧ быстрого: ", convolve_same(fast, ma3))
Вывод:
ФНЧ медленного: [3.33, 5.0, 5.0, 5.0, 5.0, 3.33] ФНЧ быстрого: [0.0, 1.67, -1.67, 1.67, -1.67, 0.0]
Постоянный сигнал в середине проходит как есть (5.0), а быстрая дрожь с размаха ±5 сжалась до ±1.67 — амплитуда упала втрое. ФНЧ пропускает низкие, давит высокие — как и обещано.
ФВЧ: выделяем изменения
Простейший ФВЧ — разность соседей y[n] = x[n] - x[n-1]. Он реагирует на быстрые перепады и гасит постоянную составляющую.
def highpass(x):
return [round(x[i] - x[i - 1], 2) if i > 0 else 0.0 for i in range(len(x))]
const = [5, 5, 5, 5, 5] # постоянный сигнал
edge = [0, 0, 9, 9, 9] # резкий фронт
print("ФВЧ постоянного:", highpass(const))
print("ФВЧ фронта: ", highpass(edge))
Вывод:
ФВЧ постоянного: [0.0, 0, 0, 0, 0] ФВЧ фронта: [0.0, 0, 9, 0, 0]
Постоянный сигнал ФВЧ обнулил (низкая частота подавлена), а на резком фронте дал всплеск 9 — выделил быстрое изменение. Полосовой и режекторный фильтры строят, комбинируя эти идеи.
Как работает под капотом
Что фильтр делает с частотами, описывает его амплитудно-частотная характеристика (АЧХ) — кривая |H(f)|, показывающая коэффициент усиления на каждой частоте. У идеального ФНЧ АЧХ — это «кирпич»: 1 до частоты среза и 0 после. Реальные фильтры так не умеют: у них есть плавная переходная зона и небольшая «рябь». АЧХ — это, как мы помним, преобразование Фурье импульсной характеристики фильтра. Поэтому проектирование фильтра — это, по сути, подбор такого ядра h, чтобы его спектр был похож на нужную форму АЧХ. Два больших класса фильтров — FIR (конечная импульсная характеристика) и IIR (бесконечная) — разберём в следующих уроках.
Частые ошибки
- Слишком агрессивный ФНЧ. Сильное сглаживание убивает не только шум, но и полезные детали сигнала.
- Забыть про фазовые искажения. Фильтр вносит задержку; для синхронных задач это важно.
- Путать «убрать частоту» и «убрать амплитуду». Фильтр работает по частотам, а не по уровню сигнала.
Итог
- Фильтр — частотное сито: пропускает нужные частоты, душит лишние.
- Четыре базовых типа: ФНЧ, ФВЧ, полосовой, режекторный.
- ФНЧ сглаживает (среднее), ФВЧ выделяет изменения (разность).
- Поведение фильтра описывает АЧХ — спектр его импульсной характеристики.