android - 检测手机加速度计的周期性数据

标签 android algorithm signal-processing accelerometer

我正在开发一个android应用程序,我需要检测用户上下文(如果步行或开车最少)
我用加速度计和所有轴的和来检测加速度矢量。它的工作方式很好,我可以看到一些周期值,而步行。但我需要用编程的方法检测这些Poeriod。
请问有没有一种数学函数可以检测一组值中的句点?我听说fourier变换可以用于此,但我真的不知道如何实现它。看起来很复杂:)
请帮助

最佳答案

检测数据周期性的最简单方法是autocorrelation。实现起来也相当简单。要在i处获得自相关,只需将数据的每个数据点与每个移动i的数据点相乘。下面是一些伪代码:

for i = 0 to length( data ) do
  autocorrel[ i ] = 0;
  for j = 0 to length( data ) do
     autocorrel[ i ] += data( j ) * data( ( j + i ) mod length( data ) )
  done
done

这将为您提供一个值数组。最高的“周期性”在具有较高值的索引处。这样可以提取任意周期部分(通常不止一个)。
另外,我建议您不要尝试在应用程序中实现自己的fft。虽然这个算法非常适合学习,但是有很多错误是很难测试的,而且很可能你的实现会比那些已经可用的要慢得多。如果在你的系统上可能的话,我建议你在fft实现时使用FFTW,这在任何方面都是不可能击败的。
编辑:
解释,为什么即使在不完全重复的值上也可以这样做:
计算自相关的通常且完全正确的方法是,从数据中减去平均值。假设你有[1, 2, 1.2, 1.8 ]。然后,您可以从每个样本中提取1.5,并留下[-.5, .5, -.3, .3 ]。现在如果你把这个和它自身相乘,在0的集合上,负数乘以负数,正数乘以正数,得到(-.5)^2 + (.5)^2 + (-.3)^2 + (.3)^2=.68。在偏移量为1时,负片将与正片相乘,产生(-.5)*(.5) + (.5)*(-.3) + (-.3)*(.3) + (.3)*(-.5)=-.64。在两次相抵时,负数将乘以负数,正数乘以正数。在偏移量为3时,类似于偏移量为1的情况再次发生。如您所见,在偏移量0和2(句点)处获得正值,在偏移量1和4处获得负值。
现在,为了只检测周期,不需要减去平均值。如果您只是保持样本不变,则每次添加时都会添加suqared平均值。由于每个计算的系数都将添加相同的值,因此比较将产生与第一次减去平均值相同的结果。最坏的情况是,数据类型可能会溢出(以防使用某种整数类型),或者当值开始变大时,可能会出现舍入错误(以防使用float,通常这不是问题)。如果发生这种情况,首先减去平均值,如果你的结果得到更好的尝试。
使用自相关与某种快速傅里叶变换相比最大的缺点是速度。autocorrelation采用O(n^2),而fft只采用O(n log(n))。如果您经常需要计算很长序列的周期,则自动关联可能在您的情况下不起作用。
如果你想知道fourier变换是如何工作的,以及实部、虚部、幅度和相位的所有这些东西(比如看一下manu发布的代码)意味着什么,我建议你看看this book
编辑2:
在大多数情况下,数据既不是完全周期的,也不是完全混沌和非周期的。通常,您的数据将由几个周期性的成分组成,具有不同的强度。周期是一个时差,通过它可以移动数据使其与自身相似。如果将数据移动一定量,则自相关计算数据的相似程度。因此它给你力量所有可能的时期。这意味着,不存在“重复值索引”,因为当数据是完全周期性的时,所有索引都将重复。具有最大值的索引将为您提供移位,此时数据与自身最为相似。因此,该索引提供一个时间偏移量,而不是数据的索引。为了理解这一点,理解时间序列是如何被认为是由完美周期函数之和(正弦基函数)组成的是很重要的。
如果您需要在很长的时间序列中检测到这一点,通常最好在数据上滑动一个窗口,然后检查这个较小的数据帧的周期。但是,您必须注意,您的窗口将向您的数据中添加额外的句点,您必须注意这些句点。
我在上一次编辑中发布的链接中有更多内容。

关于android - 检测手机加速度计的周期性数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8006466/

相关文章:

android - Json不能转int

java - 在 Firebase 上编写 ArrayList 的方法比 for 循环更好?

java - 如何将算法缩减为更小的部分以便我可以扩展它?

arrays - 将每个数字 a[i] 替换为其右侧的下一个更高的数字,

java - 如何保存Java中检测到的峰值位置?

python - 时间序列脑电图重采样可以修复电压分辨率差的问题?

matlab - 高频的 FFT 错误结果?

android - 防止 Android 包装器访问网站

android - 检查 ActionBar 的溢出弹出窗口是否显示

c++ - 在给定列和行的字符数组中查找索引?