Содержание статьи

Сигнал и его спектр
Спектр — это представление сигнала в частотной области, которое показывает, какие именно частоты присутствуют в сигнале. Спектр бывает амплитудным и фазовым. Первый показывает амплитуды частот в сигнале, а второй — фазы этих частот. В современном мире, когда кто‑то пишет о спектре, обычно подразумевается именно амплитудный спектр.
Сам спектр бывает двух видов: непрерывный и дискретный. Непрерывный спектр — это когда сигнал содержит бесконечное число компонент, распределенных в диапазоне частот. Дискретный — когда сигнал содержит только определенные частотные компоненты. Такое характерно для сигналов, которые составлены из, например, суммы синусоид или косинусоид.
Теперь начнем с самого простого — с синусоидального сигнала.
info
Все свои эксперименты с математикой я буду делать в Octave.
Создадим синусоиду с амплитудой 1 попугай и частотой 5 Гц.
% Амплитуда
A = 1;% Частота в герцах
f = 5;% Длительность нашего сигнала в секундах
T = 1;% Частота дискретизации, или количество точек в секунду. Этот параметр влияет на точность вывода: чем больше точек, тем точнее сигнал
fs = 100;% Временной ряд
t = 0:1/fs:T;% Генерируем!
y = A * sin(2 * pi * f * t);plot(t, y);xlabel('Время (с)');ylabel('Амплитуда');title('Синусоида');grid on;
После запуска этого кода в Octave ты получишь график синусоиды.

На графике пять положительных полупериодов и пять отрицательных, потому что длительность — 1 с, а частота — 5 Гц, вот и получается, что полных периодов именно пять. Это самый простой сигнал, который имеет только одну частоту в спектре — это частота самой синусоиды, то есть 5 Гц.
Преобразование Фурье
Определение
Преобразование Фурье́ (символ ℱ) — операция, сопоставляющая одной функции вещественной переменной другую (вообще говоря, комплекснозначную) функцию вещественной переменной. Эта новая функция описывает коэффициенты («амплитуды») при разложении исходной функции на элементарные составляющие — гармонические колебания с разными частотами.
По сути, преобразование Фурье — это операция, которая позволяет разложить сигнал на его простые составляющие, то есть определить, из суммы каких сигналов на каких частотах он состоит.

