我有一组数据点(我可以将其稀疏化),需要与 Bézier 曲线 进行拟合。我需要的是速度而不是准确性,但贴合度应该足够好,可以被识别。我也在寻找一种可以使用的算法,该算法不会过多使用库(特别是NumPy)。
我读过几篇研究论文,但没有一篇有足够的细节来完全实施。有没有开源的例子?
这些答案中缺少的是,您可能不想将单个三次贝塞尔曲线拟合到您的数据。更一般地,您希望将一系列三次贝塞尔曲线(即分段三次贝塞尔曲线)拟合到任意数据集。
有一篇 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 的方法保证三次贝塞尔线段之间的 G1 连续性(相邻切向量的方向相同),即平滑关节。然而,曲率可能存在不连续性(二阶导数方向的变化)。
我重新实现了代码,将其更新为现代 MATLAB (R2015b)。如果您愿意,请联系我。
这是一个仅使用三个结点(由代码自动选择)的示例,将两个三次贝塞尔线段拟合为利萨如图形。
如果大部分数据符合模型,您可以尝试RANSAC。很容易选择 4 个点并随机并从中拟合贝塞尔曲线。我无法确定根据所有其他点(RANSAC 算法的一部分)评估曲线的成本有多大。但这将是一个线性解决方案,而且 RANSAC 确实很容易编写(而且可能有开源算法)。
首先,确保你所要求的确实是你想要的。将点拟合到贝塞尔曲线会将它们放置在点的外壳中。使用样条线将确保您的曲线经过所有点。
也就是说,创建绘制任意一个的函数并不复杂。维基百科有一篇很好的文章将解释基础知识,贝塞尔曲线。
我有一个 MATLAB 解决方案来解决这个问题。 我遇到了同样的问题,但我的代码是用 MATLAB 编写的。 我希望将其翻译成Python不会太难。
您可以通过此代码找到控制点FindBezierControlPointsND.m 由于某种原因,它的存档中没有函数“ChordLengthNormND”, 但它是在第 45 行调用的。
我用以下几行替换了它:
[arclen,seglen] = arclength(p(:,1),p(:,2),'sp');
t = zeros(size(p,1),1);
sums = seglen(1);
for i = 2:size(p,1)-1
t(i) = sums / arclen;
sums = sums + seglen(i);
end
t(end) = 1;
arclength的MATLAB代码可以在这里获得。
之后我们就有了贝塞尔曲线的控制点,网上有很多通过控制点构建贝塞尔曲线的实现。