过滤加速计数据噪音
如何在Android中过滤加速计数据的噪音? 我想为我的样本数据创build一个高通滤波器,这样我就可以消除低频成分并专注于高频成分。 我已经读过卡尔曼滤波器可能是最好的候选人,但我怎么在我的应用程序集成或使用这种方法,这将主要在Android Java? 或者可以在第一时间完成? 还是通过Android NDK? 有没有可能实时完成这个任务?
任何想法将不胜感激。 谢谢!
来自Apple SDK的样本实际上是以更简单的方式来实现过滤,即使用渐变:
//斜坡速度 - 用这个值玩,直到满意 const float kFilteringFactor = 0.1f; //最后的结果存储 - 保持定义在这个函数之外,例如。 在包装物体 浮点加速[3]; //acceleration.x,.y,.z是来自传感器的input //result.x,.y,.z是过滤结果 //高通滤波器消除重力 accel [0] = acceleration.x * kFilteringFactor + accel [0] *(1.0f - kFilteringFactor); accel [1] = acceleration.y * kFilteringFactor + accel [1] *(1.0f - kFilteringFactor); accel [2] = acceleration.z * kFilteringFactor + accel [2] *(1.0f - kFilteringFactor); result.x = acceleration.x - accel [0]; result.y = acceleration.y - accel [1]; result.z = acceleration.z - accel [2];
以下是适用于Android的代码,适用于苹果自适应高通滤波器示例。 只需将其插入并实现onFilteredAccelerometerChanged()
private static final boolean ADAPTIVE_ACCEL_FILTER = true; float lastAccel[] = new float[3]; float accelFilter[] = new float[3]; public void onAccelerometerChanged(float accelX, float accelY, float accelZ) { // high pass filter float updateFreq = 30; // match this to your update speed float cutOffFreq = 0.9f; float RC = 1.0f / cutOffFreq; float dt = 1.0f / updateFreq; float filterConstant = RC / (dt + RC); float alpha = filterConstant; float kAccelerometerMinStep = 0.033f; float kAccelerometerNoiseAttenuation = 3.0f; if(ADAPTIVE_ACCEL_FILTER) { float d = clamp(Math.abs(norm(accelFilter[0], accelFilter[1], accelFilter[2]) - norm(accelX, accelY, accelZ)) / kAccelerometerMinStep - 1.0f, 0.0f, 1.0f); alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0f - d) * filterConstant; } accelFilter[0] = (float) (alpha * (accelFilter[0] + accelX - lastAccel[0])); accelFilter[1] = (float) (alpha * (accelFilter[1] + accelY - lastAccel[1])); accelFilter[2] = (float) (alpha * (accelFilter[2] + accelZ - lastAccel[2])); lastAccel[0] = accelX; lastAccel[1] = accelY; lastAccel[2] = accelZ; onFilteredAccelerometerChanged(accelFilter[0], accelFilter[1], accelFilter[2]); }
对于那些想知道norm()和clamp()方法在rbgrn的答案中做了什么,你可以在这里看到它们: http : //developer.apple.com/library/IOS/samplecode/AccelerometerGraph/Listings/AccelerometerGraph_AccelerometerFilter_m.html
我似乎记得这是在iPhone的苹果示例代码中完成的。 让我们来看看…
在Google上寻找AccelerometerFilter.h / .m(或者抓住Apple的AccelerometerGraph示例)和这个链接: http : //en.wikipedia.org/wiki/High-pass_filter (这就是苹果的代码所基于的)。
Wiki中也有一些伪代码。 但是math转化为代码相当简单。
海事组织,devise一个卡尔曼滤波器作为你的第一次尝试过度复杂化可能是一个相当简单的问题。 我会从一个简单的FIR滤波器开始,只有当你testing了这个滤波器,并且有合理的确定性地发现它不能提供你想要的东西时,才尝试更复杂的东西。 但是,我的猜测是,它将能够做到你需要的一切,并且更容易,更有效地做到这一点。