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

发布于 2024-11-15 00:32:04 字数 306 浏览 10 评论 0原文

我有一组数据点(我可以将其稀疏化),需要将其与 相匹配贝塞尔曲线。我需要的是速度而不是准确性,但贴合度应该足够好,可以被识别。我也在寻找一种可以使用的算法,该算法不会过多使用库(特别是 NumPy)。

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

I have a set of data points (which I can thin out) that I need to fit with a Bézier curve. I need speed over accuracy, but the fit should be decent enough to be recognizable. I'm also looking for an algorithm I can use that doesn't make much use of libraries (specifically NumPy).

I've read several research papers, but none has enough detail to fully implement. Are there any open-source examples?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌面超妹 2024-11-22 00:32:04

我有类似的问题,我从 Graphics Gems (1990) 中找到了关于贝塞尔曲线拟合的“自动拟合数字化曲线的算法”。
除此之外,我还发现 源代码

不幸的是它是用C 编写的,我不太了解。而且,该算法很难理解(至少对我来说)。我正在尝试将其转换为 C# 代码。如果我成功了,我会尝试分享。

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

我发现了一个类似的 StackOverflow 问题,平滑手绘曲线。批准的答案提供了来自 Graphic Gems 的曲线拟合算法的 C# 代码。

I have similar problem and I have found "An algorithm for automatically fitting digitized curves" from Graphics Gems (1990) about Bezier curve fitting.
Additionally to that I have found source code for that article.

Unfortunately it is written in C which I don't know very well. Also, the algorithm is quite hard to understand (at least for me). I am trying to translate it into C# code. If I will be successful, I will try to share it.

File GGVecLib.c in the same folder as FitCurves.c contains basic vectors manipulation functions.

I have found a similar Stack Overflow question, Smoothing a hand-drawn curve. The approved answer provide C# code for a curve fitting algorithm from Graphic Gems.

独﹏钓一江月 2024-11-22 00:32:04

许多这些答案中缺少的是,您可能不想将单个三次贝塞尔曲线拟合到您的数据。更一般地,您希望将一系列三次贝塞尔曲线(即分段三次贝塞尔曲线)拟合到任意数据集。

有一篇 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)。如果您愿意,请联系我。

下面是仅使用三个结点(由代码自动选择)将两个三次贝塞尔线段拟合为利萨如图形的示例。

李萨如图形

What's missing in a lot of these answers is that you may not want to fit a single cubic Bézier curve to your data. More generally, you would like to fit a sequence of cubic Bézier curves, i.e., a piecewise cubic Bézier fit, to an arbitrary set of data.

There's a nice thesis dating from 1995, complete with MATLAB code, that does this:

% 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

To use this, you must, at minimum, specify the number of knot points, i.e., the number data points that will be used by the optimization routines to make this fit. Optionally, you can specify the knot points themselves, which increases the reliability of a fit. The thesis shows some pretty tough examples. Note that Lane's approach guarantees G1 continuity (directions of adjacent tangent vectors are identical) between the cubic Bézier segments, i.e., smooth joints. However, there can be discontinuities in curvature (changes in direction of second derivative).

I have reimplemented the code, updating it to modern MATLAB (R2015b). Contact me if you would like it.

Here's an example of using just three knot points (chosen automatically by the code) the fits two cubic Bézier segments to a Lissajous figure.

Lissajous figure

帅的被狗咬 2024-11-22 00:32:04

如果大部分数据都符合模型,您可以尝试 RANSAC。很容易选择 4 个点并随机并从中拟合贝塞尔曲线。我无法确定根据所有其他点(RANSAC 算法的一部分)评估曲线的成本有多大。但这将是一个线性解决方案,而且 RANSAC 确实很容易编写(并且可能有开源算法)。

If most of the data fits the model you could try RANSAC. It would be easy enough to pick 4 points and random and fit a bezier curve from those. I'm not sure off the top of my head how expensive it would be to evaluate the curve against all the other points (part of the RANSAC algorithm). But it would be a linear solution and RANSAC is really easy to write (and there are probably open source algorithms out there).

轻许诺言 2024-11-22 00:32:04

我有一个 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 代码可以在这里获取。

之后我们就有了贝塞尔曲线的控制点,网上有很多通过控制点构建贝塞尔曲线的实现。

I had a MATLAB solution for this problem.
I encountered the same problem, but my code is written in MATLAB.
I hope its not too hard to translate it into Python.

You can find the control points by this code FindBezierControlPointsND.m
For some reason, it does not have function "ChordLengthNormND" in its archive,
but it is called at line 45.

I replaced it by following lines:

[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's MATLAB code can be obtained here.

After that, we have control points for Bezier curve, and there are lots of implementation of building Bezier curve by control points on the web.

浅唱々樱花落 2024-11-22 00:32:04

首先,确保你所要求的确实是你想要的。将点拟合到贝塞尔曲线会将它们放置在点的外壳中。使用样条线将确保您的曲线经过所有点。

也就是说,创建绘制任意一个的函数并不复杂。维基百科有一篇很好的文章将解释基础知识,贝塞尔曲线< /em>。

First of all, make sure what you ask for is actually what you want. Fitting the points to a Bezier curve will place them in the hull of the points. Using a spline will make sure your curve goes through all points.

That said, creating the function that draws either is not complicated at all. Wikipedia has a nice article that will explain the basics, Bézier curve.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文