Алиасинг: что будет, если нарушить теорему
Разбираем главную ловушку оцифровки: что произойдёт, если снимать отсчёты слишком редко.
Алиасинг (наложение спектров) — эффект, при котором частота выше частоты Найквиста после дискретизации неотличима от некоторой более низкой частоты («самозванца»).
Если нарушить условие Котельникова, сигнал не просто «огрубляется» — он превращается в другой, ложный. Высокая частота надевает «маску» низкой, и отличить их по отсчётам невозможно. Это самая коварная ошибка в DSP, потому что испорченные данные выглядят правдоподобно.
Демонстрация: 7 Гц притворяется 1 Гц
Возьмём fs = 8 Гц (Найквист = 4 Гц) и снимем тон 7 Гц — он выше Найквиста, условие нарушено. Сравним отсчёты с тоном 1 Гц.
import math
fs = 8.0
real7 = [round(math.sin(2 * math.pi * 7 * n / fs), 3) for n in range(8)]
real1 = [round(math.sin(2 * math.pi * 1 * n / fs), 3) for n in range(8)]
print("7 Гц @ 8 Гц:", real7)
print("1 Гц @ 8 Гц:", real1)
print("Это зеркальные копии:", [a == -b for a, b in zip(real7, real1)])
Вывод:
7 Гц @ 8 Гц: [0.0, -0.707, -1.0, -0.707, 0.0, 0.707, 1.0, 0.707] 1 Гц @ 8 Гц: [0.0, 0.707, 1.0, 0.707, 0.0, -0.707, -1.0, -0.707] Это зеркальные копии: [True, True, True, True, True, True, True, True]
Отсчёты тона 7 Гц — это в точности отсчёты тона 1 Гц, только с обратным знаком (фазой). По числам DSP видит низкочастотный сигнал, хотя на входе был высокочастотный. Семёрка «замаскировалась». Формула «самозванца»: видимая частость = |f - k*fs| для подходящего целого k; здесь |7 - 8| = 1 Гц.
Куда «складываются» частоты
def alias_freq(f, fs):
# частота, под которую замаскируется f после дискретизации
f_mod = f % fs
return f_mod if f_mod <= fs / 2 else fs - f_mod
fs = 100.0
for f in [10, 40, 60, 90, 110, 140]:
print(f"{f:>4} Гц выглядит как {alias_freq(f, fs):>5.1f} Гц")
Вывод:
10 Гц выглядит как 10.0 Гц 40 Гц выглядит как 40.0 Гц 60 Гц выглядит как 40.0 Гц 90 Гц выглядит как 10.0 Гц 110 Гц выглядит как 10.0 Гц 140 Гц выглядит как 40.0 Гц
Частоты ниже Найквиста (50 Гц) остаются собой; всё, что выше, «отражается» от границы и притворяется низкой частотой. Спектр как бы складывается гармошкой вокруг fs/2.
Где алиасинг видно глазами
- Колёса в кино едут назад. Камера снимает 24 кадра/с; если спица за кадр успевает почти на свою позицию, мозг видит медленное обратное вращение — это алиасинг по времени.
- Муар на фото решётки или ткани. Пространственная частота узора выше частоты пикселей матрицы — появляется ложный крупный узор.
- Стробоскоп. Вспышки с частотой, кратной вращению, «замораживают» вентилятор.
Как работает под капотом
Дискретизация копирует спектр с шагом fs. Частота f > fs/2 в исходном спектре имеет «зеркального двойника» в копии, который попадает в полезный диапазон 0..fs/2. После оцифровки оригинал и двойник неразличимы — они дают одинаковые отсчёты. Математически sin(2*pi*f*n/fs) и sin(2*pi*(f±k*fs)*n/fs) совпадают, потому что добавка k*fs даёт целое число периодов между отсчётами. Лекарство одно и только одно: не пускать такие частоты в АЦП — аналоговый антиалиасинговый ФНЧ перед оцифровкой. После оцифровки исправить уже нельзя.
Частые ошибки
- «Потом отфильтрую цифрой». Поздно: алиасинговые частоты уже неотличимы от полезных. Срезать надо до АЦП.
- Игнорировать высокочастотный шум. Даже если полезный сигнал низкочастотный, шум выше Найквиста сложится в полосу и испортит данные.
- Путать алиасинг с обычным шумом. Алиасинг создаёт детерминированные ложные тоны, а не случайную «травку»; их не уберёшь усреднением.
Итог
- Алиасинг — маскировка частоты выше Найквиста под более низкую при недостаточной
fs. - Видимая частота = «отражение» от
fs/2:|f - k*fs|. - Бытовые проявления: обратное вращение колёс, муар, стробоскоп.
- Защита — антиалиасинговый фильтр до АЦП; после оцифровки эффект необратим.