Основы цифровой обработки сигналов
Автор
05. Дискретное преобразование Фурье (ДПФ)
Дискретное преобразование Фурье (ДПФ) — это математический алгоритм, который преобразует последовательность дискретных отсчётов сигнала во временной области в набор комплексных коэффициентов, характеризующих его частотный состав.
Влияние фазы исследуемого сигнала
Рассмотрим, каким образом можно нивелировать влияние "случайной" фазы анализируемого сигнала:
In [ ]:
ОтношениеЧастот = 0 # @param {type:"slider",min:0,max:2,step:0.1}
Фаза = 0 # @param {type:"slider",min:0,max:360,step:5}
Синусоида = false # @param {type:"boolean"}
n = 0:25;
freq = ОтношениеЧастот / 2;
phase = Фаза*pi/180;
timeSignalFreq = ones(length(n));
timeSignalFreq = cos.(0.5.*n .- phase);
if Синусоида
probeSignal = cos.(freq.*n) + sin.(freq.*n)*im;
else
probeSignal = cos.(freq.*n);
end
product = timeSignalFreq .* probeSignal;
productSum = sum(product);
p1 = plot(n,timeSignalFreq,lc=:black,la=0.35,m=:c,mc=:black,msc=:black,ma=0.35,ms=5);
if Синусоида
p1 = scatter!(n,real(probeSignal),mc=:red,msc=:red,ma=0.65,ms=3)
p1 = scatter!(n,imag(probeSignal),mc=:blue,msc=:blue,ma=0.65,ms=3)
else
p1 = scatter!(n,probeSignal,mc=:red,ma=0.75,ms=3)
end
p1 = hline!([0], lc=:black, la=0.5, ls=:dash, lw=2);
p2 = plot(n,real(product),l=:stem,lw=12,lc=:red,la=0.5,ylim=(-1.1,1.1));
if Синусоида
p2 = plot!(n,imag(product),l=:stem,lw=12,lc=:blue,la=0.5);
end
p2 = hline!([0], lc=:black, la=0.5, ls=:dash, lw=2);
w = 0:0.01:1;
fullSummation = zeros(length(w)) + zeros(length(w))*im;
for idx = 1:length(w)
tempProbe = cos.(w[idx].*n) + sin.(w[idx].*n)*im;
tempProduct = tempProbe .* timeSignalFreq;
fullSummation[idx] = sum(tempProduct);
end
p3 = plot(w*2,real(fullSummation), lc=:red, la=0.5, lw=1.5);
if Синусоида
p3 = plot!(w*2,imag(fullSummation), lc=:blue, la=0.5, lw=1.5);
end
p3 = scatter!([ОтношениеЧастот], [real(productSum)], ms=5, mc=:red, ma=0.5, lw=2);
if Синусоида
p3 = scatter!([ОтношениеЧастот], [imag(productSum)], ms=5, mc=:blue, ma=0.5);
end
p3 = hline!([0], lc=:black, la=0.5, ls=:dash, lw=2);
l = @layout [a; b; c]
plot(p1, p2, p3; layout = l, legend = false, size=(800,400))
Out[0]:
Дискретное преобразование Фурье (для )
Где:
-
— -й комплексный гармонический коэффициент (частотная область);
-
— -й отсчет сигнала во временной области;
-
— общее количество отсчетов;
-
— мнимая единица;
-
— индекс частоты (от до );
-
— индекс отсчета времени (от до ).
In [ ]:
k = 0 # @param {type:"slider",min:0,max:10,step:1}
Фаза = 0 # @param {type:"slider",min:0,max:360,step:5}
DC = false # @param {type:"boolean"}
Гармоника = false # @param {type:"boolean"}
fs = 11; # Частота дискретизации
T = 1/fs; # Период дискретизации
N = 11;
t = (0:N-1).*T;
phase = Фаза*pi/180;
timeSignal = cos.(2*pi*t .+ phase) .+ DC/3 + (Гармоника/3).*cos.(6*pi*t .+ phase);
# Сигналы для "сравнения"
n = 0:N-1;
ndense = (0:10*N-1)/10;
psdense = exp.(-2*pi*im/N.*ndense*k);
probeSig = exp.(-2*pi*im/N.*n*k);
probeSignalMatrix = exp.(-2*pi*im/N.*n.*transpose(0:10));
productMatrix = timeSignal .* probeSignalMatrix;
productSumVector = vec(sum(productMatrix, dims = 1));
# Верхний график
p1 = scatter(n,timeSignal,mc=:black,ma=0.35,ms=8, xlim = (-1,11), ylim = (-1.5, 1.5));
p1 = plot!(n,timeSignal,lc=:black,la=0.25,lw=3);
p1 = scatter!(n,real(probeSig),mc=:red,ma=0.45,ms=5)
p1 = plot!(ndense,real(psdense),lc=:red,la=0.25,lw=2)
p1 = scatter!(n,imag(probeSig),mc=:blue,ma=0.45,ms=5)
p1 = plot!(ndense,imag(psdense),lc=:blue,la=0.25,lw=2)
# Нижний график
if k > 0
p2 = plot(0:k,imag.(productSumVector[1:k+1]), l=:stem, lw=6, m=:c, ms = 6, leg=false, xlim=(-1,11),ylim = (-6, 6))
p2 = plot!(0:k,real.(productSumVector[1:k+1]), l=:stem, lw=6, m=:c, ms = 6, leg=false)
else
p2 = plot([0],[real.(productSumVector[1])], l=:stem, lc=:red, la=0.5; lw=6, m=:c, ms = 6, mc=:red, ma=0.5, leg=false, xlim=(-1,11),ylim = (-6, 6))
end
l = @layout [a; b]
plot(p1, p2; layout = l, legend = false, size=(800,400))
Амплитудный и фазовый спектры сигнала
Для начала рассмотрим комплексный отсчёт на выходе алгоритма ДПФ:
In [ ]:
complexnumber = productSumVector[2]
Определим модуль и угол комплексной величины:
In [ ]:
abs(complexnumber)
In [ ]:
180*angle(complexnumber)/pi
Построим нормированный на длину ДПФ амплитудный спектр сигнала:
In [ ]:
plot(0:10,abs.(productSumVector) .* (2/N), l=:stem, lw=6, m=:c, ms = 6, leg=false, xlim=(-1,11))
И фазовый спектр в градусах:
In [ ]:
plot(0:10, (180/pi) .* angle.(productSumVector), l=:stem, lw=6, m=:c, ms = 6, leg=false, xlim=(-1,11), ylim=(-200,200))