2. 可穿戴设备步数统计算法实现
步数检测的核心问题
加速度计输出的三轴信号中,步行产生的周期性波动叠加在重力分量和手部随机抖动之上。直接对原始幅值做阈值计数,在慢走时会漏计(峰值低于阈值),在快走或摆臂时会误计(单个步态周期出现多个局部峰值)。因此算法需要解决三件事:把三轴合成为与姿态无关的幅值、用自适应方式跟踪步态节律、对候选峰值做时间间隔约束。
算法实现
下面给出一个可直接在嵌入式或移动端运行的步数检测实现。输入为三轴加速度采样序列,输出为累计步数。核心参数:采样率 50Hz,带通 0.5–3.5Hz,滑动窗 2s,阈值系数 k=0.8,最小步间隔 250ms。
import math
from collections import deque
class StepCounter:
def __init__(self, fs=50.0, win_sec=2.0, k=0.8,
min_step_ms=250, max_step_ms=2000):
self.fs = fs
self.k = k
self.min_gap = int(min_step_ms * fs / 1000)
self.max_gap = int(max_step_ms * fs / 1000)
self.win = int(win_sec * fs)
self.buf = deque(maxlen=self.win) # 滤波后幅值
self.steps = 0
self.last_peak_idx = -10**9
self.idx = 0
# 一阶带通(高通+低通级联)状态
self.hp_prev = 0.0
self.lp_prev = 0.0
self.hp_a = 0.95 # 高通系数,抑制重力
self.lp_a = 0.20 # 低通系数,抑制抖动
def _bandpass(self, m):
# 高通:去除重力与缓慢漂移
hp = self.hp_a * (self.hp_prev + m - self._hp_in_prev) \
if hasattr(self, '_hp_in_prev') else 0.0
self._hp_in_prev = m
self.hp_prev = hp
# 低通:平滑高频噪声
lp = self.lp_prev + self.lp_a * (hp - self.lp_prev)
self.lp_prev = lp
return lp
def update(self, ax, ay, az):
m = math.sqrt(ax*ax + ay*ay + az*az)
f = self._bandpass(m)
self.buf.append(f)
self.idx += 1
if len(self.buf) < self.win:
return self.steps
# 自适应阈值
mean = sum(self.buf) / len(self.buf)
var = sum((v - mean)**2 for v in self.buf) / len(self.buf)
thr = mean + self.k * math.sqrt(var)
# 峰值检测:当前点大于阈值且为局部极大
if len(self.buf) >= 3:
a, b, c = self.buf[-3], self.buf[-2], self.buf[-1]
if b > thr and b > a and b > c:
gap = self.idx - self.last_peak_idx
if self.min_gap <= gap <= self.max_gap:
self.steps += 1
self.last_peak_idx = self.idx
elif gap > self.max_gap:
# 长时间无步,重置参考点,避免漏计首步
self.last_peak_idx = self.idx
return self.steps
参数选择与验证
| 参数 | 取值 | 作用 | 调整方向 |
|---|---|---|---|
| 采样率 fs | 50 Hz | 满足 3.5Hz 上限的奈奎斯特要求 | 低于 25Hz 会丢失快走谐波 |
| 带通下限 | 0.5 Hz | 抑制重力与姿态漂移 | 过高会削掉慢走基频 |
| 带通上限 | 3.5 Hz | 抑制手部抖动与高频噪声 | 过低会平滑掉峰值 |
| 阈值系数 k | 0.8 | 控制灵敏度 | k 增大→漏计增多;k 减小→误计增多 |
| 最小步间隔 | 250 ms | 抑制单周期双峰误计 | 对应最快 4 步/秒 |
| 最大步间隔 | 2000 ms | 判定为停顿并重置参考 | 过长会漏计慢走首步 |
验证方法:用同一段录制数据分别以 1.2Hz(慢走)和 2.4Hz(快走)回放,统计输出步数与人工标注步数的偏差。慢走场景重点观察是否漏计,快走场景重点观察是否出现约 2 倍误计。若慢走漏计,优先降低 k 或放宽带通下限;若快走误计,优先收紧最小步间隔或提高带通上限。
加速度计安装位置会显著影响信号质量。手腕佩戴时摆臂幅度大,快走易产生双峰;腰部佩戴时信号更干净但慢走幅值小。同一套参数在不同佩戴位置下表现不同,实际部署时应按佩戴位置分别标定 k 与最小步间隔。