我需要找到加速度计值流达到最大值的次数。我使用CoreMotion方法获取DeviceMotionUpdates,绘制了从iPhone获取的加速度计值随时间变化的图。在记录数据时,我摇了摇手机9次(每个极端都是加速度的最高点之一)。
我已经标记了18点(即9 * 2)次加速度达到最大值的红色方块。
但是,如你所见,有一些我不想考虑的局部最大值。有人可以指导我一个能够帮助我实现只检测最重要的最大值的想法吗?
编辑:我想我必须使用低通滤波器。但是,我如何在Swift中实现它?如何选择截止频率?
编辑2: 我实现了一个低通滤波器并通过它传递原始运动数据并获得如下所示的图形。这要好得多。我仍然需要一种方法来避免可以观察到的微不足道的最大值。我将与过滤器深入合作,并可能修复它。
答案 0 :(得分:1)
我会尝试寻找周期,而不是试图找到最大值。特别是,我们注意到(主要)最小值似乎比最大值更加一致。
我不熟悉swift,所以我会用伪代码布局我的想法。假设我们的值v[i]
和dv[i] = v[i] - v[i - 1]
中的导数。如果您获得更好的结果,您可以使用任何其他差异化方案。
我会尝试像
这样的东西cycles = [] // list of pairs
cstart = -1
cend = -1
v_threshold = 1.8 // completely guessing these figures looking at the plot
dv_threshold = 0.01
for i in v:
if cstart < 0 and
v[i] > v_threshold and
dv[i] < dv_threshold then:
// cycle is starting here
cstart = i
else if cstart > 0 and
v[i] < v_threshold and
dv[i] < dv_threshold then:
// cycle ended
cend = i
cycles.add(pair(cstart, cend))
cstart = -1
cend = -1
end if
现在您在评论中注意到用户应该能够以不同的力量进行摇动,您应该能够识别动作。我将从简单的“硬编码”开始。如上所述的案例,看看你是否可以让它充分发挥作用。有很多事情可以尝试获得可变阈值,但是你仍然需要一个。但是,根据您显示的数据,我强烈建议至少限制自己观察最小值而不是最大值。
另外:我建议的代码是在您拥有完整数据集的情况下编写的,但是您需要实时运行它。这将没有问题,算法仍然可以工作(也就是说,这个想法仍然有用,但你必须对它进行不同的编码)。