检测和消除信号中的步骤

信息处理 matlab 过滤
2022-02-04 19:19:11

给定下面显示的信号,删除它包含的步骤和局部最大值的最佳方法是什么。该信号包含一些步骤,这些步骤可以持续多达 100 个样本,然后它们会返回到与步骤之前大致相同的值(用红色圆圈标记)。还有一些峰只持续一个样品,也应该去除。

第一个数据集:在这个数据集上,中值过滤器按预期工作(此处未显示)。采样信号,所有的峰都应该被移除,那些被标记为红色的峰也应该被移除。

在以下数据集上,具有相同设置的中值过滤器失败。以中值代替许多样本。 样本信号,绿色:来自答案之一的中值滤波器

我已经尝试过的:

  • 使用移动平均线。优点:小峰影响较小,可以很好地去除。缺点:信号中的持续时间较长。
  • 获取信号 ( diff(X)) 的一阶差分,如果一个大的正变化之后立即出现负变化,则更正 X 中的值。优缺点同上。

有什么好的方法可以删除/纠正这些不需要的值?

2个回答

移动平均线的问题在于,平均值对异常值的存在并不稳健——因此您需要一个非常大的窗口大小来“稀释”异常值。

尝试使用非线性滤波器,例如中值滤波器:对信号应用中值滤波器 - 您需要至少 300 个样本的窗口大小。计算原始信号和中值滤波版本之间的差异。如果差值高于阈值,则将信号替换为中值滤波版本。


这是一些scilab尝试实现此建议的代码。结果绘制在此处;它似乎可以很好地处理伪造的数据。

在此处输入图像描述

function sm = smooth(x,len)
    sm = filter(ones(1,len)/len,1,x);
endfunction

N = 6000;
x = 0.1*rand(1,N,'normal');
y = cumsum(x);
y = smooth(y,100);

clf
subplot(211);
plot(y)


Njumps = 20;

jump_indices = round(rand(1,Njumps)*N);

jump_length = 0;

y2 = y;

for idx = jump_indices,
    y2(min(N,idx:(idx+jump_length))) = y(min(N,idx:(idx+jump_length))) + 1;
    //plot(min(N,idx:(idx+jump_length)),y2(min(N,idx:(idx+jump_length))),'r')
    jump_length = jump_length + 1;
end

plot(y2,'g');

filter_length = 10;
y3 = y;
for k = 1:N,
    y3(k) = median(y3(max(1,min(N,(k-filter_length/2):(k+filter_length/2)))));
end

plot(y3,'k')

subplot(212);
plot(y-y2);
plot(y-y3,'r');

使用该diff方法,您可以分别纠正大的积极变化和大的消极变化,即放弃第二个必须立即跟随第一个的条件。计算diff,使用阈值检测异常值,用零或非异常值差异的平均值替换它们,计算差异的累积和。

结果不会是完美的。如果您需要更好的结果,我建议您调查这些步骤和峰值的来源,或者从一开始就避免它们,或者设计一种适合其特性的校正方法。