如何在Matlab中进行曲线平滑处理?

9

渐变图像

蓝色的图表是原始图表(红色)的噪声图表。是否有任何方法可以将蓝色图表近似为红色图表?


当然。有很多不同的方法可以实现这个,你尝试过什么了吗?作为一个简单的第一步,可以尝试使用移动平均滤波器,或者由于您似乎有大量的异常值,可以尝试使用移动中位数滤波器。上传一份数据样本是有意义的。 - Tobias
4个回答

14

让我们定义一个波浪函数:

x = 0:.1:20;
y1 = 5*sin(x) + 2*x - x.^2 +.3*x.^3 - .2*(x-15).^4 - 10*x.^2.*cos(x./3+12).^3 + .5*(x-12).^4;

并且添加大量噪音:

r = randi(1000,1,201) - 500;
y2 = y1+r;

现在制作一个一维高斯滤波器,对其进行归一化并与我们的函数进行卷积

g = gausswin(20); % <-- this value determines the width of the smoothing window
g = g/sum(g);
y3 = conv(y2, g, 'same')

让我们看看结果

figure;
hold on; 
plot(y1, 'r', 'linewidth', 3); 
plot(y2, 'b'); 
plot(y3, 'g', 'linewidth', 3);

红色是原始函数,蓝色是嘈杂版本,绿色是平滑的“恢复”函数。

平滑函数的线图


1
首先,这不是一个多项式。其次,原问题中绘图的示例噪声根本不服从正态分布,也肯定不是同方差的。高斯滤波涉及一些隐含的假设。 - user85109
首先,没错,它是一个多项式加上正弦函数。其次,我认为它仍然有效。但是,当然,另一个滤波器可能会为他的数据提供更好的结果,我并不是说这是唯一的方法。 - Junuxx
@Junuxx 是的,当我对高斯滤波的结果进行平均滤波时,它有点起作用。而且是的,噪声通常是正态分布的,所以结果不够好。 - crack_addict
2
注意:使用 gausswin() 函数需要安装信号处理工具箱。 - sergej
@Junuxx,这对我非常有用,谢谢!您能推荐一些关于数据过滤、高斯窗口等主题的更多信息资源/好书吗? - jap jap

11

另一种选择是使用 'smooth'。我喜欢使用它,因为它是一个单行函数。使用 @Junuxx 的先前答案中的代码:

x = 0:.1:20;
y1 = 5*sin(x) + 2*x - x.^2 +.3*x.^3 - .2*(x-15).^4 - 10*x.^2.*cos(x./3+12).^3 + .5*(x-12).^4;
r = randi(1000,1,201) - 500;
y2 = y1+r;

现在应用平滑效果:

ys = smooth(x,y2,0.25,'rloess');
plot(x,y2,x,ys)

在这里输入图片描述

更多信息请参见:

doc smooth

1
要使用'smooth',您可能需要:smooth - 曲线拟合工具箱 - embert

4

gausswin()需要信号处理工具箱

smooth()需要曲线拟合工具箱

如果您没有这些工具箱,这里提供一个简单的smooth()实现:

smooth.m:

function yy = smooth(y, span)
    yy = y;
    l = length(y);

    for i = 1 : l
        if i < span
            d = i;
        else
            d = span;
        end

        w = d - 1;
        p2 = floor(w / 2);

        if i > (l - p2)
           p2 = l - i; 
        end

        p1 = w - p2;

        yy(i) = sum(y(i - p1 : i + p2)) / d;
    end
end

使用 @Junuxx 的代码,对于 y3 = smooth(y2, 15) 的结果如下:

enter image description here


2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接