Finden, translation und Skalierung auf zwei Sätze von Punkte zu bekommen, die kleinste quadratische Fehler in der Entfernung?
Ich habe zwei Sätze von 3D-Punkten (original und nachgebaut) und Korrespondenz Informationen über die Paare - die Stelle aus einem Satz darstellt, die zweite. Ich muss 3D-translation und Skalierung Faktor, welche die Transformationen rekonstruieren festgelegt, sodass die Summe der quadratischen Abstände würden zumindest (rotation wäre auch schön, aber Punkte sind gedreht, ebenso, so ist dies nicht erste Priorität und könnte weggelassen werden, im Interesse der Einfachheit und Schnelligkeit). Und so ist meine Frage - ist dieses Problem gelöst und irgendwo im Internet? Persönlich würde ich verwenden, kleinste-Quadrate-Methode, aber ich habe nicht viel Zeit (und ich bin zwar einigermaßen gut in Mathe, ich benutze es nicht oft, also wäre es besser für mich, es zu vermeiden), so möchte ich eine andere Lösung, wenn es vorhanden ist. Ich bevorzuge die Lösung in C++, zum Beispiel unter Verwendung von OpenCV, aber-Algorithmus allein ist gut genug.
Wenn es keine solche Lösung finden, werde ich es berechnen von mir, ich will nicht, Sie zu stören so viel.
LÖSUNG: (aus den Antworten)
Für mich ist es Kabsch alhorithm;
Basis-info: http://en.wikipedia.org/wiki/Kabsch_algorithm
Allgemeine Lösung: http://nghiaho.com/?page_id=671
NOCH NICHT GELÖST:
Ich muss auch Maßstab. Skala Werte von SVD sind für mich nicht verständlich; wenn ich brauche, Maßstab etwa 1-4 für alle Achsen (geschätzt von mir), SVD-Skala ist über [2000, 200, 20], die nicht an allen hilft.
Evgeny Kluev: ich danke Ihnen sehr, es sieht aus wie es ist. Ich werde versuchen und post-Ergebnisse (es wird einige Zeit dauern; ich habe einige andere Sachen zu implementieren). By the way, zum Glück für mich, OpenCV enthält SVD-Rechner, das vereinfacht vieles.
Evgeny Kluev: ich zutiefst entschuldige mich für die so späte Antwort: ich hatte mehr wichtige Projekte. Ich möchte Sie Fragen, wie soll ich das deuten Skalierungsfaktoren? Diese zahlen sind wirklich groß (200 - 2000) oder klein (~0.5), aber von meinem Urteil, Waage sollte etwa 1-4. Und auch, scale-Faktoren sind oft für verschiedene Achse (zum Beispiel [2000, 200, 20]).
Eigentlich gibt es keinen Weg, um Skalierungsfaktoren direkt von singulären Werte. Mein Fehler. Sorry. SVD-basierten Algorithmus anwendbar sein kann hier, aber ich weiß nicht, wie. Sie sind In jedem Fall kalt versuchen, mehr Allgemeinen Iterative closest point Algorithmus.
Haben Sie schaute auf meine Antwort unten? Erhalten Sie die Skala von Eigen-als auch eigen.tuxfamily.org/dox/... natürlich, dies setzt Voraus, Sie haben die Korrespondenzen
InformationsquelleAutor | 2012-11-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da Sie bereits Kabsch Algorithmus, werfen Sie einen Blick auf Umeyama Papier die sich es zu Holen Skala. Alles, was Sie tun müssen, ist, um die Standardabweichung Ihrer Punkte und berechnen Maßstab:
wo
D
ist die diagonal-matrix mit SVD-ZERLEGUNG in der rotation estimation andS
ist entweder die Einheitsmatrix oder[1 1 -1]
Diagonale matrix, je nach dem Vorzeichen der Determinante vonUV
(Kabsch verwendet, um die korrekte Reflexionen in der richtigen Rotationen). Also, wenn Sie[2000, 200, 20]
multiplizieren Sie das Letzte element von +-1 (je nach dem Vorzeichen der Determinante vonUV
), Summe Sie und dividieren durch die Standardabweichung Ihrer Punkte zu Holen Skala.Können Sie recyceln, der folgende code, der ist mit dem Eigen Bibliothek:
naja, um ehrlich zu sein, weiß ich nicht Skala der Kovarianz-matrix (wie man im code sehen). Der Algorithmus würde wahrscheinlich funktionieren, aber der Maßstab der Berechnung würde nicht. Große zahlen in D sind nicht unbedingt problematisch, als das Ausmaß hängt auch von der Standardabweichung, die vielleicht groß (oder klein) durch sich selbst, unabhängig von der Skala. Danke für das Lob obwohl.
Als seitliche Anmerkung, manche Menschen es vorziehen Horn-Algorithmus. Es ist sehr ähnlich zu Kabsch, mit der Ausnahme, dass es zersetzt eine 4x4-matrix, und die Ausgabe ist eine quaternion. Zu mir, es scheint nur mehr etwas aufwändig zu berechnen, so dass ich stick mit Kabsch und konvertieren Sie die 3x3-matrix in ein Quaternion danach. Ich bin mir nicht ganz sicher, ob es eine version von Horn-Algorithmus, der erholt sich die Skala als gut.
Vielen Dank für die tolle Antwort. Ich habe ein 20 Zeilen Python-Implementierung des vollen Problems hier, die ich versucht habe, zu Stimmen, für die Verständlichkeit.
InformationsquelleAutor the swine
Für 3D-Punkte ist das problem bekannt, wie die Absolute Ausrichtung problem. Eine c++ - Implementierung ist verfügbar von Eigen http://eigen.tuxfamily.org/dox/group__Geometry__Module.html#gab3f5a82a24490b936f8694cf8fef8e60 und Papier http://web.stanford.edu/class/cs273/refs/umeyama.pdf
können Sie es über opencv durch die Umwandlung der Matrizen zu eigen mit cv::cv2eigen () - Aufrufe.
InformationsquelleAutor bendervader
Möchten Sie vielleicht versuchen, ICP - (Iterative closest point).
Zwei Sätze von 3d-Punkten, es wird Ihnen sagen, die transformation (rotation + translation) vom ersten auf den zweiten.
Wenn Sie interessiert sind, in einer c++ - einfache Implementierung, versuchen libicp.
Glück!
ICP ist unnötig kompliziert und langsam, wenn die Korrespondenzen zwischen den Punkten sind bekannt. Für Kabsch wissen Sie bereits, die Korrespondenzen zwischen den Punkten. ICP kann passen zu jedem Punkt zwei Sätze (unterschiedliche Anzahl von Punkten, nur teilweise sich überschneidende Formen,...), aber natürlich zu einem viel höheren Preis und mit der Gefahr, dass es nicht zusammen, um die beste Lösung.
InformationsquelleAutor Nacho
Beginnen mit der übersetzung der beiden Sätze von Punkte. So, dass Ihr Schwerpunkt fällt mit dem Ursprung des Koordinatensystems. Translationsvektor ist eben der Unterschied zwischen diesen centroide.
Nun haben wir zwei Sätze von Koordinaten dargestellt, die als Matrizen P und Q. Eine Reihe von Punkten erlangt werden kann, werden von einer durch die Anwendung einiger linearer operator (das führt sowohl rotation und Skalierung). Dieser operator wird vertreten durch die 3x3-matrix X:
P * X = Q
Finden der richtigen Skalierung/rotation wir müssen Sie nur lösen diese matrix-Gleichung, finden X, dann zerlegen Sie diese in mehrere Matrizen, die jeweils einige Skalierung oder rotation.
Einer einfachen (aber wahrscheinlich nicht numerisch stabil) Art und Weise zu lösen, es ist zu multiplizieren Sie beide Teile der Gleichung, um die transponierte matrix P (loswerden von nicht-quadratischen Matrizen), dann multiplizieren Sie beide Teile der Gleichung für die umgekehrte PT * P:
PT * P * X = PT * Q
X = (PT * P)-1 * PT * Q
Anwendung Singulärwertzerlegung zu matrix X gibt zwei rotation Matrizen und matrix-mit Skala Faktoren:
X = U * S * V
Hier S ist eine Diagonale matrix mit den Skalierungsfaktoren (eine Skala für jede Koordinate), U und V sind rotation Matrizen, eine richtig dreht die Punkte so, dass Sie skaliert werden können, die entlang der Koordinatenachsen, der andere dreht Sie einmal mehr richten sich die Ausrichtung auf den zweiten Satz von Punkten.
Beispiel (2D-Punkte verwendet werden, für die Einfachheit):
Nach der Lösung der Gleichung:
Nachdem SVD-ZERLEGUNG:
Hier SVD hat richtig rekonstruiert alle Manipulationen, die ich geleistet habe auf matrix P zu bekommen-matrix Q: drehen um den Winkel 0.75, Skalierung der X-Achse von 4, Maßstab Y-Achse von 3, drehen um den Winkel -0.25.
Wenn Sätze Punkte sind einheitlich skaliert (Skalierungsfaktor gleich von jeder Achse), dieses Verfahren kann erheblich vereinfacht.
Verwenden Sie einfach Kabsch Algorithmus zu bekommen translation/rotation-Werte. Dann führen Sie diese translation und rotation (centroide sollte zeitgleich mit dem Ursprung des Koordinatensystems). Dann wird für jedes paar von Punkten (und für jede Koordinate) Schätzung Lineare regression. Lineare regression Koeffizient ist genau der Skalierungsfaktor.
im 2D-Fall ist trivial: matrix-Komponenten sind nur sin und cos des Winkels. im 3D-Fall: die Drehachse ist bestimmt durch Eigenvektor, dann finden Sie den Winkel zwischen einem Vektor senkrecht zu der Achse und den gleichen Vektor transformiert durch die rotation matrix. Details finden Sie unter wikipedia.
Danke, Evgeny, vor allem für den link zu Wikipedia. In Ihrem Beispiel, wie haben Sie bestimmen, ob -0.7317 oder 0.7317 für den Cosinus?
Ehrlich gesagt, weiß ich nicht. Das problem ist, dass einige Zeilen der matrix von SVD werden annulliert, und ich weiß nicht, was. Der einzige Weg, um diese Daten nutzen, (ohne zu Graben tiefer in das problem) ist, zu versuchen, beide Möglichkeiten, die Drehung anzuwenden, um die tatsächlichen Punkte und sehen, welche richtig ist.
InformationsquelleAutor Evgeny Kluev
Eine gute Erklärung Die Suche nach optimalen rotation und translation zwischen den entsprechenden 3D-Punkte
Sich der code in matlab, aber es ist trivial zu konvertieren, um opengl mit der cv::SVD-Funktion
Dieser Ansatz funktioniert nur mit gleich große Wolken. Normal kennt man die Wolken, den gleichen Maßstab, den ich habe nicht versucht es, aber es ist ein scale-Ansatz google.com/...
InformationsquelleAutor Martin Beckett
Die Allgemeine transformation, als auch die Waage kann abgerufen werden über Prokrustes-Analyse. Es funktioniert durch die überlagerung der Objekte auf der jeweils anderen und versucht zu schätzen, die transformation, die von dieser Einstellung. Es wurde im Rahmen des ICP, viele Male. In der Tat, Ihre Einstellung, Kabash-Algorithmus ist ein Spezialfall dieser.
Außerdem, Horn-alignment-Algorithmus (basierend auf Quaternionen) findet auch eine sehr gute Lösung sind, während Sie sehr effizient. Ein Matlab-Implementierung ist auch verfügbar.
InformationsquelleAutor Tolga Birdal
Maßstab abgeleitet werden kann, ohne SVD, wenn Sie Ihre Punkte sind gleichmäßig in alle Richtungen skaliert (ich konnte nicht Sinn der SVD-s-Skala-matrix). Ist hier, wie ich gelöst habe das gleiche problem:
Messen von Entfernungen eines jeden Punktes auf andere Punkte in der Punktwolke um eine 2d-Tabelle der Strecken, wo der Eintrag in (i,j) ist die norm(point_i-point_j). Machen Sie dasselbe für die andere Punktwolke, so erhalten Sie zwei Tabellen-eine für die original-und die andere für die rekonstruierten Punkte.
Teilt alle Werte in einer Tabelle durch die entsprechenden Werte in der anderen Tabelle. Da die Punkte einander entsprechen, die Entfernungen auch. Im Idealfall ist die resultierende Tabelle hat alle Werte einander gleich, und das ist der Maßstab.
Wird der Mittelwert der Divisionen sollte ziemlich in der Nähe der Skala, die Sie suchen. Der Mittelwert ist auch in der Nähe, aber ich wählte median nur um Ausreißer auszuschließen.
Nun können Sie den scale-Wert zu skalieren alle rekonstruierten Punkte und dann gehen Sie zu der Schätzung der rotation.
Tipp: Wenn es zu viele Punkte in den Punktwolken zu finden, Entfernungen zwischen allen von Ihnen, dann eine kleinere Teilmenge von Entfernungen funktioniert auch, solange es die gleiche Teilmenge für beide Punktwolken. Im Idealfall nur eine Distanz-pair-Mädchen arbeiten würde, wenn es keine Messung von Lärm, e.g wenn eine Punktwolke ist direkt abgeleitet von der anderen nur durch drehen.
InformationsquelleAutor Rasmus
können Sie auch ScaleRatio ICP-vorgeschlagen von BaoweiLin
Der code ist im github
InformationsquelleAutor user3654844