Python 音频信号过滤不好
Python audio signal doesn't filter well
我需要获取一个嘈杂的 .wav 音频文件并过滤掉所有噪音。我必须使用傅立叶变换来完成。经过几天的研究和试验,我终于实现了一个有效的功能,问题是它并没有像我预期的那样工作。这是我制作的功能:
# Audio signal processing
from scipy.io.wavfile import read, write
import matplotlib.pyplot as plt
import numpy as np
from scipy.fft import fft, fftfreq, ifft
def AudioSignalProcessing(audio):
# Import the .wav format audio into two variables:
# sampling (int)
# audio signal (numpy array)
sampling, signal = read(audio)
# time duration of the audio
length = signal.shape[0] / sampling
# x axis based on the time duration
time = np.linspace(0., length, signal.shape[0])
# show original signal
plt.plot(time, signal)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Original signal")
plt.show()
# apply Fourier transform and normalize
transform = abs(fft(signal))
transform = transform/np.linalg.norm(transform)
# obtain frequencies
xf = fftfreq(transform.size, 1/sampling)
# show transformed signal (frequencies domain)
plt.plot(xf, transform)
plt.xlabel("Frecuency (Hz)")
plt.ylabel("Amplitude")
plt.title("Frequency domain signal")
plt.show()
# filter the transformed signal to a 40% of its maximum amplitude
threshold = np.amax(transform)*0.4
filtered = transform[np.where(transform > threshold)]
xf_filtered = xf[np.where(transform > threshold)]
# show filtered transformed signal
plt.plot(xf_filtered, filtered)
plt.xlabel("Frecuency (Hz)")
plt.ylabel("Amplitude")
plt.title("FILTERED time domain signal")
plt.show()
# transform the signal back to the time domain
filtrada = ifft(signal)
# show original signal filtered
plt.plot(time, filtrada)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Filtered signal")
plt.show()
# convert audio signal to .wav format audio
# write(audio.replace(".wav", " filtrado.wav"), sampling, filtrada.astype(signal.dtype))
return None
AudioSignalProcessing("audio.wav")
这是输出图:
Original signal
Transformed signal
Filtered transformed signal
Filtered audio signal
过滤后的频率看起来不像我认为的那样,而且在将过滤后的信号转换回音频后,它听起来一点也不好。另外,我尝试过使用不同的音频,但会发生相同的滤波器失真。
我建议在 https://dsp.stackexchange.com/ 询问详细的信号处理问题。
您似乎只想保留那些至少在最大分量的 40% 以内的频率分量。如果是这样的话:
保留DFT的复数形式,否则无法变回;所以从 transform = abs(fft(signal))
.
行中删除 abs
不要使用np.where
来“保持”你想要的频率;相反,将变换幅度低于阈值的位置设置为 0;就像是
transform[abs(transform) < 0.4 * max(abs(transform))] = 0
最后,对这个改变后的变换应用逆 DFT;您已将其应用于 signal
(请参阅第 filtrata = ifft(signal)
行)。 (您在绘制 filtrada 时可能会收到有关丢弃虚数值的警告。)
我需要获取一个嘈杂的 .wav 音频文件并过滤掉所有噪音。我必须使用傅立叶变换来完成。经过几天的研究和试验,我终于实现了一个有效的功能,问题是它并没有像我预期的那样工作。这是我制作的功能:
# Audio signal processing
from scipy.io.wavfile import read, write
import matplotlib.pyplot as plt
import numpy as np
from scipy.fft import fft, fftfreq, ifft
def AudioSignalProcessing(audio):
# Import the .wav format audio into two variables:
# sampling (int)
# audio signal (numpy array)
sampling, signal = read(audio)
# time duration of the audio
length = signal.shape[0] / sampling
# x axis based on the time duration
time = np.linspace(0., length, signal.shape[0])
# show original signal
plt.plot(time, signal)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Original signal")
plt.show()
# apply Fourier transform and normalize
transform = abs(fft(signal))
transform = transform/np.linalg.norm(transform)
# obtain frequencies
xf = fftfreq(transform.size, 1/sampling)
# show transformed signal (frequencies domain)
plt.plot(xf, transform)
plt.xlabel("Frecuency (Hz)")
plt.ylabel("Amplitude")
plt.title("Frequency domain signal")
plt.show()
# filter the transformed signal to a 40% of its maximum amplitude
threshold = np.amax(transform)*0.4
filtered = transform[np.where(transform > threshold)]
xf_filtered = xf[np.where(transform > threshold)]
# show filtered transformed signal
plt.plot(xf_filtered, filtered)
plt.xlabel("Frecuency (Hz)")
plt.ylabel("Amplitude")
plt.title("FILTERED time domain signal")
plt.show()
# transform the signal back to the time domain
filtrada = ifft(signal)
# show original signal filtered
plt.plot(time, filtrada)
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.title("Filtered signal")
plt.show()
# convert audio signal to .wav format audio
# write(audio.replace(".wav", " filtrado.wav"), sampling, filtrada.astype(signal.dtype))
return None
AudioSignalProcessing("audio.wav")
这是输出图:
Original signal
Transformed signal
Filtered transformed signal
Filtered audio signal
过滤后的频率看起来不像我认为的那样,而且在将过滤后的信号转换回音频后,它听起来一点也不好。另外,我尝试过使用不同的音频,但会发生相同的滤波器失真。
我建议在 https://dsp.stackexchange.com/ 询问详细的信号处理问题。
您似乎只想保留那些至少在最大分量的 40% 以内的频率分量。如果是这样的话:
保留DFT的复数形式,否则无法变回;所以从
行中删除transform = abs(fft(signal))
.abs
不要使用
np.where
来“保持”你想要的频率;相反,将变换幅度低于阈值的位置设置为 0;就像是transform[abs(transform) < 0.4 * max(abs(transform))] = 0
最后,对这个改变后的变换应用逆 DFT;您已将其应用于
signal
(请参阅第filtrata = ifft(signal)
行)。 (您在绘制 filtrada 时可能会收到有关丢弃虚数值的警告。)