2

在我的项目中,我有通过算法计算的 20.000 个点的高曲面。该算法有时会出现错误,错误地计算小区域中的 1 个或多个点。

这个错误在算法中是无法解决的,需要事后检测。

错误如下图所示:

在此处输入图像描述

如您所见,有一个点计算错误,不仅破坏了整个均匀表面,而且破坏了情节的美学(这在项目中也很重要。)

有时可能不止一个点,一般不超过5个或6个。误差总是Z轴,所以不需要检查X和Y

我一直在努力寻找一种“通用”算法来检测这个点。我认为可能会采用表面的补丁并表示 Z,然后从方差中检测点......但我认为它不会一直有效。

有任何想法吗?

注意:我不希望有人为我编写代码,只是一个想法。

PD:avobe图像的相关代码:

[x,y] = meshgrid([-2:.07:2]);
Z = x.*exp(-x.^2-y.^2);
subplot(1,2,1)
surf(x,y,Z,gradient(Z))
subplot(1,2,2)
Z(35,35)=Z(35,35)+0.3;
surf(x,y,Z,gradient(Z))
4

2 回答 2

3

标准技巧是使用拉普拉斯算子,寻找最大的异常值。(这与 Mohsen 提出的答案没有什么不同,但实际上更容易一些。)你甚至可以用 conv2 来做,所以它会非常有效。

我可以提供一些方法来实现这个想法。一个简单的方法是使用我在 File Exchange 上找到的 gridfit 工具。(Gridfit 本质上使用拉普拉斯算子进行平滑操作。)拟合包含所有点的曲面,然后寻找受拟合影响最大的单点。排除它,然后重新运行拟合,再次寻找最大的异常值。(使用 gridfit,您可以使用权重为点赋予零权重,这是一种排除点或点列表的简单方法。)当所需的最大扰动足够小时,您可以决定停止该过程。一件好事是 gridfit 还将为异常值估算新值,填充所有漏洞。

第二种方法是直接使用拉普拉斯算子,更像是一种过滤方法。在这里,您只需计算每个点的值,该值是左、右、上和下每个邻居的平均值。与计算平均值最大不一致的单个值被替换为新值。或者,您可以使用新值与旧值的加权平均值。同样,迭代直到该过程不产生任何大于某个容差的东西。(这是我从 Fortran IMSL 库中回忆的旧异常值检测和校正方案的基础,但可能可以追溯到大约 30 年前。)

于 2013-07-04T14:12:05.427 回答
2

由于您的函数似乎变化平稳,因此可以通过查看导数来检测这些突然的变化。你可以

  1. 向一个方向求导
  2. 计算导数的均值和标准差
  3. 通过查找距离均值较远某个标准差倍数的点来查找这些点。

这是代码

U=diff(Z);
V=(U-mean(U(:)))/std(U(:));
surf(x(2:end,:),y(2:end,:),V)
V=[zeros(1,size(V,2)); V];
V(abs(V)<10)=0;
V=sign(V);
W=cumsum(V);
[I,J]=find(W);
outliers = [I, J];

对于您的示例,您会得到这个图,V峰值在 21.7 左右,而第二个峰值在 1.9528 左右,所以阈值 10 可能是可以的。 在此处输入图像描述

并运行代码返回

outliers =

    35    35

需要的cumsum是你有一块不正确的相邻点的情况。

于 2013-07-04T11:34:35.633 回答