基于SciPy的加速度峰检测:峰值>20且谷值在0-5之间
解决方案
核心思路
要满足你的检测需求,需同时匹配两个约束条件:
- 峰值本身数值大于20
- 峰值的左右相邻局部谷值处于0-5区间内
原代码仅通过height=24筛选峰值,既错误提高了峰值阈值,也完全未考虑谷值的约束要求,因此结果不符合预期。以下是针对性的实现方案:
代码实现
import numpy as np from scipy.signal import find_peaks, argrelextrema import matplotlib.pyplot as plt # 你的加速度数据 x = np.array([1, 9, 18, 24, 26, 5, 26, 25, 26, 16, 20, 16, 23, 5, 1, 27, 22, 26, 27, 26, 25, 24, 25, 26, 3, 25, 26, 24, 23, 12, 22, 11, 15, 24, 11, 26, 26, 26, 24, 25, 24, 24, 22, 22, 22, 23, 24]) # 1. 先筛选出所有大于20的峰值 all_peaks, peak_props = find_peaks(x, height=20) # 2. 提取所有局部谷值,用于后续验证 valleys = argrelextrema(x, np.less)[0] # 3. 逐一验证峰值的相邻谷值条件 valid_peaks = [] for peak_idx in all_peaks: # 找到峰值左侧最近的谷值 left_nearest_valley = valleys[valleys < peak_idx][-1] if len(valleys[valleys < peak_idx]) > 0 else None # 找到峰值右侧最近的谷值 right_nearest_valley = valleys[valleys > peak_idx][0] if len(valleys[valleys > peak_idx]) > 0 else None # 验证左右谷值是否在0-5区间内 left_valid = 0 <= x[left_nearest_valley] <=5 if left_nearest_valley is not None else False right_valid = 0 <= x[right_nearest_valley] <=5 if right_nearest_valley is not None else False if left_valid and right_valid: valid_peaks.append(peak_idx) valid_peaks = np.array(valid_peaks) # 可视化结果 fig = plt.figure(figsize=(10,4)) plt.plot(x, label='加速度数据') plt.plot(all_peaks, x[all_peaks], 'o', color='orange', label='所有>20的峰值') plt.plot(valid_peaks, x[valid_peaks], 'x', color='red', label='符合谷值条件的目标峰值') plt.plot(valleys, x[valleys], '^', color='green', label='局部谷值') plt.legend() plt.show()
关键步骤说明
- 初始峰值筛选:用
height=20替代原代码的24,确保覆盖所有符合峰值下限要求的点。 - 谷值提取:通过
argrelextrema识别所有局部最小值,作为验证峰值的核心依据。 - 谷值条件验证:对每个峰值,分别定位其左右最近的谷值,只有两个谷值都落在0-5区间内的峰值,才会被判定为有效目标峰值。
- 可视化对比:通过不同标记区分所有候选峰值和最终有效峰值,直观验证检测结果。
内容的提问来源于stack exchange,提问作者aparna podili
相关产品推荐
相关产品推荐

