信号平滑算法(Matlab的移动平均值)

时间:2019-05-14 08:05:35

标签: matlab

我编写了一个简单的代码,该代码执行3点移动平均平滑算法。它旨在遵循与here中所述的Matlab的smooth(...)函数相同的基本算法。

但是,我的代码结果与Matlab的结果非常不同。 Matlab的3点滤波器似乎执行了更加主动的平滑处理。

这是使用我的代码(红色)和Matlab函数(蓝色)平滑后的嘈杂数据的比较:

Here is a comparison:

这是我以函数形式编写的代码:

function [NewSignal] = smoothing(signal)
NewSignal = signal;
for i = 2 : length(signal)-1
    NewSignal(i,:) = (NewSignal(i,:)+NewSignal(i-1,:)+NewSignal(i+1,:))./3;
end
end

Matlab的功能用法如下:

signal = smooth(time, signal, 3, 'moving');

据我了解,Matlab的功能以相同的方式工作;它会将3个相邻箱平均为一个箱。所以我希望两种算法都能产生相同的结果。

那么,差异的原因是什么?我该如何调整代码以产生相同的结果?

编辑:

我的示例数据可以找到here。可以使用以下方式访问它:

M = csvread('DS0009.csv');
time = M(:,1);
signal = M(:,2);

这是使用rinkert校正的新结果(红色曲线):

enter image description here

2 个答案:

答案 0 :(得分:5)

产生差异的一个原因可能是您在平滑过程中部分使用了平滑信号。在循环中,您将平滑后的值存储在NewSignal(i,:)中,下一个要平滑的样本将由NewSignal(i-1,:)调用。

NewSignal仅由原始signal确定:

function [NewSignal] = smoothing(signal)
    NewSignal = signal;
    for i = 2 : length(signal)-1
        NewSignal(i,:) = (signal(i,:)+signal(i-1,:)+signal(i+1,:))./3;
    end
end

更新:要说明上述功能实际上与Matlab的smooth功能相同,请考虑以下MVCE

t = (0:0.01:10).';      % time vector 
y = sin(t) + 0.5*randn(size(t));

y_smooth1 = smooth(t,y,3,'moving');
y_smooth2 = smoothing(y);

difference_methods = abs(y_smooth1-y_smooth2);

因此,创建一个正弦波,添加一些噪声,并确定两种方法之间的绝对差。如果对所有差异进行求和,您会发现这加起来像7.5137e-14,无法解释您看到的差异。

绘制平滑信号(蓝色原始,红色平滑):

figure(1); clf; hold on
plot(t,y)
plot(t,y_smooth2)

enter image description here

然后绘制两种方法之间的差异:

figure(2); clf; hold on;
plot(t,y_smooth1-y_smooth2)

enter image description here

如您所见,差异约为1e-16,因此受浮点相对精度的影响(请参见eps)。

答案 1 :(得分:1)

要在评论中回答您的问题:函数filtersmooth在算术上的表现相同(在将它们应用于移动平均的情况下)。但是,在开始和结束时有一些特殊情况,它们的处理方式有所不同。 平滑的“ Because of the way smooth handles endpoints, the result differs from the result returned by the filter function.”文档中也对此进行了说明

在以下示例中看到它:

%generate randonm data
signal=rand(1,50);

%plot data
plot(signal,'LineWidth',2)
hold on
%plot filtered data
plot(filter(ones(3,1)/3,1,signal),'r-','LineWidth',2)
%plot smoothed data
plot( smooth(signal,3,'moving'),'m--','LineWidth',2)
%plot smoothed and delayed
plot([zeros(1,1); smooth(signal,3,'moving')],'k--','LineWidth',2)
hold off
legend({'Data','Filter','Smooth','Smooth-Delay'})

Example

如您所见,过滤后的数据(红色)只是平滑数据的延迟版本(洋红色)。此外,它们在开始时有所不同。延迟平滑后的数据会产生与滤波后的数据相同的波形(除了开始处)。正如rinkert指出的那样,您的方法将覆盖您下一步要访问的数据点。这是另一个问题。

在下一个示例中,您将看到rinkerts实现(smooth-rinkert)与matlabs smooth相同,并且由于覆盖了值,您的方法与二者不同:

comparison between your and rinkerts approach

因此,您的功能会使低通通过输入变得更强。 (如克里斯指出)