如何将Bézier曲线拟合到一组数据?

2024-05-21 00:17:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组数据点(可以精简)需要与Bézier curve匹配。我需要速度超过准确性,但适合应该是体面的,足以识别。我也在寻找一个我可以使用的算法,它不太使用库(特别是NumPy)。

我读过几篇研究论文,但没有一篇有足够的细节可以完全实现。有没有开源的例子?


Tags: 数据numpy算法开源精简细节速度例子
3条回答

我也有类似的问题,我发现了“一个自动拟合数字化曲线的算法”,来自Graphics Gems(1990)关于Bezier曲线拟合。 除此之外,我还为那篇文章找到了source code

不幸的是它是用C写的,我不太清楚。而且,算法很难理解(至少对我来说)。我想把它翻译成C代码。如果我能成功,我会努力与大家分享。

FitCurves.c位于同一文件夹中的文件GGVecLib.c包含基本向量操作函数。

我发现了一个类似的堆栈溢出问题,Smoothing a hand-drawn curve。经批准的答案提供了一个图形Gems曲线拟合算法的C#代码。

这些答案中缺少的是,你可能不想用一条三次Bézier曲线来拟合你的数据。一般来说,您希望将一系列三次Bézier曲线(即分段三次Bézier曲线)拟合到任意数据集。

有一篇很好的论文可以追溯到1995年,里面有MATLAB代码,它可以做到:

% Lane, Edward J. Fitting Data Using Piecewise G1 Cubic Bezier Curves.
% Thesis, NAVAL POSTGRADUATE SCHOOL MONTEREY CA, 1995

http://www.dtic.mil/dtic/tr/fulltext/u2/a298091.pdf

要使用此选项,必须至少指定结点数,即优化例程将使用的数据点数,以使此匹配。(可选)可以指定节点本身,从而提高拟合的可靠性。这篇论文举了一些很难的例子。注意,Lane的方法保证了三次Bézier段之间G1的连续性(相邻切线向量的方向相同),即光滑的关节。但是,曲率可能存在不连续性(二阶导数方向的变化)。

我已经重新实现了代码,并将其更新为现代的MATLAB(R2015b)。如果你愿意的话请联系我。

下面是一个使用三个节点(由代码自动选择)的示例,它将两个三次Bézier分段拟合到Lissajous图形。

Lissajous figure

如果大多数数据符合模型,可以尝试RANSAC。从中随机选取4个点并拟合出贝塞尔曲线就足够简单了。我不确定用其他所有点来计算曲线(RANSAC算法的一部分)有多贵。但这将是一个线性解决方案,RANSAC非常容易编写(而且可能有开源算法)。

相关问题 更多 >