用傅里叶变换给音频降噪

# Enabling the `widget` backend.
# This requires jupyter-matplotlib a.k.a. ipympl.
# ipympl can be install via pip or conda.
#%matplotlib widget

用傅里叶变换给音频降噪

FFT提供幅度和相位。振幅被编码为复数(sqrt(x ^ 2 + y ^ 2))的大小,而相位被编码为角度(atan2(y,x))。
为了从FFT得到严格实数结果,输入信号必须具有偶数对称性。
如果你关心的只是强度,那么复数的大小足以用于分析。
引用自这里

# 用于保存音频
import wave
def saveAudio(filename,data):
    with wave.open(filename + '.wav', 'wb') as wavfile:
        wavfile.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wavfile.writeframes(data)
#数学库
import numpy as np
import matplotlib.pyplot as plt

#中文支持和布局调整
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.sin(2000*np.pi*x)
noise=np.random.rand(len(x))

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

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

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

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


plt.subplot(222)
plt.title("降噪前的频率振幅谱")
plt.plot(abs(ft_y))

#干掉掉直流分量和小于最大振幅二分之一的信号
ft_y[0]=0+0j
ft_y[np.where(abs(ft_y)<=avg)]=0+0j

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

plt.subplot(221)
plt.title("加了噪音的原音频")
plt.plot(y)

plt.subplot(223)
plt.plot(abs(ft_y))
plt.title("降噪后的频率振幅谱")
plt.xlabel("frequency")
plt.ylabel("amplitude")
plt.subplot(224)
plt.title("降噪后的音频")
plt.plot(np.fft.ifft(ft_y))

plt.show()

用傅里叶变换给音频降噪_第1张图片

精度不够的下场!!!

你看看这画的什么鬼畜玩意!!!

import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,5,.05)#100个采样点根本不够
y=20*np.sin(1000*np.pi*x)
plt.plot(y)
plt.show()

用傅里叶变换给音频降噪_第2张图片

import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,5,.00005)
y=20*np.sin(1000*np.pi*x)
plt.plot(y)
plt.show()

用傅里叶变换给音频降噪_第3张图片

你可能感兴趣的:(信号与系统,FFT,信号与系统,傅里叶)