大多数人对滤波器的了解,只是认为,滤波器就是对信号进行分离,比如滤除信号中低频或者高频的成分,实际上这种理解是狭义的,广义上的滤波器除了包括上面的功能以外,还包括对信号的整形,而前者是频域滤波器,后者为时域滤波器。本文所提到的Moving Average Filter实际上就是一种时域滤波器。
由滤波器的名称可以得知,这种滤波器就是通过对输入信号做平均来产生输出信号的方式。
其中y[]是输出信号,x[]是输入x[]是输入信号,M表示用来做平均的点数
例如:
这是取输出采样点的右边做平均,还可以取对称的两边:
这是取输出点两边做平均,但是此时M必须取奇数
采用这种滤波算法的效果图,这种滤波方式主要是用来去噪,并且往往M取值越大,则得到的波形就会越平滑,去噪能力越强,但同时信号的上升沿会遭到破坏,变缓less sharp。
上图是频响曲线,可以看出,M值越大,高频损耗就越大,越偏向低频滤波器,相当于高频成分都会消失。
滤波器也是通过将输入信号和滤波器的的impulse response(filter kernel)做卷积得到输出信号,只不过moving average的filter kernel的每一个point都是相等的。
还有一类和moving average很类似的filter,relatives of the moving average,有高斯和布莱克blackman
和moving average相比,它们的优势,在阻带衰减性能更佳,moving average每个输入point对于输出point的权重都是一样大的,但是高斯却是距离输出点越远,则占输出点的权重越小。
实际上,如果重复使用moving average则实际得到的就类似于高斯filter。
使用多次,相当于moving average滤波器对其自身作卷积,上图分别是,做2次,4次的效果。
实例:
下面是对采集卡采到的数据,使用moving average做了处理,主要是通过matlab来实现的
代码如下:
points_per_period=16; %定义每个周期有多少个采样点
col_array=650; %取多少个点(因为文件中有4096个采用点,这里我们只取650个点)
data_array_section=ones(1,col_array);
for k=1:col_array
data_array_section(k)=data_array(k); %将取出的650个采样点放入矩阵data_array_section中
end
moving_point=9; %定义moving average中去多少个点进行平均运算,也就是M的值
moving_point_left=(-moving_point+1)/2; %取输出点对称两边的采样点的值做平均,这里值为-4
moving_point_right=(moving_point-1)/2; %这里值为4
data_array_filter=zeros(1,col_array); %初始化一个和data_array_section大小相同的矩阵,存储结果
for i=1:moving_point_right
data_array_filter(i)=data_array_section(i);
end
for i=(col_array+moving_point_left+1):col_array %这一段代码,是对矩阵的前4个和后4个点进行赋值
data_array_filter(i)=data_array_section(i);
end
for i=(moving_point_right+1):(col_array+moving_point_left)
for j=moving_point_left:moving_point_right
data_array_filter(i)=data_array_filter(i)+data_array_256(i+j); %moving average filter process
end
data_array_filter(i)=data_array_filter(i)/moving_point;
end
plot(data_array_filter,'-.*r'); %将结果绘图
没有filter之前的波形图
采用moving average filter之后的结果M=9
本文提到的这种滤波算法,是一种很简单,但是很好用的滤波方法,基本上对得到的原始采样数据都可以采用这种方法先处理一下。