我有一组超过4000点的数据。我想从它们中排除凹槽,理想情况是从它们开始的位置。数据看起来像这样:
这个问题是我在高原顶部发出的噪音。我有一个想法,我会在某些边界内取一个最常见的平均值(再次,理想情况下像这里的红线一样:
然后我会构建一个临时矩阵,如果它们小于这个平均值,它将逐个填充Y.如果Y(i)将超过平均值,则矩阵将找到其最小值并将其与全局最小值进行比较。如果临时矩阵的最小值不是全局最小值的80%,它将作为噪声丢弃。
我尝试过使用均值(Y),在多项式(绿线)中进行插值和拟合 - 这些方法都没有将它切割到我满意的程度。
我需要它非常强大,而且不需要很快。顶部和底部值可以变化很多,以及高原的形状。凹槽宽度或多或少相同。
你有什么想法吗?同样,重点是提取将产生凹槽的值。
答案 0 :(得分:2)
median filter怎么样?
让我们定义一些类似于你的噪音数据,并将其绘制成蓝色:
x = .2*sin((0:9999)/1000); %// signal
x(1000:1099) = x(1000:1099) + sin((0:99)/50*pi); %// noise: spike
x(5000:5199) = x(5000:5199) - sin((0:199)/100*pi); %// noise: wider spike
x = x + .05*sin((0:9999)/10); %// noise: high-freq ripple
plot(x)
现在应用中值滤镜(使用图像处理工具箱中的medfilt2
)并绘制为红色。参数k
控制过滤器内存。它应该选择与噪声变化相比较大,与信号变化相比较小:
k = 500; %// filter memory. Choose as needed
y = medfilt2(x,[1 k]);
hold on
plot(y, 'r', 'linewidth', 2)
答案 1 :(得分:2)
如果您没有图像处理工具箱,并且无法使用medfilt2
更加手动的方法。跳过极值,并使用sin1
作为曲线类型curve fit。 请注意,这仅在信号实际上是正弦波时才有效!
x = linspace(0,3*pi,1000);
y1 = sin(x) + rand()*sin(100*x).*(mod(round(10*x),5)<3);
y2 = 20*(mod(round(5*x),5) == 0).*sin(20*x);
y = y1 + y2; %// A messy sine-wave
yy = y; %// Store the messy sine-wave
[~, idx] = sort(y);
y(idx(1:round(0.15*end))) = y(idx(round(0.15*end))); %// Flatten out the smallest values
y(idx(round(0.85*end):end)) = y(idx(round(0.85*end)));%// Flatten out the largest values
[foo goodness output] = fit(x.',y.', 'sin1'); %// Do a curve fit
plot(foo,x,y) %// Plot it
hold on
plot(x,yy,'black')
可能不完美,但这是朝着正确方向迈出的一步。