使用2D/3D样条曲线从嘈杂的数据点中找到曲率?(C++)

23

我尝试从脉冲曲线上提取其曲率(如下图所示)。该脉冲是在一个长度和高度为150x100单元格的网格上使用C++实现的有限差分计算得出的。

带有不同曲率的波形图

我提取了所有具有相同值(等高线/级别集)的点,并在下面的图中将它们标记为红色连续线。其他颜色可以忽略。

红线= 具有相同值的数据点

然后,我尝试通过以下方式从已经很嘈杂(由于网格离散化)的轮廓线中找到曲率:

(已应用移动平均)

1) 通过切线计算曲率
从两个点P和N近似计算曲率

点P处的曲线曲率定义为:

2个点的切线=某点的曲率

因此,曲率是delta角度与P和N之间的弧长之比的极限。由于我的点之间有一定距离,我无法足够近似极限,因此曲率无法正确计算。我用圆测试了它,圆自然具有恒定曲率。但我无法重现这个结果(只有1位有效数字是正确的)。

2) 使用弧长参数化的线的二阶导数

我根据弧长对线进行了一阶导数计算,并应用了移动平均平滑,然后再次进行了导数计算(2阶导数)。但是,在这里我也只得到了1个有效数字的正确结果。不幸的是,求导数会将已有的噪声扩大到更高的水平。

3) 在局部使用圆来逼近曲线

由于圆的半径倒数是曲率,我采用了以下方法:

用圆来近似曲率

到目前为止,这是最好的方法(2个正确有效数字),但我需要进一步改进。所以我的新想法如下:

不再使用离散点处的值来确定曲率,而是想用三维样条曲面来近似脉冲轮廓。然后从中提取某个特定值的等值集以获得平滑的点线,从中可以找到一个好的曲率。

到目前为止,我找不到一个可以生成这样的Bezier样条曲面的C++库。你能帮我指路吗?

你认为这种方法值得一试吗?还是说我在曲率上会失去太多精度?

你知道其他方法吗?

谢谢您的耐心帮助!

编辑:看起来我不能作为新用户发布图片,所以我从问题中删除了所有图片,尽管我认为它们很重要来解释我的问题。有没有什么办法可以让我仍然展示它们呢?

编辑2:好的,搞定了 :)


2
样条曲线适用于生成点,而不是插值。考虑使用最小二乘法。 - Hans Passant
@Janna - 如果您在帖子中保留链接,具有编辑权限的用户可以使图像内联。对于新用户来说,限制是因为并非每个人都发布漂亮的图片... - Bo Persson
@ Hans Passant:一开始我考虑了最小二乘法,但是事先不可能知道什么样的函数逼近我的脉冲。我不知道是否可以用LSQ逼近任意函数(+前两个导数平滑)。 - JannaJ
1个回答

1

ALGLIB支持各种插值方法:

  • 多项式插值
  • 有理插值
  • 样条插值
  • 最小二乘拟合(线性/非线性)
  • 双线性和双三次样条插值
  • 快速RBF插值/拟合

我不知道它是否符合您的所有要求。我个人还没有使用过这个库,但我相信三次样条插值可能是您要寻找的(二次可微)。

为了防止过度拟合到嘈杂的输入点,您应该应用某种平滑机制,例如您可以尝试移动窗口平均值/高斯/FIR滤波器等。还可以查看(三次)平滑样条。


非常感谢提供ALGLIB链接。听起来很有前途。我也看了OpenCV,但是我找不到有关计算提取轮廓曲率的信息:( - JannaJ
@JannaJ 啊 - 你要找的是轮廓线的曲率而不是表面的曲率! - moooeeeep
抱歉造成误解。我更新了我的问题以使其更加精确。无论如何,我很惊讶使用OpenCV可以找到曲面的曲率,但不能找到轮廓的曲率? - JannaJ
据我所知,不是。 - moooeeeep

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