web-dev-qa-db-fra.com

Comment adapter une courbe de Bézier à un ensemble de données?

J'ai un ensemble de points de données (que je peux éclaircir) que je dois adapter à une courbe courbe de Bézier . J'ai besoin de rapidité plutôt que de précision, mais l'ajustement devrait être suffisamment décent pour être reconnaissable. Je cherche aussi un algorithme que je peux utiliser et qui n’utilise pas beaucoup les bibliothèques (en particulier NumPy ).

J'ai lu plusieurs documents de recherche, mais aucun n'a suffisamment de détails pour être pleinement mis en œuvre. Existe-t-il des exemples open-source?

22
user791684

J'ai un problème similaire et j'ai trouvé "Un algorithme pour ajuster automatiquement les courbes numérisées" de Graphics Gems (1990) sur l'ajustement des courbes de Bézier. En plus de cela, j'ai trouvé code source pour cet article. 

Malheureusement, il est écrit en C que je ne connais pas très bien. En outre, l'algorithme est assez difficile à comprendre (du moins pour moi). J'essaie de le traduire en code C #. Si je réussis, je vais essayer de le partager.

Le fichier GGVecLib.c dans le même dossier que FitCurves.c contient les fonctions de base de manipulation de vecteurs.

J'ai trouvé une question de débordement de pile similaire,Lissage d'une courbe dessinée à la main. La réponse approuvée fournit le code C # pour un algorithme d'ajustement de courbe de Graphic Gems.

17
Archibald

Ce qui manque dans beaucoup de ces réponses, c'est que vous ne souhaiterez peut-être pas adapter une courbe de Bézier cubique unique à vos données. Plus généralement, vous voudriez ajuster une séquence de courbes de Bézier cubiques, c'est-à-dire un ajustement de Bézier cubique par morceaux, à un ensemble arbitraire de données. 

Il y a une thèse de Nice datant de 1995, complétée avec le code MATLAB, qui fait ceci:

% 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

Pour utiliser cela, vous devez au minimum spécifier le nombre de nœuds, c’est-à-dire le nombre de points de données qui seront utilisés par les routines d’optimisation pour y parvenir. Vous pouvez également spécifier les points de nœud eux-mêmes, ce qui augmente la fiabilité d'un ajustement. La thèse montre des exemples assez difficiles. Notez que l'approche de Lane garantit la continuité G1 (les directions des vecteurs tangents adjacents sont identiques) entre les segments de Bézier cubiques, c'est-à-dire les joints lisses. Cependant, il peut y avoir des discontinuités dans la courbure (changements de direction de la dérivée seconde).

J'ai réimplémenté le code, en le mettant à jour vers MATLAB moderne (R2015b). Contactez moi si vous le souhaitez. 

Voici un exemple d’utilisation de trois nœuds (choisis automatiquement par le code) qui adapte deux segments de Bézier cubiques à une figure de Lissajous. 

 Lissajous figure

9
Biofloat

Vous pouvez configurer le problème sous la forme de moindres carrés s’adaptant aux données bruitées.

Voir http://nbviewer.ipython.org/5688579

Notez qu'une fois que vous avez compris les équations, le calcul réel est assez simple. Les calculs réels se résument sur les données, puis inversent et multiplient une matrice 4x4.

Je sais que ce fil est mort depuis longtemps, mais j'ai trouvé que c'était un problème intéressant au cas où quelqu'un d'autre tomberait dessus.

Voir http://www.embedded.com/electrical-engineer-community/industry-blog/4027019/1/Why-all-the-math- pour un excellent tutoriel sur les moindres carrés.

5
Luke Whittlesey

Vous trouverez ici une implémentation python du code C référé. https://github.com/volkerp/fitCurves

2
Fred Guth

Si la plupart des données correspondent au modèle, vous pouvez essayer RANSAC . Il serait assez facile de choisir 4 points et aléatoire et ajuster une courbe de Bezier de ceux-ci. Je ne sais pas très bien à quel point il serait coûteux d'évaluer la courbe par rapport à tous les autres points (partie de l'algorithme RANSAC). Mais ce serait une solution linéaire et RANSAC est vraiment facile à écrire (et il existe probablement des algorithmes open source).

2
Pace

Tout d’abord, assurez-vous que vous demandez ce que vous voulez. En ajustant les points à une courbe de Bézier, vous les placerez dans la coque des points. L'utilisation d'une spline vous assurera que votre courbe passe par tous les points. 

Cela dit, créer la fonction qui dessine l'un ou l'autre n'est pas compliqué du tout. Wikipedia a un article de Nice qui expliquera les bases,courbe de Bézier.

0
Pedery

J'avais une solution MATLAB pour ce problème. J'ai rencontré le même problème, mais mon code est écrit en MATLAB. J'espère que ce n'est pas trop difficile de le traduire en Python.

Vous pouvez trouver les points de contrôle à l'aide de ce code FindBezierControlPointsND.m Pour une raison quelconque, il n'a pas de fonction "ChordLengthNormND" dans son archive, , Mais il est appelé à la ligne 45.

Je l'ai remplacé par les lignes suivantes:

[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;

Le code MATLAB de arclength peut être obtenu ici.

Après cela, nous avons des points de contrôle pour la courbe de Bézier et il existe de nombreuses implémentations de construction de la courbe de Bézier par des points de contrôle sur le Web.

0
lintseju