如何对2D矩阵/图像进行对数缩放

4
我有一个2D的numpy数组,其中包含音频的频谱图,我想将其保存为图片。
我正在使用librosa库获取频谱。我也可以使用librosa.display.specshow()函数绘制它。如下所示,有许多不同的缩放类型。
import PIL
import librosa
import librosa.display

def display_spectrogram(spectrum, sampling_rate):
    """
    Frequency types:
    ‘linear’, ‘fft’, ‘hz’ : frequency range is determined by the FFT window and sampling rate.
    ‘log’ : the spectrum is displayed on a log scale.
    ‘mel’ : frequencies are determined by the mel scale.
    ‘cqt_hz’ : frequencies are determined by the CQT scale.
    ‘cqt_note’ : pitches are determined by the CQT scale.
    """

    librosa.display.specshow(spectrum, sr=sampling_rate, x_axis='time', y_axis='log')
    plt.colorbar(format='%+2.0f dB')
    plt.title('Spectrogram')
    plt.show()

我还可以将频谱图(一个numpy数组)转换为图像并保存,如下所示。
img = PIL.Image.fromarray(spectrum)
img.save("out.png")

我有原始的频谱图(线性缩放),我想将其保存为y轴以对数比例尺度显示。我查看了库源代码,以便了解它是如何缩放的,但无法弄清楚。
如何将图像/ 2D numpy数组的y轴进行对数比例尺度缩放?

linear matrix log scaled result


@Antimon 我不想改变这些值,我只是想对它们进行对数压缩。 - enesdemirag
1
没事了,我误解了你的问题。我现在明白了。但你需要告诉我们数字数据的格式是什么。频率和时间点是如何索引的? - Antimon
1个回答

3
实际上,Y轴的对数变换是由matplotlib完成的。您可以通过执行 ax.set_yscale('linear')ax.set_yscale('linear') 进行测试。因此,最简单的替代方法是调整matplotlib图以删除刻度、边框等。以下是一个示例:https://dev59.com/zFoU5IYBdhLWcg3wHERo#37810568 如果您想自己进行对数缩放,则需要按照以下步骤:
- 计算当前Y轴上的频率。使用librosa.fft_frequencies - 计算所需Y轴上的频率。使用numpy.logspace或类似工具 - 在所需的频率下对光谱图进行采样,例如使用scipy.interpolate(interp1d)

1
感谢@jonnor。使用plt.axis("off")plt.tight_layout(pad=0),我保存了图片。这种方法解决了问题。 - enesdemirag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接