傅里叶变换FFT和IFFT在音频去噪的应用

FFT

FFT是DFT的快速算法,可以将一个信号从时域变换到频域。

有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。

另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。

去掉FFT变换时,频谱中的直流分量

直流分量:理论中,输入=0时,输出=0,没有什么直流分量的;

直流分量是输入信号带入的。

在模拟部分的电路中,元件输出会有直流漂移,即输出应该为零时,实际上是一个直流电压。

通常数字信号去直流直接减去均值即可。

IFFT

IFFT的计算原理是将频域(频域是复数)数据进行取共轭复数(虚部取反),然后进行FFT变换,这样便将频域信号转换到时域。
 

代码模块介绍

用到的库

# 用于保存音频
import wave
#数学库
import numpy as np
import matplotlib.pyplot as plt

生成余弦波和噪声

x=np.arange(0,5,.00005)
y=np.cos(2000*np.pi*x)
noise=np.random.rand(len(x))

保存音频

def saveAudio(filename,data):
    with wave.open(filename + '.wav', 'wb') as wavfile:
        wavfile.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wavfile.writeframes(data)

加噪声

y=y+noise

saveAudio("加噪音",y)

 离散傅里叶变换,得到一组可以表示各次谐波的幅值与相位的复数(0点为直流分量)

ft_y=np.fft.fft(y)

傅里叶反变换,并保存音频

saveAudio("去噪音",np.fft.ifft(ft_y))

完整代码:

# 用于保存音频
import wave
#数学库
import numpy as np
import matplotlib.pyplot as plt

def saveAudio(filename,data):
    with wave.open(filename + '.wav', 'wb') as wavfile:
        wavfile.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wavfile.writeframes(data)

#中文支持和布局调整
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
plt.rcParams['figure.figsize']=(15,8)

plt.subplots_adjust(left=None, bottom=None, right=None, top=None,
                wspace=0.5, hspace=0.5)


#生成余弦波和噪音
x=np.arange(0,5,.00005)
y=np.cos(2000*np.pi*x)
noise=np.random.rand(len(x))
print("noise value:", noise)

#保存原音频
saveAudio("原音频",y)

#保存原音频
b = y.copy()
print("yuan yin pin", b)

#加噪音
y=y+noise
saveAudio("加噪音",y)

#离散傅里叶变换,得到一组可以表示各次谐波的幅值与相位的复数(0点为直流分量)
ft_y=np.fft.fft(y)
n = len(y) 
print("len of y:" + str(n))
print("len of fft y:" + str(len(ft_y)))
print("ft_y value", ft_y)

#取得最大的振幅的二分之一
avg=np.max(abs(ft_y[1:]))/2


plt.subplot(233)
plt.title("降噪前的频率振幅谱")
plt.plot(abs(ft_y[0:]))

#干掉掉直流分量和小于最大振幅二分之一的信号
#ft_y[0]=0+0j
ft_y[np.where(abs(ft_y)<=avg)]=0+0j
print("qqq:",np.fft.ifft(ft_y))
saveAudio("去噪音",np.fft.ifft(ft_y))

plt.subplot(231)
plt.title("原音频")
plt.plot(b[0:200])

plt.subplot(232)
plt.title("加了噪音的原音频")
plt.plot(y[0:200])

plt.subplot(234)
plt.plot(abs(ft_y[0:]))
plt.title("降噪后的频率振幅谱")
plt.xlabel("frequency")
plt.ylabel("amplitude")
plt.subplot(235)
plt.title("降噪后的音频")
plt.plot(np.fft.ifft(ft_y)[0:200])


plt.subplot(236)
plt.title("原音频频谱")
plt.plot(abs(np.fft.fft(b))[0:200])

plt.show()

降噪前后波形对比图

猜你喜欢

转载自blog.csdn.net/u013177138/article/details/124228325