让短时傅里叶变换时频图平滑的代码
时间: 2023-09-23 19:13:30 浏览: 101
matlab离散傅里叶变换平滑代码-NumPy:NumPy
短时傅里叶变换(STFT)得到的时频图通常具有较高的分辨率,但也会存在较大的噪声和不平滑性。对于这种情况,可以采用平滑技术来降低噪声和提高可视化效果。
常用的平滑技术包括移动平均、高斯平滑和中值滤波等。下面是一个使用高斯平滑的Python示例代码:
```python
import numpy as np
from scipy.signal import gaussian
def smooth_spectrogram(spectrogram, sigma):
'''
对给定的时频图进行高斯平滑。
:param spectrogram: 待平滑的时频图,形状为 (freq_bins, time_steps)。
:param sigma: 高斯函数的标准差。
:return: 平滑后的时频图。
'''
freq_bins, time_steps = spectrogram.shape
# 创建高斯窗口
window = gaussian(freq_bins, sigma)
# 对每个时间步进行平滑
smoothed_spectrogram = np.zeros_like(spectrogram)
for t in range(time_steps):
smoothed_spectrogram[:, t] = np.convolve(window, spectrogram[:, t], mode='same')
return smoothed_spectrogram
```
在这段代码中,我们使用 `scipy` 库的 `gaussian` 函数来生成高斯窗口。然后,对于每个时间步长,我们使用 `numpy` 库中的 `convolve` 函数来对窗口和时频图在频域上进行卷积,从而实现平滑。
使用示例:
```python
import librosa
import matplotlib.pyplot as plt
# 加载音频文件
audio, sr = librosa.load('example.wav', sr=44100)
# 计算STFT
stft = librosa.stft(audio, n_fft=1024, hop_length=512)
# 将幅度谱转换为分贝
spec_db = librosa.amplitude_to_db(np.abs(stft), ref=np.max)
# 平滑时频图
smoothed_spec_db = smooth_spectrogram(spec_db, sigma=2)
# 可视化原始和平滑后的时频图
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
librosa.display.specshow(spec_db, sr=sr, hop_length=512, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Original Spectrogram')
plt.subplot(2, 1, 2)
librosa.display.specshow(smoothed_spec_db, sr=sr, hop_length=512, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Smoothed Spectrogram')
plt.tight_layout()
plt.show()
```
这里我们使用了 `librosa` 库来计算STFT并进行可视化。您可以根据自己的需求更改参数,例如 STFT 的窗口大小和跳跃长度以及高斯函数的标准差。
阅读全文