2017-10-13 11 views
1

J'ai un ensemble de coordonnées 3D (x,y,z) auquel je voudrais adapter une courbe de l'espace. Est-ce que quelqu'un sait des routines existantes pour cela en Python? De ce que j'ai trouvé (https://docs.scipy.org/doc/scipy/reference/interpolate.html), il existe des modules existants pour adapter une courbe à un ensemble de coordonnées 2d, et d'autres pour adapter une surface à un ensemble de coordonnées 3D. Je veux le chemin du milieu - en ajustant une courbe à un ensemble de coordonnées 3D.Obtenir une bonne interpolation/ajustement pour la courbe 1d dans l'espace 3D - Python

EDIT -

J'ai trouvé une réponse explicite à ce sur un autre poste ici, en utilisant interpolate.splprep() et interpolate.splenv(). Voici mes points de données:

21.735556483642707 7.9999120559310359 -0.7043281314370935 
21.009401429607784 8.0101161320825103 -0.16388503829177037 
20.199370045383134 8.0361339131845497 0.25664085801558179 
19.318149385194054 8.0540100864979447 0.50434139043379278 
18.405497793567243 8.0621753888918484 0.57169888018720161 
17.952649703401562 8.8413995204241491 0.39316793526155014 
17.539007529982641 9.6245700151356104 0.14326173861202204 
17.100154581079089 10.416295524018977 0.011339000091976647 
16.645143439968102 11.208477191735446 0.070252116425261066 
16.198247656768263 11.967005154933993 0.31087815045809558 
16.661378578010989 12.717314230004659 0.54140549139204996 
17.126106263351478 13.503461982612732 0.57743407626794219 
17.564249250974573 14.28890107482801 0.42307198199366186 
17.968265052275274 15.031985807202176 0.10156997950061938 

Voici mon code:

from scipy import interpolate 
from mpl_toolkits.mplot3d import Axes3D 

data = data.transpose() 

#now we get all the knots and info about the interpolated spline 
tck, u= interpolate.splprep(data, k=5) 
#here we generate the new interpolated dataset, 
#increase the resolution by increasing the spacing, 500 in this example 
new = interpolate.splev(np.linspace(0,1,500), tck, der=0) 

#now lets plot it! 
fig = plt.figure() 
ax = Axes3D(fig) 
ax.plot(data[0], data[1], data[2], label='originalpoints', lw =2, c='Dodgerblue') 
ax.plot(new[0], new[1], new[2], label='fit', lw =2, c='red') 
ax.legend() 
plt.savefig('junk.png') 
plt.show() 

Ceci est l'image:

Data and fit.

Vous pouvez voir que l'ajustement est pas bon, alors que J'utilise déjà la valeur d'ordre d'ajustement maximale autorisée (k=5). Est-ce parce que la courbe n'est pas entièrement convexe? Est-ce que quelqu'un sait comment je peux améliorer l'ajustement?

Répondre

0

Dépend de ce que les points représentent, mais s'il s'agit simplement de données de position, vous pouvez utiliser un kalman filter such as this one written in python. Vous pouvez simplement interroger le filtre kalman à tout moment pour obtenir le "point attendu" à ce moment-là, donc cela fonctionnerait comme une fonction du temps. Si vous prévoyez d'utiliser un filtre kalman, il vous suffit de définir l'estimation initiale sur votre première coordonnée et de définir votre covariance comme une matrice diagonale de nombres énormes, ce qui indiquera que vous êtes très incertain sur la position de votre point suivant, qui verrouillera rapidement le filtre sur vos coordonnées.

Vous voudriez éviter les méthodes d'ajustement de spline, car les splines passeront toujours par vos données.

0

Vous pouvez adapter une courbe à n'importe quelle donnée dimensionnelle. Les algorithmes d'ajustement de courbe/d'optimisation (disons, dans scipy.optimize) traitent tous les observations que vous voulez modéliser comme un tableau simple de 1 d, et ne se soucient pas de ce que sont les variables indépendantes. Si vous aplatissez vos données 3D, chaque valeur correspondra à un tuple (x, y, z). Vous pouvez simplement transmettre ces informations en tant que données «supplémentaires» à votre routine d'ajustement pour vous aider à calculer la courbe du modèle qui sera adaptée à vos données.

+0

J'ai mis à jour la question. S'il vous plaît voir ci-dessus. – ap21