如何将贝塞尔曲线拟合到一组数据?
5 个回答
3
如果大部分数据都符合你的模型,你可以试试 RANSAC 这个方法。你可以随机选取4个点,然后用这些点来拟合一条贝塞尔曲线。至于要把这条曲线和其他所有点进行比较需要花费多少时间,我现在不太确定(这是RANSAC算法的一部分)。不过,这个过程是线性的,也就是说它的效率还不错,而且RANSAC的实现起来很简单(网上可能还有开源的算法可以用)。
16
很多回答中缺少的一点是,你可能不想只用一条三次贝塞尔曲线来拟合你的数据。更一般来说,你可能希望用一系列的三次贝塞尔曲线,也就是分段的三次贝塞尔拟合,来处理任意的数据集。
有一篇很不错的论文,早在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)。如果你需要,可以联系我。
下面是一个例子,使用了三个节点点(由代码自动选择),拟合了两个三次贝塞尔段到一个Lissajous图形上。