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% 以内的频率分量。如果是这样的话:

  1. 保留DFT的复数形式,否则无法变回;所以从 transform = abs(fft(signal)).

    行中删除 abs
  2. 不要使用np.where来“保持”你想要的频率;相反,将变换幅度低于阈值的位置设置为 0;就像是 transform[abs(transform) < 0.4 * max(abs(transform))] = 0

  3. 最后,对这个改变后的变换应用逆 DFT;您已将其应用于 signal(请参阅第 filtrata = ifft(signal) 行)。 (您在绘制 filtrada 时可能会收到有关丢弃虚数值的警告。)