中值&&均值滤波的C++实现

最近的开发工作中,为了消除上层数据的波动,接触到了神奇的十大滤波算法。虽然滤波算法很不科学,但是没有别的更好的方案。最后思来想去,决定采用中值+均值滤波的方式解决这一问题。

中值滤波

方法:
连续采样N次(N取奇数),把N次采样值按大小排列,
取中间值为本次有效值。
优点:
能有效克服因偶然因素引起的波动干扰;
对温度、液位的变化缓慢的被测参数有良好的滤波效果。
缺点:
对流量、速度等快速变化的参数不宜。

均值滤波

方法:
连续取N个采样值进行算术平均运算:
N值较大时:信号平滑度较高,但灵敏度较低;
N值较小时:信号平滑度较低,但灵敏度较高;
N值的选取:一般流量,N=12;压力:N=4。
优点:
适用于对一般具有随机干扰的信号进行滤波;
这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制不适用;比较浪费RAM。

C++实现

因为这两个算法都存在一个数据组的采集,都符合先进先出这一顺序,因此我们采用队列这一STL来实现。
实现顺序为:

st=>start: 开始 
e=>end: 进入下一帧
op1=>operation: 记录五组数据
op2=>operation: 排序并取中间三个平均
op3=>operation: 先进出列
st->op1->op2->op3->e

实现代码

以下为实现这一流程的部分代码

double Control::getAngleData(double angle)
{
    Control::angle_data.push(angle);
    if (angle_data.size() < 5)
    {
        std::cout << "<5"<<std::endl;
        return angle;
    }
    else if (angle_data.size() > 5)
    {
        std::cout << "wrong"<<std::endl;
        return 0;
    }
    else
    {
        double angle[5];
        for (int i = 0; i < 5; i++)
        {
            angle[i]=angle_data.front();
            angle_data.push(angle[i]);
            angle_data.pop();
        }
        angle_data.pop();
        sort(angle, angle + 5);
        std::cout << "=5"<<std::endl;
        double r_angle = (angle[1] + angle[2] + angle[3]) / 3.0;
        return r_angle;
    }
}
添加新评论