Python中如何通过音频识别跳绳次数?
每次的声音还是比较有规律的, 就是有没有音频模糊匹配的方法,可以识别这个音频里面一共跳了多少下?
找到了一个这个库, 但是感觉这个库比较大, 有没有比较简单的实现的方法。
用上面那可库的实现方法就是, 从开始一点一点的截取音频, 直到找到一个匹配, 然后在从新开始截取, 这样不断的循环下去。
Python中如何通过音频识别跳绳次数?
音频波
找相似的波普。。
要识别跳绳次数,最简单的方法是用麦克风录下跳绳时的声音,然后分析音频中的冲击波峰。跳绳落地会产生明显的“啪”声,我们可以通过检测这些声音脉冲来计数。
这里有个完整的示例代码,用了pyaudio录音和scipy做信号处理:
import pyaudio
import numpy as np
from scipy.signal import find_peaks
import wave
import time
# 录音参数
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 30 # 录制30秒
# 开始录音
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("开始录音...")
frames = []
for _ in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("录音结束")
stream.stop_stream()
stream.close()
p.terminate()
# 将音频数据转为numpy数组
audio_data = np.frombuffer(b''.join(frames), dtype=np.int16)
# 计算能量(平方后滑动平均)
window_size = int(0.05 * RATE) # 50ms窗口
energy = np.convolve(audio_data**2, np.ones(window_size)/window_size, mode='same')
# 归一化
energy = energy / np.max(energy)
# 寻找峰值(跳绳声)
peaks, _ = find_peaks(energy, height=0.2, distance=int(0.3 * RATE)) # 最小间隔0.3秒
# 输出结果
print(f"检测到跳绳次数: {len(peaks)}次")
print(f"峰值位置(秒): {peaks / RATE}")
# 可选:保存录音用于调试
with wave.open('jump_rope.wav', 'wb') as wf:
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
关键点:
- 用
pyaudio录制原始音频 - 计算短时能量来突出冲击声
- 用
find_peaks找能量峰值,distance参数防止重复检测 - 调整
height和distance阈值来适应不同环境
这方法在安静环境下效果不错,但在嘈杂环境可能需要更复杂的处理,比如带通滤波或机器学习。你可以先试试这个基础版本,根据实际录音调整参数。
简单说就是:录声音、算能量、找波峰。
总时间长度除以单次长度……哈哈~
Fingerprinting 是用来做精准匹配音频的,核心算法是特征提取和 Hash 累积匹配,跟你说的 “从开始一点一点的截取音频, 直到找到一个匹配” 相差挺远的。而且 FP 也不是用来做一个没有原始特征的这种模糊识别的算法,你这种需求直接从频谱里找竖向的峰值就好了。
这个 dejavu 只用了一个 local max 来找特征,算是最 naive 的方法了,实际的比如 Shazam 的 FP 算法要复杂的多。不过你只是找跳绳的声音参考这个的 get_2D_peaks 基本上也足够了。
提供一个思路,如果杂音不明显的话,用软件直接先转成音频的波形图(应该也有库可以完成这一步吧),然后画一条线看看,有多少个波峰超过这条线,就转换成了图形的问题。
如果能导出音频的波形图数据出来,那也可以说是数学问题了。(可以参考各种 xx 色谱的计算机处理)
仅供参考
可以用机器学习。
傅里叶变换
第一项的周期就是结果.
训练样本呢?
自己在不同环境差异明显最佳,录一些跳绳的声音就可以采集样本。具体怎么计算我也不懂。斯坦福公开课机器学习第一节就有经过机器学习后将 KTV 声音分离的介绍,原理是用两个 mic。
- 把跳绳的声音一段段切出来,10 段~20 段就可以了,作为模板;模板越多越好;最好选取不同人、不同跳绳的录音;
2. 模板片段提取 MFCC 系数,每个片段的 MFCC 系数做一下平均,作为整个片段的模板;多个模板可以再以下聚类,缩减一下模板数量,假设最后剩下 N 模板。
3. 测试片段的 MFCC 特征序列与 N 模板算一下余弦相似度,每个 MFCC 系数与任意一个模板的相似度超过阈值 t1,则标记为 1,未超过的标记为 0 ;
4. 对测试片段标记为 0~1 的序列做一个 5~10 点平滑,基本就可以用了。
比较简单粗暴,估计误识别会很高。
说的是对的,那个库适合做音频指纹检索,对这个 case 不太适合。
傅立叶变换就好了啊…信号与处理…想起了那些奋战在“电灯比油灯进步多了”的日子- -
用这个库要谨慎一点,库的作者已经不维护了,不过他的效率挺好的,通过短时傅里叶变换,然后过滤找到峰值点,在生成指纹,它是用来做音频识别的,跟你的场景不一样,你可以利用它的算法提出单次跳绳的峰值点,然后进行匹配,需要你自己实现。
这不能用傅立叶变换吧?跳绳频率不一定是均匀的。我觉得 #4 的方法就可以。这个问题应该不难,很多年前就有波形声音转 midi 的软件了,而这个只相当于把鼓点找出来
把声音波段弄出来 很轻松
要想非常稳健、鲁棒性很好地去搞定这个看上去并不起眼的问题,可能需要两个研究生去搞定
第一步就是降噪,环境噪音太大怎么没办?
第二步,blabla
傅立叶变化。。先把波分开。然后就好找了

