20

我在图表上绘制了大约 9000 个点:

[全分辨率]

替代文字

其实剧情并没有我想的那么流畅。有什么方法可以将图表平滑到所需的程度?

或者某种形式的阈值,以便我可以选择性地平滑过于颠簸的部分?

我不确定,但快速傅立叶变换可以提供帮助吗?

4

5 回答 5

30

如果您有曲线拟合工具箱,您可以使用该smooth功能。默认方法是大小为 5 的移动平均(方法可以更改)。一个例子:

% some noisy signal
Fs = 200; f = 5;
t = 0:1/Fs:1-1/Fs;
y = sin(2*pi*f*t) + 0.6*randn(size(t));
subplot(411)
plot(y), title('Noisy signal')

% smoothed signal
subplot(412)
plot( smooth(y, 5, 'moving') ), title('smooth')
ylim([-2 2])

filter如果没有,您可以使用核心 MATLAB中的函数使用您自己的窗口函数:

% equivalent to a moving average window
wndwSize = 5;
h = ones(1,wndwSize)/wndwSize;
subplot(413)
plot( filter(h, 1, y) ), title('filter + square window')

% Guassian
h = pdf('Normal',-floor(wndwSize/2):floor(wndwSize/2),0,1);
subplot(414)
plot( filter(h, 1, y) ), title('filter + Guassian window')

截屏

于 2009-10-04T11:11:44.083 回答
17

一种简单的(临时)方法是alpha在每个点与其相邻点取一个加权平均值(可通过 调整):

data(2:n-1) = alpha*data(2:n-1) + (1-alpha)*0.5*(data(1:n-2)+data(3:n))

或其一些变体。是的,为了更复杂,您可以先对数据进行傅立叶变换,然后再切断高频。就像是:

f = fft(data)
f(n/2+1-20:n/2+20) = zeros(40,1)
smoothed = real(ifft(f))

这会去除最高的 20 个频率。小心将它们对称地剪掉,否则逆变换不再是真实的。您需要仔细选择截止频率以实现正确的平滑级别。这是一种非常简单的滤波(频域中的箱式滤波),因此如果失真不可接受,您可以尝试轻轻衰减高阶频率。

于 2009-10-04T09:16:35.630 回答
5

FFT 不是一个坏主意,但在这里可能有点矫枉过正。运行或移动平均线的结果通常很差,除了迟到的作业(和白噪声)之外,应该避免任何事情。

我会使用 Savitzky-Golay 过滤(在 Matlab sgolayfilt(...) 中)。这将为您提供所需的最佳结果 - 在保持曲线形状的同时进行一些局部平滑。

-保罗

于 2009-11-05T07:11:51.880 回答
3

有时您应该避免使用移动平均值,因为它对异常值不可靠。在这些情况下,移动中位数更可取。

于 2011-07-14T14:36:37.507 回答
1

我首先尝试显示多个点的运行平均值,例如 5 或 10。这样,值中的单个差异对图表的影响很小。当然,这取决于您需要图表的准确程度。

于 2009-10-04T09:12:27.760 回答