登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 Lighting 于 2021-11-17 13:39 编辑
转自微信公众号:气象汇
略有修改
因为种种原因,使用MATLAB绘图时,可能会导致等值线出现锯齿,这样画出来的图就会显得不美观。本文就介绍一下,如何平滑等值线。
首先,我们先创建一组样本数据并绘制原图[注1]:
- [x, y, z] = peaks(50);
- levels = -7:9;
- contour(x, y, z, levels)
复制代码
然后,我们对原始数据进行处理,加入干扰:
- zn = z + rand(50);
- contour(x, y, zn, levels)
复制代码
可以看出,所绘制的等值线和原始数据绘制的图相比,锯齿非常明显了,而且还有一些很小的等值线。下面我们就对加入干扰后的数据进行处理。
首先,使用 fspecial 函数创建一个2D过滤器: - h = fspecial('gaussian');
复制代码
然后,计算2D卷积:
- znc = conv2(zn, h, 'same');
复制代码
默认情况下会返回完整的2D卷积,当然也可以设置其他参数来决定返回值。设置为 'same' 时返回值维度与 zn 的大小相同。
注意:传递给 conv2 的输入数据必须是 double 或 single 类型。
- contour(x, y, znc, levels)
复制代码
下图是,进行过滤后所绘制的等值线图。可以看出,等值线平滑了不少,而且很小的等值线也基本消失了。
除了使用高斯滤波默认值之外,也可以指定参数。
- h = fspecial('gaussian', [5, 5], 5);
- znc = conv2(zn, h, 'same');
- contour(x, y, znc, levels)
复制代码
可以看出,默认的参数可能效果并不是很好,需要根据效果更改参数。
除了使用高斯低通滤波之外,我们可以使用其他滤波方式看看:
平均滤波 - h = fspecial('average');
- znc = conv2(zn, h, 'same');
- contour(x, y, znc, levels);
复制代码
使用平均滤波之后,可以发现,等值线平滑程度更加明显,但是有一些细节也被消除了。
拉普拉斯高斯滤波 - h = fspecial('log');
- znc = conv2(zn, h, 'same');
- contour(x, y, znc, levels);
复制代码
可以看出,在平滑等值线方面,使用此滤波方式并不能得到想要的结果。
除了上述几种滤波方法之外,也可以使用其他滤波方法来对数据进行处理。当然,除了使用 fspecial 函数创建过滤器之外,也可以自定义过滤器。比如:
- h = ones(3)*0.1;
- znc = conv2(zn, h, 'same');
- contour(x, y, znc, levels);
复制代码
可以看出,自定义过滤器得到的平滑效果和使用高斯低通滤波得到的结果差不多,而且可能要好一些。但是在自定义过滤器的时候可能不好把握。
除了使用上述方法外,MATLAB File Exchange 中提供了一个函数,来对2D平面进行平滑[注2]。
将干扰后的数据插值到更稀疏的网格:
- xx = -3:0.15:3;
- yy = -3:0.15:3;
- zz = gridfit(x, y, zn, xx, yy);
- [X, Y] = meshgrid(xx, yy);
- contour(X, Y, zz, levels)
复制代码
将干扰后的数据插值到更密的网格中:
- xx = -3:0.01:3;
- yy = -3:0.01:3;
- zz = gridfit(x, y, zn, xx, yy);
- [X, Y] = meshgrid(xx, yy);
- contour(X, Y, zz, levels)
复制代码
可以发现:当将干扰数据插值到更密的网格时,会导致数据失真更加严重。因此,在使用此函数平滑等值线时,选择适当的参数进行平滑。
除了可以平滑等值线之外,也可以对1D数据进行滤波,从而平滑曲线。把相应的函数换为处理1D数据的即可。
|