2010-11-19 41 views
6

Tôi muốn biết tần suất dữ liệu. Tôi đã có một chút ý tưởng rằng nó có thể được thực hiện bằng cách sử dụng FFT, nhưng tôi không chắc chắn làm thế nào để làm điều đó. Một khi tôi đã chuyển toàn bộ dữ liệu sang FFT, thì nó cho tôi 2 đỉnh, nhưng làm thế nào tôi có thể nhận được tần số?Làm cách nào để tính toán tần suất dữ liệu bằng FFT?

Cảm ơn rất nhiều trước.

+0

FFT sẽ cung cấp cho bạn tần suất các thành phần hình sin của tín hiệu của bạn. Nếu bạn muốn đo tần số của tín hiệu thực (bất kỳ hình dạng nào) hơn bạn phải quên FFT và sử dụng quét mẫu để không vượt qua, hoặc tìm kiếm đỉnh cao nhất vv ... phụ thuộc khá nhiều vào hình dạng và bù đắp tín hiệu của bạn. btw trên FFT bạn có 2 peeks một là gương của người đầu tiên nếu tín hiệu đầu vào là trên tên miền thực) vì vậy bỏ qua nửa thứ hai của FFT – Spektre

Trả lời

-6

Tần số = tốc độ/bước sóng.

Bước sóng là khoảng cách giữa hai đỉnh.

+0

Hai đỉnh trong miền * tần số *. –

+0

Steve: Không hoàn toàn. Nếu dữ liệu của bạn thực sự định kỳ với một mức tối đa, thì khoảng cách giữa các đỉnh sẽ cho bạn chính xác 1/f. Tuy nhiên, thông thường bạn đang xử lý dữ liệu bán định kỳ, mà phân tích toán học tiêu chuẩn được áp dụng cho dữ liệu định kỳ không hoạt động. –

+0

Ý tôi trong bình luận trước đó của tôi là tác giả đã có được hai đỉnh trong miền tần số. Câu trả lời này giải thích sai hai đỉnh nằm trong miền thời gian. –

8

Giả sử x[n] = cos(2*pi*f0*n/fs) nơi f0 là tần số của hình sin của bạn trong Hertz, n=0:N-1, và fs là tỷ lệ lấy mẫu của x trong các mẫu mỗi giây.

Hãy để X = fft(x). Cả hai xX có chiều dài N. Giả sử X có hai đỉnh ở số n0N-n0.

Sau đó, tần số xoangf0 = fs*n0/N Hertz.

Ví dụ: fs = 8000 mẫu mỗi giây, N = 16000 mẫu. Do đó, x kéo dài hai giây.

Giả sử X = fft(x) có các mức cao nhất là 2000 và 14000 (= 16000-2000). Do đó, f0 = 8000 * 2000/16000 = 1000 Hz.

+0

Điều này là chính xác. Tuy nhiên, lưu ý rằng dữ liệu được cung cấp bởi các thuật toán fft không được định trước do thiết kế fft (mạng bướm). Nó phải được thay đổi trước khi diễn giải các giá trị. – ypnos

4

Nếu bạn đang xem kết quả độ lớn từ FFT thuộc loại được sử dụng phổ biến nhất, thì thành phần tần số hình sin mạnh mẽ của dữ liệu thực sẽ hiển thị ở hai nơi, một lần ở nửa dưới cùng với ảnh gương liên hợp phức tạp của nó ở nửa trên. Cả hai đỉnh đều đại diện cho cùng một phổ đỉnh và cùng tần số (đối với dữ liệu thực tế nghiêm ngặt). Nếu các số bin kết quả FFT bắt đầu ở 0 (không), thì tần số của thành phần hình sin được biểu diễn bởi thùng trong nửa dưới của kết quả FFT rất có thể.

Frequency_of_Peak = Data_Sample_Rate * Bin_number_of_Peak/Length_of_FFT ; 

Hãy chắc chắn để làm việc ra đơn vị thích hợp của bạn trong phương trình trên (để có được các đơn vị của chu kỳ mỗi giây, mỗi hai tuần, mỗi kiloparsec, vv)