На картинке выше наглядно показан процесс такого разложения. Сумма всех синих сигналов даст красный, а их частоты показаны на спектре сигнала справа.
При прямом преобразовании Фурье мы получаем на выходе комплексное число, которое состоит из реальной и мнимой части.
Комплексные числа
Комплексное число — это расширенное множество вещественных чисел. Комплексные числа выглядят следующим образом: a + bi, где a и b — вещественные числа, а i — мнимая единица. Мнимая единица — это корень из –1, то есть i²
.
В радио очень широко используются комплексные числа, так как они позволяют хранить больше информации о сигнале. Например, существуют амплитудный и фазовый спектры, и первый определяется действительной частью, а второй — мнимой.
Сразу же хочется упомянуть еще одно из свойств преобразования Фурье: если сдвигать сигнал во времени, то амплитудный спектр сигнала меняться не будет. Изменяться будет только фазовый спектр, который описывается комплексной частью.
Обратное преобразование Фурье
Обратное преобразование Фурье — это процедура получения сигнала из спектра. У сигнала может быть несколько параметров, такие как максимальная амплитуда, диапазон частот и его длительность. Давай начнем с простого примера: сделаем сигнал из спектра, на котором будет только отметка в 5 Гц с амплитудой 1.
% Частота дискретизации в герцахfs = 1000;% Длительность сигнала в секундахT = 1;% Общее количество отсчетовN = T * fs;% Создание спектра% Инициализация спектра нулямиspectrum = zeros(1, N);% Частота для отметки в спектреf_target = 5;% Индекс для частоты 5 Гцindex = f_target + 1;% Установка амплитудыspectrum(index) = 1;
Первым делом задаются параметры: длительность, частота дискретизации и количество отсчетов на основе длительности и дискретизации. Далее создаем сам спектр — он будет, по сути, просто массивом. Устанавливаем в нем все значения в ноль и только амплитуду частоты 5 Гц ставим в единицу. В этом примере мы устанавливаем только вещественную часть комплексного числа. Ты можешь попробовать добавить мнимую часть — для этого вместо spectrum(
напиши spectrum(
и посмотри, что будет. Фаза сигнала должна измениться.
% Обратное преобразование Фурье для получения сигналаsignal = real(ifft(spectrum));t = 0:1/fs:T-1/fs;% Визуализация сигналаfigure;plot(t, real(signal));title('Сигнал, полученный из спектра');xlabel('Время (с)');ylabel('Амплитуда');% Визуализация спектраf_axis = (0:N-1) * fs / N;figure;stem(f_axis(1:N/2), abs(spectrum(1:N/2)), 'filled');title('Спектр с отметкой на 5 Гц');xlabel('Частота (Гц)');ylabel('Амплитуда');xlim([0 10]);
Преобразуем наш спектр в сигнал с помощью команды ifft
, которая выполняет обратное преобразование, и строим визуализацию. В моем коде я беру сразу реальную часть сигнала для отображения, но если поменять функцию real
на imag
в строке с ifft
, то можно будет получить фазовый спектр, о котором я говорил в начале статьи.
Смешиваем сигналы
Для примера давай сделаем сигнал из смеси трех синусоид на частотах 5, 10 и 15 Гц. Для этого достаточно все эти три синусоиды просто сложить.
% Частота дискретизации в герцахfs = 1000;% Продолжительность сигнала в секундахT = 1;% Вектор времениt = 0:1/fs:T-1/fs;% Частотыf1 = 5;f2 = 10;f3 = 15;% Синусоидыsignal1 = sin(2 * pi * f1 * t);signal2 = sin(2 * pi * f2 * t);signal3 = sin(2 * pi * f3 * t);% Складываем синусоиды (шок)signal = signal1 + signal2 + signal3;plot(t, signal);xlabel('Время (с)');ylabel('Амплитуда');title('Синусоида');grid on;
Все переменные можно по отдельности изучить в окне Workspace. Нетяжело заметить, что t
— это массив из 1000 элементов, в котором хранятся времена отсчетов.
0 0.0010 0.0020 0.0030 0.0040 0.0050 0.0060 ...
Сам же сигнал (signal1
) — это тоже массив. Для каждого времени Octave автоматически посчитал синус и создал новый массив. Каждому i-му элементу массива с сигналом соответствует i-й элемент массива t
, определяющий время, в которое сигнал будет иметь такую амплитуду.
0 0.031411 0.062791 0.094108 0.12533 0.15643 0.18738 ...
Если же закончить выполнение скрипта и посмотреть результаты сложения в переменной signal
, то увидим ожидаемую сумму трех синусоидальных сигналов.
0 0.18831 0.37551 0.56048 0.74215 0.91944 1.0913 ...
Теперь можно запустить оставшуюся часть кода и увидеть отрисованную форму сигнала.

Выглядит интересно. А теперь посмотрим на амплитудный спектр этого сигнала. Чтобы это сделать, используем следующий код.
% Частота дискретизации в герцахfs = 1000;% Продолжительность в секундахT = 1;t = 0:1/fs:T-1/fs;f1 = 5;f2 = 10;f3 = 15;% Синусоидыsignal1 = sin(2 * pi * f1 * t);signal2 = sin(2 * pi * f2 * t);signal3 = sin(2 * pi * f3 * t);% Сложение синусоидsignal = signal1 + signal2 + signal3;% Выполнение преобразования Фурьеsignal_fft = fft(signal);P2 = abs(signal_fft / length(signal));P1 = P2(1:length(signal)/2+1);P1(2:end-1) = 2*P1(2:end-1);f_axis = fs*(0:(length(signal)/2))/length(signal);% Визуализация спектраbar(f_axis, P1, 'hist');title('Амплитудный спектр сигнала');xlabel('Частота (Гц)');ylabel('|P1(f)|');xlim([0, max(f_axis)]);
Запускаем и получаем три красивых столбика как раз на частотах 5, 10 и 15 Гц. Прекрасно.

Картинка
Теперь, когда мы знаем, как создавать свои сложные сигналы и как они раскладываются обратно на составляющие их частоты, можно приступать к контролю над миром тем, что выводится на водопаде. Задачу возьмем несложную — вывести на водопад картинку.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»