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

不使用display.specshow实现librosa频谱图频率轴对数缩放的方法

实现方案

你要实现的对数Y轴频谱图可以直接通过频率坐标插值实现,全程不需要调用Matplotlib接口,单样本处理速度可以提升10~100倍,完全满足批量生成训练数据的需求。

核心原理

librosa的specshow(y_axis='log')本质是做了两步操作:

  • 生成覆盖[1Hz, 采样率/2]区间的对数分布频率坐标(对数轴不支持0Hz,所以最低值取1Hz)
  • 将线性频率轴上的频谱幅值插值到对数频率坐标上,再做渲染

完整实现代码

import numpy as np
import librosa
from scipy.interpolate import interp1d

def get_log_spectrogram_from_wav(wav: np.ndarray, sample_rate: int, n_fft: int = 2048, hop_length: int = 512) -> np.ndarray:
    # 1. 计算基础线性频率频谱
    spec = np.abs(librosa.stft(wav, n_fft=n_fft, hop_length=hop_length))
    spec_db = librosa.amplitude_to_db(spec, ref=np.max)
    freq_bins = spec_db.shape[0]

    # 2. 生成线性频率坐标和目标对数频率坐标
    linear_freqs = librosa.fft_frequencies(sr=sample_rate, n_fft=n_fft)
    log_freqs = np.logspace(np.log10(1), np.log10(sample_rate/2), freq_bins)

    # 3. 对每个时间步的频谱做插值
    interpolator = interp1d(linear_freqs, spec_db, axis=0, kind='linear', fill_value='extrapolate')
    log_spec_db = interpolator(log_freqs)

    # 4. 归一化到0~255灰度范围,可直接作为神经网络输入
    log_spec_db_norm = (log_spec_db - log_spec_db.min()) / (log_spec_db.max() - log_spec_db.min()) * 255
    return log_spec_db_norm.astype(np.uint8)

效果说明

输出的数组可以直接用PIL.Image.fromarray保存为灰度图,和specshow(y_axis='log')的输出频率轴分布完全一致。如果需要调整输出图像的高度,只要修改log_freqs生成时的长度参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:06:00