Я новичок в принципе вычисления мгновенной частоты и придумал много вопросов по этому поводу. Вы найдете их все в списке маркеров в конце этого текста. Текст может быть немного длинным, извините за это, но я действительно пытался решить эту проблему самостоятельно.
Поэтому меня интересует мгновенная частота действительного сигнала . Расчет производится с помощью аналитического сигнала , где - гильбертово преобразование .
Чтобы вычислить мгновенные частоты из аналитического сигнала я следовал работе:
Расчет мгновенной частоты и мгновенной полосы пропускания Артур Э. Барнс с 1992 года. В этой статье он вводит несколько методов для расчета мгновенной частоты. Я записываю все формулы, которые он предложил (и я использовал) в одно мгновение.
Для «обучения» я играл с очень простым и двумя немного более сложными сигналами в MATLAB и хотел получить их мгновенные частоты.
Fs = 1000; % sampling-rate = 1kHz
t = 0:1/Fs:10-1/Fs; % 10s 'Timevector'
chirp_signal = chirp(t,0,1,2); % 10s long chirp-signal, signal 1
added_sinusoid = chirp_signal + sin(2*pi*t*10); % chirp + sin(10Hz), signal 2
modulated_sinusoid = chirp_signal .* sin(2*pi*t*10); % chirp * sin(10Hz), signal 3
Графики этих трех сигналов во временной области выглядят следующим образом:
Графики всех мгновенных частот, которые я получил после применения всех методов из статьи, следующие:
Мгновенные частоты чистого ЛЧМ-сигнала: мгновенные частоты ЛЧМ-сигнала с добавленной синусоидой: Мгновенные частоты модулированного ЛЧМ-сигнала: обратите внимание, что на всех трех изображениях ось Y графиков 3 и 4 увеличена, поэтому амплитуды этих сигналы очень крошечные!
function [instantaneous_frequency] = f2(analytic_signal,Fs)
factor = Fs/(2*pi);
instantaneous_frequency = factor * diff(unwrap(angle(analytic_signal)));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
В статье Barns теперь предлагают (или, скорее, упомянутые компиляции) четыре других способа вычисления мгновенных частот из аналитического сигнала. Он также упоминает верхнюю формулу, но считает, что она нецелесообразна из-за неясностей в фазе. Я думаю, он не знал о unwrap()
методе, или, точнее, о математике, стоящей за ним. (Я сам узнал об этом методе только сегодня, когда смотрел на некоторые другие исходные коды на мгновенных частотах)
В его статье формула имеет метку Number (2), поэтому я дал f (t) индекс 2. Все остальные индексы точно так же соответствуют их номерам в статье.
Из-за неоднозначности в фазе он скорее предлагает:
function [instantaneous_frequency] = f3(analytic_signal,Fs,T)
x = real(analytic_signal);
y = imag(analytic_signal);
diff_x = diff(x);
diff_y = diff(y);
factor = Fs/(2*pi);
a = x(2:end).*diff_y;
b = y(2:end).*diff_x;
c = x(2:end).^2;
d = y(2:end).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Insert leading 0 in return-vector to maintain size
instantaneous_frequency = [0 instantaneous_frequency];
end
function[instantaneous_frequency] = f9(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(2*pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = x(1:end-T).*x(1+T:end);
d = y(1:end-T).*y(1+T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append 0 to return-vector to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = f11(analytic_signal, Fs, T)
x = real(analytic_signal);
y = imag(analytic_signal);
factor = Fs/(4*pi*T);
a = x(1:end-2*T).*y(1+2*T:end);
b = x(1+2*T:end).*y(1:end-2*T);
c = x(1:end-2*T).*x(1+2*T:end);
d = y(1:end-2*T).*y(1+2*T:end);
instantaneous_frequency = factor.*atan((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [zeros(1,T) instantaneous_frequency zeros(1,T)];
end
function [instantaneous_frequency] = formula14(analytic_signal, Fs, T);
x = real(analytic_signal);
y = imag(analytic_signal);
factor = 2*Fs/(pi*T);
a = x(1:end-T).*y(1+T:end);
b = x(1+T:end).*y(1:end-T);
c = (x(1:end-T)+x(1+T:end)).^2;
d = (y(1:end-T)+y(1+T:end)).^2;
instantaneous_frequency = factor * ((a-b)./(c+d));
% Append and insert 0s to maintain size
instantaneous_frequency = [instantaneous_frequency zeros(1,T)];
end
Во всех трех приближениях Формулы T были установлены на Fs (T = Fs = 1000 = 1 с), как это предлагается в статье.
Теперь мой вопрос:
- Формулы f2 и f3 возвращают один и тот же результат для чистого сигнала ЛЧМ. Я думаю, что это хорошо, так как они рассчитывают одинаково. Три метода приближения не возвращают то же самое, даже то, что близко к нему! Почему это так? (Я надеюсь, что это не просто ошибка программирования ...)
- Несмотря на то, что они возвращают то же самое, особенно в конце сюжета они начинают «покачивания» много . Чем это объясняется? Сначала я подумал о чем-то вроде псевдонимов, но моя частота дискретизации довольно высока по сравнению с частотой сигналов, поэтому я думаю, что это можно исключить.
По крайней мере, f2 и f3 кажутся подходящими для чистого сигнала ЛЧМ, но все методы, включая f2 и f3, не работают ужасно, когда речь идет о более чем одной частоте в сигнале. В действительности наличие в сигнале более одной частоты - это всегда так. Так как же получить (более или менее) правильную мгновенную частоту?
- Я даже не знаю, чего ожидать, когда в сигнале присутствует более одной частоты. Вычисление возвращает одно число для данного момента времени, так что он должен делать, когда, как здесь, присутствует больше частот? Вернуть среднее значение всех частот или что-то в этом роде?
И мой, пожалуй, самый важный вопрос , как это обрабатывается в реальном и разработанном программном обеспечении? Допустим, я хочу узнать мгновенную частоту модулированного сигнала за 1,75 с, и я выбрал метод f2, чем я могу «повезти» и получу число, близкое к 6 [Гц], что, скорее всего, является правильным ответом, или я выберите мои результаты в нескольких образцах рядом с ним, и внезапно я получу какой-нибудь проводной, очень высокий результат, потому что я, к сожалению, выбрал значение в пике. Как это можно сделать? Постобработкой со средним или даже лучше медианным фильтром? Я думаю, что даже это может быть очень сложно, особенно в регионах, где много шипов находятся рядом друг с другом.
И последний, не очень важный вопрос, почему большинство статей, которые я нахожу на мгновенных частотах, относятся к области географии, особенно при расчете сейсмографических событий, таких как землетрясения. Бумага Барна также берет это как пример. Разве мгновенная частота не интересна во многих областях?
Вот и все, я очень благодарен за каждый ответ, особенно когда кто-то дает мне советы о том, как реализовать его в реальном программном проекте ;)
С уважением, Патрик