smooth_filter 平滑滤波器

1.移动平均法(邻域平均值滤波器)

One simple form of moving average is to calculate the average of adjacent measurements at a certain position. In a one-dimensional series of measurements a[1:N], for example, the moving average at a[n] can be calculated as a[n] = (a[n-1] + a[n] + a[n+1]) / 3, for example. If you go through all of your measurements, you're done. In this simple example, our averaging window has size 3. You can also use windows of different sizes, depending on how much smoothing you want

Use an algorithm based on convolution to make the calculation easier. The advantage of using convolution is that you can choose different kinds of averages, like weighted averages, by simply changing the window.

参考下面这个滤波器的实现:

bool SmoothingTrajectoryFilter::applyFilter(robot_trajectory::RobotTrajectory& rob_trajectory) const
{
  /** 总体思路:
   * - 使用相邻的num_coef_个数据,来生成第i个数据过滤后的值 //num_coef_为奇数, k=num_coef_/2;  i-k,...,i,...,i+k 共2k+1个原始数据,num_coef_=2k+1
  * - 每个数据的比重(系数),在coef_设定  //vector<>
  * - 每个数据,分别乘以coef_对应的系数,累加生成新值sum,除以增益gain_,作为第i个数据滤波后的值
  * 
  * e.g:
  *  sum = data(i-k)*coef_(i-k)+...+data(i)*coef_(i)+...data(i+k)*coef_(i+k);
  *  data_filter(i) = sum/gain_; //若gain_=num_coef_, coef_全为1,相当于取num_coef_个相邻数据的平均值
  * 
  */

  if(!initialized_) return(false);

  const int num_points = rob_trajectory.getWayPointCount(); 
  if(num_points <=2) return(false); // nothing to do here, can't change either first or last point
  const int num_states = rob_trajectory.getWayPoint(0).getVariableCount();
  std::vector<double> xv;
    
  // filter each variable independently
  for(int i=0; i<num_states; i++)
  { 
    double start_value     = rob_trajectory.getWayPoint(0).getVariablePosition(i);
    double start_slope     = rob_trajectory.getWayPoint(1).getVariablePosition(i) - start_value; // slope at start
    double end_value      = rob_trajectory.getWayPoint(num_points-1).getVariablePosition(i);
    double end_slope      = end_value - rob_trajectory.getWayPoint(num_points-2).getVariablePosition(i); // slope at end

    // initialize the filter to have initial slope
    xv.clear();
    double value = start_value - (num_coef_/2)*start_slope;
    for(int j=0; j<num_coef_; j++) 
    { 
      xv.push_back(value);
      value += start_slope;
    }
    
    // cycle through every waypoint, and apply the filter, NOTE, 1st and last waypoints should not be changed
    for(int j=1; j<num_points-1; j++)
    {
      // shift backwards
      for(int k=0; k<num_coef_-1; k++)
      {
        xv[k] = xv[k+1];  
      }

      // get next input to filter which is num_coef/2 in front of current point being smoothed
      if(j+num_coef_/2 < num_points)
      {	
        xv[num_coef_ - 1] = rob_trajectory.getWayPoint(j+num_coef_/2).getVariablePosition(i); // i'th state of j'th waypoint
      }
      else
      {
        end_value += end_slope;
        xv[num_coef_-1] = end_value; // fill by continuing with final slope
      }

      // apply the filter
      double sum = 0.0;
      for(int k=0; k<num_coef_; k++)
      { 
        sum += xv[k]*coef_[k];
      }

      // save the results
      rob_trajectory.getWayPointPtr(j)->setVariablePosition(i,sum/gain_); // j'th waypoint, i'th variable set to output value

    }// end for every waypoint

  } // end for every state

  return(true);

}// end SmoothingTrajectoryFilter::applyfilter()

2.Savitzky-Golay S-G法

It uses least squares to regress a small window of your data onto a polynomial, then uses the polynomial to estimate the point in the center of the window. Finally the window is shifted forward by one data point and the process repeats. This continues until every point has been optimally adjusted relative to its neighbors.

是邻域平均值滤波器的改进,是基于最小二乘的卷积拟合算法,使用相邻2*k+1个数据的最小二乘拟合多项式,以此来计算第i个数据对应的滤波后的值。

S-G 滤波其实是一种移动窗口的加权平均算法,但是其加权系数不是简单的常数窗口,而是通过在滑动窗口内对给定高阶多项式的最小二乘拟合得出。 

Savitzky-Golay平滑滤波被广泛地运用于数据流平滑除噪,是一种在时域内基于局域多项式最小二乘法拟合的滤波方法。这种滤波器最大的特点在于在滤除噪声的同时可以确保信号的形状、宽度不变。
 

进一步参考

Savitzky-Golay 滤波器_Ivan 的专栏-CSDN博客_savitzky-golay

python 平滑_Python 生成曲线进行快速平滑处理_带着神评走天下的博客-CSDN博客

3.FFT滤波器

4. Gaussian Filter

5.Kalman Filter

卡尔曼滤波的理解、推导和应用 - 古月居

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下代码对 dense 层的一维度输出进行平滑滤波处理: ``` from tensorflow.keras.layers import Input, Dense, Lambda from tensorflow.keras.models import Model from tensorflow.keras import backend as K import numpy as np class SmoothFilter(Conv1D): def __init__(self, filter_size=3, **kwargs): super().__init__( filters=1, kernel_size=filter_size, padding='same', activation='linear', use_bias=False, **kwargs ) self.filter_size = filter_size def build(self, input_shape): super().build(input_shape) # 初始化卷积核 kernel = np.ones((self.filter_size, 1, 1)) kernel /= self.filter_size self.set_weights([kernel]) def call(self, inputs): return super().call(inputs) # 定义输入层 input_layer = Input(shape=(6,)) # 定义 Dense 层 dense_layer = Dense(units=6, activation='relu')(input_layer) # 定义 SmoothFiltersmooth_layer = SmoothFilter(filter_size=3)(dense_layer) # 定义 Lambda 层,用于将 SmoothFilter 层的输出与 Dense 层的输出进行拼接 def concat_layer(x): return K.concatenate([x[0], x[1]], axis=-1) output_layer = Lambda(concat_layer)([dense_layer, smooth_layer]) # 定义模型 model = Model(inputs=input_layer, outputs=output_layer) # 打印模型结构 model.summary() ``` 在这个代码中,我们首先定义了一个 `SmoothFilter` 类,这是一个继承自 `Conv1D` 的类,用于实现一维卷积操作。在这个类中,我们定义了一个卷积核,初始化为一个 3x1 的全 1 矩阵,并除以 3,用于实现平均滤波。然后,我们通过 `super().call(inputs)` 调用父类的 `call` 方法,实现卷积操作。 接下来,我们定义了一个输入层和一个 Dense 层,用于产生一维度的输出。然后,我们定义了一个 `SmoothFilter` 层,对 Dense 层的输出进行平均滤波处理。最后,我们定义了一个 Lambda 层,用于将 SmoothFilter 层的输出与 Dense 层的输出进行拼接,得到最终的输出结果。 最后,我们定义了一个模型,并使用 `model.summary()` 打印了模型的结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值