You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab转Python:Scipy频谱图与原结果不符问题求助

解决Matlab与Scipy频谱图迁移的差异问题

核心问题分析

你遇到的差异来自三个关键参数和逻辑的不一致:

  • Scipy默认返回功率谱密度(实数),而Matlab默认返回复频谱(复数)
  • 幅值转dB的计算逻辑存在差异
  • 绘图坐标轴方向与Matlab不匹配

具体修正步骤

1. 调整Spectrogram参数,获取复频谱

将Scipy的mode参数改为'complex',同时把scaling设为'spectrum',匹配Matlab的幅值谱输出逻辑:

f, t, Sxx = signal.spectrogram(
    data[:,0],  # 取单声道,对应Matlab的sound(:,1)
    fs=48000, 
    window='hamming', 
    nperseg=1000, 
    noverlap=500, 
    nfft=1000, 
    detrend='constant', 
    return_onesided=True, 
    scaling='spectrum',  # 对应Matlab的幅值谱模式
    axis=-1, 
    mode='complex'  # 关键:获取复频谱,匹配Matlab返回的S
)

2. 修正dB转换逻辑

Matlab的mag2db(abs(S))本质是20*log10(abs(S)),直接用numpy实现该逻辑,避免第三方库的默认参数差异:

# 与Matlab mag2db(abs(S))完全一致的dB计算
dB = 20 * np.log10(np.abs(Sxx))
# 若需对齐录音设备的0dB基准(最大幅值对应0dB),可添加:
# dB = dB - np.max(dB)

3. 匹配坐标轴方向

Matlab的axis xy将频率轴原点放在左下角,而Matplotlib默认倒置,需手动反转y轴:

plt.gca().invert_yaxis()  # 对应Matlab的axis xy设置

完整修正后的Python代码

import numpy as np
from scipy.io import wavfile
from scipy import signal
import matplotlib.pyplot as plt

rate, data = wavfile.read(file)
# 匹配Matlab参数获取复频谱
f, t, Sxx = signal.spectrogram(
    data[:,0],
    fs=48000, 
    window='hamming', 
    nperseg=1000, 
    noverlap=500, 
    nfft=1000, 
    detrend='constant', 
    return_onesided=True, 
    scaling='spectrum', 
    axis=-1, 
    mode='complex'
)
# 计算dB值
dB = 20 * np.log10(np.abs(Sxx))
# 对齐设备0dB基准(可选)
# dB = dB - np.max(dB)

# 绘图
plt.pcolormesh(t, f, dB, shading='gouraud')
plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (s)')
plt.colorbar()
plt.title(f"{file} Spectrogram")
plt.gca().invert_yaxis()
plt.show()

关键差异说明

  • mode参数:Scipy默认mode='psd'返回功率谱(实数),Matlab默认返回复频谱,必须指定mode='complex'才能匹配
  • scaling参数:'spectrum'对应幅值谱,'density'是功率谱密度,两者幅值量级差异极大
  • 坐标轴方向:Matplotlib默认频率轴从上到下为高频到低频,与Matlab相反,需反转y轴

内容的提问来源于stack exchange,提问作者jukebox41188

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:52:18