簡體   English   中英

如何在python中提取與fft值相關的頻率

[英]how to extract frequency associated with fft values in python

我在 numpy 中使用了fft函數,這導致了一個復雜的數組。 如何獲得准確的頻率值?

np.fft.fftfreq告訴您與系數相關的頻率:

import numpy as np

x = np.array([1,2,1,0,1,2,1,0])
w = np.fft.fft(x)
freqs = np.fft.fftfreq(len(x))

for coef,freq in zip(w,freqs):
    if coef:
        print('{c:>6} * exp(2 pi i t * {f})'.format(c=coef,f=freq))

# (8+0j) * exp(2 pi i t * 0.0)
#    -4j * exp(2 pi i t * 0.25)
#     4j * exp(2 pi i t * -0.25)

OP 詢問如何以赫茲為單位找到頻率。 我相信公式是frequency (Hz) = abs(fft_freq * frame_rate)

這里有一些代碼可以證明這一點。

首先,我們制作一個 440 Hz 的波形文件:

import math
import wave
import struct

if __name__ == '__main__':
    # http://stackoverflow.com/questions/3637350/how-to-write-stereo-wav-files-in-python
    # http://www.sonicspot.com/guide/wavefiles.html
    freq = 440.0
    data_size = 40000
    fname = "test.wav"
    frate = 11025.0
    amp = 64000.0
    nchannels = 1
    sampwidth = 2
    framerate = int(frate)
    nframes = data_size
    comptype = "NONE"
    compname = "not compressed"
    data = [math.sin(2 * math.pi * freq * (x / frate))
            for x in range(data_size)]
    wav_file = wave.open(fname, 'w')
    wav_file.setparams(
        (nchannels, sampwidth, framerate, nframes, comptype, compname))
    for v in data:
        wav_file.writeframes(struct.pack('h', int(v * amp / 2)))
    wav_file.close()

這將創建文件test.wav 現在我們讀入數據,對其進行FFT,找到功率最大的系數,並找到對應的fft頻率,然后轉換為赫茲:

import wave
import struct
import numpy as np

if __name__ == '__main__':
    data_size = 40000
    fname = "test.wav"
    frate = 11025.0
    wav_file = wave.open(fname, 'r')
    data = wav_file.readframes(data_size)
    wav_file.close()
    data = struct.unpack('{n}h'.format(n=data_size), data)
    data = np.array(data)

    w = np.fft.fft(data)
    freqs = np.fft.fftfreq(len(w))
    print(freqs.min(), freqs.max())
    # (-0.5, 0.499975)

    # Find the peak in the coefficients
    idx = np.argmax(np.abs(w))
    freq = freqs[idx]
    freq_in_hertz = abs(freq * frate)
    print(freq_in_hertz)
    # 439.8975

與 DFT 值相關的頻率(在 python 中)

通過fft (快速傅立葉變換),我們了解了一大類算法中的一個成員,這些算法能夠快速計算等采樣信號的 DFT(離散傅立葉變換)。

一個DFT N個復號的列表轉換成N個復號的列表,了解這兩個名單是周期性的,周期為N。

在這里,我們處理fftnumpy實現。

在很多情況下,你會想到

  • 在長度為N的時域中定義的信號x ,以恆定間隔dt采樣,
  • 它的 DFT X (這里特別是X = np.fft.fft(x) ),其元素在頻率軸上以采樣率dw采樣。

一些定義

  • 的信號的周期(也稱為持續時間) x ,在采樣dtN樣本是被

    T = dt*N
  • X的基本頻率(Hz 和 rad/s),你的 DFT 是

    df = 1/T dw = 2*pi/T # =df*2*pi
  • 最高頻率是奈奎斯特頻率

    ny = dw*N/2

    (它不是dw*N

與 DFT 中特定元素相關的頻率

對於給定索引0<=n<N對應於X = np.fft.fft(x)的元素的頻率可以計算如下:

def rad_on_s(n, N, dw):
    return dw*n if n<N/2 else dw*(n-N)

或在一次掃描中

w = np.array([dw*n if n<N/2 else dw*(n-N) for n in range(N)])

如果您更喜歡以 Hz、 s/w/f/為單位考慮頻率

f = np.array([df*n if n<N/2 else df*(n-N) for n in range(N)])

使用這些頻率

如果你想修改原始信號x -> y以頻率函數的形式在頻域中應用一個算子,要走的路是計算w

Y = X*f(w)
y = ifft(Y)

介紹np.fft.fftfreq

當然numpy有一個方便的函數np.fft.fftfreq ,它返回無量綱的頻率而不是有維的頻率但它就像

f = np.fft.fftfreq(N)*N*df
w = np.fft.fftfreq(N)*N*dw

因為df = 1/TT = N/spssps是每秒的樣本數)也可以寫

f = np.fft.fftfreq(N)*sps

頻率只是數組的索引。 / the array's length (radians per unit).在索引n 處,頻率為 2 / 陣列的長度(每單位弧度)。 考慮:

>>> numpy.fft.fft([1,2,1,0,1,2,1,0])
array([ 8.+0.j,  0.+0.j,  0.-4.j,  0.+0.j,  0.+0.j,  0.+0.j,  0.+4.j,
        0.+0.j])

結果在索引 0、2 和 6 處具有非零值。有 8 個元素。 這意味着

       2πit/8 × 0       2πit/8 × 2       2πit/8 × 6
    8 e           - 4i e           + 4i e
y ~ ———————————————————————————————————————————————
                          8

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM