使用numpy和scipy查找音频信号中的峰值

iqjalb3h  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(280)

我只是在学习如何使用numpy和scipy来使用python,我想使用音频波形来玩它们。
我正在从mp3中获取音频数据,我获取的范围为-1到+1,我将其转换为-255到+255,
现在我在谷歌上阅读,在cookbooks和stackoverflow和ilm上尝试看看我可以使用scipy.signal.findpeeks的拾取检测类型之间的区别,问题是它发现几乎所有的点都是峰值,我遗漏了一些东西。
这是我尝试使用的峰值参数:

peaks, _ = find_peaks(data, distance=25)
peaks2, _ = find_peaks(data, prominence=1)      # BEST!
peaks3, _ = find_peaks(data, width=20)
peaks4, _ = find_peaks(data, threshold=0.4)

并且这是显示所有峰值的结果:

这是完整的代码:

import av
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks, find_peaks_cwt, argrelextrema, argrelmax, argrelmin
from scipy.ndimage.filters import gaussian_filter1d

container = av.open(
    'free.mp3')

data = np.empty(shape=0)

for packet in container.demux():
    for frame in packet.decode():
        if isinstance(frame, av.audio.frame.AudioFrame):
            layout = frame.layout
            channels = layout.channels
            (chl, chr) = channels
            print(frame,
                  frame.format,
                  frame.layout,
                  frame.rate,
                  frame.samples)
            print(chl, chr)
            array = frame.to_ndarray()[0]
            data = np.concatenate([data, array])
data = np.interp(data, [-1, 1], [-255, 255])
peaks, _ = find_peaks(data, distance=25)
peaks2, _ = find_peaks(data, prominence=1)      # BEST!
peaks3, _ = find_peaks(data, width=20)
peaks4, _ = find_peaks(data, threshold=0.4)     # Required vertical distance to its direct neighbouring samples, pretty useless

plt.subplot(2, 2, 1)
plt.plot(peaks, data[peaks], "xr");

# plt.plot(data);

plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, data[peaks2], "ob");

# plt.plot(data); plt.legend(['prominence'])

plt.subplot(2, 2, 3)
plt.plot(peaks3, data[peaks3], "vg");

# plt.plot(data);

plt.legend(['width'])

plt.subplot(2, 2, 4)
plt.plot(peaks4, data[peaks4], "xk");

# plt.plot(data);

plt.legend(['threshold'])

plt.plot(data)
plt.legend(['cwt'])
plt.grid()
plt.tight_layout()
plt.show()

我错过了什么?
如有关于此问题的任何信息,我们将不胜感激,谢谢。

8oomwypt

8oomwypt1#

您需要指定多个参数

scipy.signal.find_peaks(x, height=None, threshold=None, distance=None, prominence=None, width=None, wlen=None, rel_height=0.5, plateau_size=None)

这是函数的文档,所以你需要在questin中指定一组适合你的信号的参数。

相关问题