python基於傅里葉變換的頻率濾波-音頻降噪

1. 傅里葉簡介

法國科學家傅里葉提出,任何一條週期曲線,無論多麼跳躍或不規則,都能表示成一組光滑正弦曲線疊加之和。

傅里葉變換即基於傅里葉定理,對一條不規則的曲線進行拆解,從而得到一組光滑正弦曲線函數的過程。

例如:彈鋼琴
假設有一時間域函數:y = f(x),根據傅里葉理論它可以被分解爲一系列正弦函數的疊加,這些正弦函數具有不同的振幅A,頻率ω或初相位φ。:
y=A1sin(ω1x+ϕ1)+A2sin(ω2x+ϕ2)+A2sin(ω2x+ϕ2)+... y = A_1sin(\omega_1x+\phi_1) + A_2sin(\omega_2x+\phi_2) + A_2sin(\omega_2x+\phi_2) + ...
在信息處理過程中,通常處理步驟是:

  • 1.通過傅里葉變換是將時域(即時間域)上的信號轉變爲頻域(即頻率域)上的信號,進行相應的濾波去噪、增強、統計分析等處理。
  • 2.處理後的信號可以通過傅里葉逆變換在轉換成時域信號,從而達到相應的信號處理效果。

2. 示例說明

該示例主要實現通過傅里葉變換實現一段音頻數據的降噪處理過程。主要過程如下:

part1. 利用 scipy.io.wavfile.read() 讀取音頻文件,該接口會返回該音頻數據的採用率sample_reate和每個採樣點的位移值sigs,根據這組採樣點可以繪製音頻的時域圖,這裏爲了顯示截取了前178個採樣點。

part2. 利用numpy.fft.fft()接口完成時域信號到頻域信號的轉換,並繪製音頻的頻域圖。

part3. 該部分示意一個簡單的去噪過程,音頻中的高頻信號爲需要保留的信息,其他都爲噪聲信號,這裏簡單的將噪聲信號統一設置爲0僅保留了高頻信號;

part4. 將去噪完的信息通過numpy.fft.ifft()接口逆傅里葉變換成時域信號。

'''
基於傅里葉變換的頻域濾波。
'''
import numpy as np
import numpy.fft as nf
import matplotlib.pyplot as plt
import scipy.io.wavfile as wf

#讀取音頻文件,將其按照採樣率離散化,返回採樣率和信號
#sample_reate:採樣率(每秒採樣個數), sigs:每個採樣位移值。
#================1.原始音頻信號,時域信息=================================
sameple_rate,sigs = wf.read('../da_data/noised.wav')
print('採樣率:{}'.format(sameple_rate))
print('信號點數量:{}'.format(sigs.size))
sigs = sigs/(2**15)

times = np.arange(len(sigs))/sameple_rate
plt.figure('Filter',facecolor='lightgray')
plt.subplot(221)
plt.title('Time Domain',fontsize=16)
plt.ylabel('Signal',fontsize=12)
plt.grid(linestyle=':')
plt.plot(times[:178],sigs[:178],color='dodgerblue',label='Noised Signal')
plt.legend()

#==================2.轉換爲頻率域信號===================================
#基於傅里葉變換,獲取音頻頻域信息
#繪製音頻頻域的: 頻域/能量圖像
freqs = nf.fftfreq(sigs.size, 1/sameple_rate)
complex_arry = nf.fft(sigs)
pows = np.abs(complex_arry)
plt.subplot(222)
plt.title('Frequence Domain',fontsize=16)
plt.ylabel('power',fontsize=12)
plt.grid(linestyle=':')
plt.semilogy(freqs[freqs>0],pows[freqs>0],color='dodgerblue',label='Noised Freq')
plt.legend()

#==============第3步=================================================
#將低能噪聲去除後繪製音頻頻域的: 頻率/能量圖書
fun_freq = freqs[pows.argmax()] #獲取頻率域中能量最高的
noised_idx = np.where(freqs != fun_freq)[0] #獲取所有噪聲的下標
ca = complex_arry[:]
ca[noised_idx] = 0 #高通濾波
filter_pows = np.abs(complex_arry)

plt.subplot(224)
plt.ylabel('power',fontsize=12)
plt.grid(linestyle=':')
plt.plot(freqs[freqs>0],filter_pows[freqs>0],color='dodgerblue',label='Filter Freq')
plt.legend()
#================第4步==============================================
filter_sigs = nf.ifft(ca)
plt.subplot(223)
plt.title('Time Domain',fontsize=16)
plt.ylabel('Signal',fontsize=12)
plt.grid(linestyle=':')
plt.plot(times[:178],filter_sigs[:178],color='dodgerblue',label='Filter Signal')
plt.legend()

#重新生成音頻文件
filter_sigs = (filter_sigs*(2**15)).astype('i2')
wf.write('../da_data/filter.wav',sameple_rate,filter_sigs)

plt.tight_layout()
plt.show()

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章