Lưu ý rằng trừ khi bước sóng của dữ liệu là một chính xác số nguyên submultiple của chiều dài FFT, đỉnh thực tế sẽ là giữa các thùng, do đó phân phối năng lượng giữa nhiều thùng kết quả FFT gần đó. Vì vậy, bạn có thể phải suy ra để ước tính tốt hơn tần số đỉnh. Các phương thức nội suy phổ biến để tìm một ước lượng tần số chính xác hơn là 3 điểm parabolic và Sinc convolution (gần như giống với việc sử dụng một FFT không có lớp đệm dài hơn).

6

Đây là những gì có lẽ bạn đang tìm kiếm:

Khi bạn nói về tính toán tần số của một tín hiệu, có lẽ bạn không nên quan tâm đến những con sóng sin thành phần. Đây là những gì FFT cung cấp cho bạn. Ví dụ, nếu bạn tổng hợp sin (2 * pi * 10x) + sin (2 * pi * 15x) + sin (2 * pi * 20x) + sin (2 * pi * 25x), bạn có thể muốn phát hiện "tần số "là 5 (hãy xem đồ thị của hàm này). Tuy nhiên, FFT của tín hiệu này sẽ phát hiện độ lớn của cho tần suất 5.

Điều bạn có thể quan tâm nhiều hơn là dấu hiệu thời gian của tín hiệu. Đó là, khoảng thời gian mà tại đó tín hiệu trở thành giống như chính nó. Vì vậy, hầu hết những gì bạn muốn là tự động tự tương quan. Tìm kiếm. Điều này về cơ bản sẽ cung cấp cho bạn một thước đo như thế nào tự tương tự như tín hiệu là chính nó sau khi được chuyển qua một số tiền nhất định. Vì vậy, nếu bạn tìm thấy một đỉnh trong tự tương quan, điều đó sẽ chỉ ra rằng tín hiệu phù hợp với chính nó khi chuyển qua số tiền đó. Có rất nhiều môn toán mát đằng sau nó, nhìn nó lên nếu bạn quan tâm, nhưng nếu bạn chỉ muốn nó hoạt động, chỉ cần làm điều này:

  1. Window tín hiệu, sử dụng một cửa sổ mịn (một cosin sẽ làm Các cửa sổ nên được ít nhất hai lần lớn như thời kỳ lớn nhất mà bạn muốn phát hiện. 3 lần như lớn sẽ cho kết quả tốt hơn). (xem http://zone.ni.com/devzone/cda/tut/p/id/4844 nếu bạn đang bối rối).

  2. Lấy FFT (tuy nhiên, hãy đảm bảo kích thước FFT lớn gấp đôi cửa sổ, với nửa thứ hai được đệm bằng số không. Nếu kích thước FFT chỉ là kích thước của cửa sổ, bạn sẽ thực sự có hiệu quả các tròn tự tương quan, mà không phải những gì bạn muốn là. thấy https://en.wikipedia.org/wiki/Discrete_Fourier_transform#Circular_convolution_theorem_and_cross-correlation_theorem)

  3. Thay thế tất cả các hệ số của FFT với giá trị vuông của họ (thật^2 + IMAG^2). Điều này là có hiệu quả lấy autocorrelation.

  4. Lấy IFFT

  5. Tìm đỉnh lớn nhất trong IFFT. Đây là chu kỳ mạnh nhất của dạng sóng. Bạn thực sự có thể thông minh hơn một chút, trong đó đỉnh cao bạn chọn, nhưng đối với hầu hết các mục đích, điều này là đủ. Để tìm tần số, bạn chỉ cần lấy f = 1/T.

+0

Cảm ơn câu trả lời rõ ràng ở đây, đã xem xét rất nhiều thông tin về chủ đề này và điều này đã giúp tôi giải quyết thêm một chút. – Adamski

5

Nếu bạn có một tín hiệu với một tần số (ví dụ:

y = sin(2 pi f t) 

Với:

  • tín hiệu thời gian y
  • f tần số trung tâm
  • t thời gian

Sau đó, bạn sẽ nhận được hai đỉnh, một ở tần số tương ứng với f và một ở tần số tương ứng với -f.

Vì vậy, để đến tần số, có thể hủy phần tần số âm. Nó nằm sau phần tần số dương. Hơn nữa, phần tử đầu tiên trong mảng là độ lệch DC, do đó tần số là 0. (Hãy coi chừng bù đắp này thường lớn hơn 0, vì vậy các thành phần tần số khác có thể bị lừa bởi nó.)

Trong mã : (Tôi đã viết nó trong python, nhưng nó phải đơn giản như nhau trong C#):

import numpy as np 
from pylab import * 
x = np.random.rand(100) # create 100 random numbers of which we want the fourier transform 
x = x - mean(x) # make sure the average is zero, so we don't get a huge DC offset. 
dt = 0.1 #[s] 1/the sampling rate 
fftx = np.fft.fft(x) # the frequency transformed part 
# now discard anything that we do not need.. 
fftx = fftx[range(int(len(fftx)/2))] 
# now create the frequency axis: it runs from 0 to the sampling rate /2 
freq_fftx = np.linspace(0,2/dt,len(fftx)) 
# and plot a power spectrum 
plot(freq_fftx,abs(fftx)**2) 
show() 

Bây giờ tần số được đặt ở đỉnh lớn nhất.

+0

+1 để trừ đi giá trị trung bình để chế ngự bù trừ DC. Theo tôi, sẽ rõ ràng hơn nếu bạn sử dụng tần số lấy mẫu để lập chỉ mục tần suất và không phải là khoảng thời gian lấy mẫu. –

+1

Rất tuyệt! Nhưng có một lỗi đánh máy trong câu trả lời: dòng âm mưu phải là cốt truyện (freq_fftx, abs (fftx) ** 2) –

+0

Cảm ơn! Sửa lỗi. – Dirklinux

1

Giả sử bạn sử dụng biến đổi Fourier rời rạc để xem xét tần số, thì bạn phải cẩn thận về cách diễn giải tần số chuẩn hóa thành tần số chuẩn (ví dụ: Hz).

Theo FFTW tutorial về cách tính toán phổ năng lượng của một tín hiệu:

#include <rfftw.h> 
... 
{ 
    fftw_real in[N], out[N], power_spectrum[N/2+1]; 
    rfftw_plan p; 
    int k; 
    ... 
    p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); 
    ... 
    rfftw_one(p, in, out); 
    power_spectrum[0] = out[0]*out[0]; /* DC component */ 
    for (k = 1; k < (N+1)/2; ++k) /* (k < N/2 rounded up) */ 
      power_spectrum[k] = out[k]*out[k] + out[N-k]*out[N-k]; 
    if (N % 2 == 0) /* N is even */ 
      power_spectrum[N/2] = out[N/2]*out[N/2]; /* Nyquist freq. */ 
    ... 
    rfftw_destroy_plan(p); 
} 

Lưu ý nó xử lý độ dài dữ liệu mà không phải là chẵn. Lưu ý đặc biệt nếu chiều dài dữ liệu được đưa ra, FFTW sẽ cung cấp cho bạn một "thùng" tương ứng với tần số Nyquist (tỷ lệ mẫu chia cho 2). Nếu không, bạn không nhận được nó (tức là thùng cuối cùng nằm ngay dưới Nyquist).

Một MATLAB example là tương tự, nhưng họ đang lựa chọn chiều dài của 1000 (một số chẵn) ví dụ:

N = length(x); 
xdft = fft(x); 
xdft = xdft(1:N/2+1); 
psdx = (1/(Fs*N)).*abs(xdft).^2; 
psdx(2:end-1) = 2*psdx(2:end-1); 
freq = 0:Fs/length(x):Fs/2; 

Nói chung, nó có thể được thực hiện (của DFT) phụ thuộc. Bạn nên tạo một sóng sin tinh khiết thử nghiệm ở tần số đã biết và sau đó đảm bảo tính toán cho cùng một số.

Các vấn đề liên quan