Tôi chưa quen với nguyên tắc tính tần số tức thời và đã đưa ra rất nhiều câu hỏi về nó. Bạn tìm thấy tất cả chúng trong một danh sách gạch đầu dòng ở cuối văn bản này. Văn bản có thể hơi dài, xin lỗi vì điều đó, nhưng tôi thực sự đã cố gắng tự mình giải quyết vấn đề đó.
Vì vậy, tôi quan tâm đến tần số tức thời của tín hiệu có giá trị thực . Việc tính toán được thực hiện với sự trợ giúp của tín hiệu phân tích , trong đó là phép biến đổi Hilbert của .
Để tính tần số tức thời từ tín hiệu phân tích tôi đã làm theo bài báo:
Việc tính toán tần số tức thời và băng thông tức thời của Arthur E. Barns từ năm 1992. Trong bài báo này, ông giới thiệu nhiều phương pháp để tính tần số tức thời. Tôi viết ra, tất cả các công thức anh ấy đề xuất (và tôi đã sử dụng) trong một khoảnh khắc.
Để "học", tôi đã chơi xung quanh với một tín hiệu rất đơn giản và hai tín hiệu phức tạp hơn một chút, trong MATLAB, và muốn có được tần số tức thời của chúng.
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
Các sơ đồ trong miền thời gian của ba tín hiệu này trông như sau:
Các sơ đồ của tất cả các tần số tức thời tôi nhận được sau khi áp dụng tất cả các phương pháp từ bài báo, như sau:
Tần số tức thời của tín hiệu chirp thuần túy: Tần số tức thời của tín hiệu chirp có thêm hình sin: Tần số tức thời của tín hiệu chirp được điều chế: Xin lưu ý rằng trong cả ba hình ảnh, trục y của ô 3 và 4 đều được phóng to, do đó biên độ của các tín hiệu đó tín hiệu rất nhỏ!
Khả năng đầu tiên để có được từ tín hiệu phân tích đến tần số tức thời là:
trong đó là pha tức thời. Tôi nghĩ rằng đây là phương pháp phổ biến nhất được sử dụng hiện nay, ít nhất là trên trang web của MATLAB, nó được tính theo cách đó. Mã này trông như sau:
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
Trong bài báo Barns hiện đề xuất (hay nói đúng hơn là biên dịch) bốn cách khác để tính tần số tức thời từ tín hiệu phân tích. Ông cũng đề cập đến công thức trên, nhưng ý kiến cho rằng nó không thực tế do sự mơ hồ trong giai đoạn. Tôi đoán, anh ta không biết unwrap()
phương pháp này, hay nói chính xác hơn là toán học đằng sau nó. (Tôi, bản thân tôi đã tìm hiểu về phương pháp đó ngay hôm nay, khi xem xét một số mã nguồn khác về tần số tức thời)
Trong bài báo của mình, công thức có nhãn Số (2), do đó, tôi đã cho f (t) chỉ số 2. Tất cả các chỉ mục khác tương ứng với các số của chúng trong bài báo.
Vì sự mơ hồ trong pha, anh ta gợi ý:
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
Sau đó, Barner đưa ra thêm ba công thức mà anh ta đặt tên là "xấp xỉ tần số tức thời":
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
Trong cả 3 Công thức gần đúng T được đặt thành Fs (T = Fs = 1000 = 1s), như được đề xuất trong bài báo.
Bây giờ câu hỏi của tôi là:
- Công thức f2 và f3 trả về cùng một kết quả cho tín hiệu chirp thuần túy. Tôi nghĩ điều đó tốt, vì họ tính toán như nhau. Ba phương pháp gần đúng không trả lại giống nhau, thậm chí không phải là một cái gì đó gần với nó! Tại sao lại như vậy? (Tôi hy vọng nó không chỉ là một lỗi lập trình ...)
- Mặc dù họ trở lại như cũ, đặc biệt là ở phần cuối của cốt truyện, họ bắt đầu 'ngọ nguậy' rất nhiều . Giải thích cho điều đó là gì? Đầu tiên tôi nghĩ về một cái gì đó như răng cưa, nhưng tần số lấy mẫu của tôi khá cao, so với tần số của tín hiệu, vì vậy tôi nghĩ rằng có thể loại trừ được.
Ít nhất f2 và f3 dường như hoạt động phù hợp với tín hiệu chirp thuần túy, nhưng tất cả các phương pháp, bao gồm f2 và f3 dường như không thành công khủng khiếp, khi có nhiều hơn một tần số trong tín hiệu. Trong thực tế, có nhiều hơn một tần số trong một tín hiệu là luôn luôn như vậy. Vậy làm thế nào để có thể có được tần số tức thời (ít nhiều) chính xác?
- Tôi thực sự thậm chí không biết những gì mong đợi, khi có nhiều hơn một tần số xuất hiện trong tín hiệu. Tính toán trả về một số cho một thời điểm nhất định, vậy nó nên làm gì khi, như ở đây, có nhiều tần số hơn? Trả về trung bình của tất cả các tần số hoặc một cái gì đó như thế?
Và câu hỏi có lẽ quan trọng nhất của tôi là, làm thế nào mà nó được xử lý trong một phần mềm thực sự và công phu? Giả sử tôi muốn biết tần số tức thời của tín hiệu được điều chế ở mức 1,75 giây và tôi đã chọn phương pháp f2, hơn là tôi có thể 'may mắn' và nhận được một số gần 6 [Hz] rất có thể là câu trả lời đúng, hoặc tôi chọn kết quả của tôi một vài mẫu bên cạnh và đột nhiên tôi nhận được một số kết nối có dây, lên cao, vì tôi không may chọn một giá trị trong đột biến. Làm thế nào điều này có thể được xử lý? Bằng cách xử lý hậu kỳ với bộ lọc trung bình hoặc thậm chí tốt hơn? Tôi nghĩ thậm chí điều đó có thể trở nên thực sự khó khăn, đặc biệt là ở các khu vực có nhiều gai nằm cạnh nhau.
Và một câu hỏi cuối cùng, không quá quan trọng, tại sao hầu hết các bài báo tôi tìm thấy về tần số tức thời là từ khu vực địa lý, đặc biệt là trong việc tính toán các sự kiện địa chấn như động đất. Bài báo của Barne cũng lấy đó làm ví dụ. Không phải là tần số tức thời thú vị trong nhiều lĩnh vực?
Cho đến nay, tôi rất biết ơn về mọi câu trả lời, đặc biệt là khi ai đó cho tôi lời khuyên về cách triển khai nó trong một dự án phần mềm thực sự ;)
Trân trọng, Patrick