Trapezkorrektur mit 3D-Punkten von Kinect

15

Mit XNA zeige ich ein einfaches Rechteck an, das auf den Boden projiziert wird. Der Projektor kann an einer beliebigen Position aufgestellt werden. Offensichtlich wird das projizierte Rechteck je nach Position und Winkel des Projektors verzerrt. Ein Kinect tastet den Boden nach den vier Ecken ab. Mein Ziel ist es nun, das ursprüngliche Rechteck so zu transformieren, dass die Projektion nicht mehr durch eine grundlegende Vorverzerrung des Rechtecks ​​verzerrt wird.

Mein erster Ansatz bestand darin, alles in 2D zu tun: Berechnen Sie zuerst eine Perspektiventransformation (mit OpenCVs warpPerspective()) von den gescannten Punkten zu den Punkten des internen Rechtecks ​​und wenden Sie die Umkehrung auf das Rechteck an. Dies schien zu funktionieren, war aber zu langsam, da es auf der GPU nicht gerendert werden konnte.

Der zweite Ansatz bestand darin, alles in 3D zu tun, um die Rendering-Funktionen von XNA zu nutzen. Zuerst würde ich eine Ebene anzeigen, ihre Ecken mit Kinect scannen und die erhaltenen 3D-Punkte der ursprünglichen Ebene zuordnen. Theoretisch könnte ich die Umkehrung der perspektivischen Transformation auf die Ebene anwenden, wie ich es im 2D-Ansatz getan habe. Da XNA jedoch mit einer Ansichts- und Projektionsmatrix arbeitet, kann ich nicht einfach eine Funktion wie aufrufen warpPerspective()und das gewünschte Ergebnis erzielen. Ich müsste die neuen Parameter für die Ansicht und die Projektionsmatrix der Kamera berechnen.

Frage: Ist es möglich, diese Parameter zu berechnen und in zwei Matrizen aufzuteilen (Ansicht und Projektion)? Wenn nicht, gibt es einen anderen Ansatz, den ich verwenden könnte?

philllies
quelle
1
XNA verwendet eine Ansichts- und eine Projektionsmatrix, aber ich denke, das Endergebnis = Vektor * Ansicht * Projektion. Warum versuchen Sie nicht, aus einer Identitätsmatrix und einer Projektion eine inverse Perspektivmatrix zu machen und zu prüfen, ob dies funktioniert? (Nicht 100% sicher, dass genau das passiert)
Roy T.
1
Wie genau haben Sie eine Perspektiventransformation berechnetwarpPespective ? Ich bin mit OpenCV nicht vertraut, aber das Lesen der doc es wie dieser Funktion sieht nur gilt eine Perspektive auf ein Bild. Oder bin ich verwirrt? Vielleicht würde es helfen, weitere Details zu Ihrer ersten Implementierung hinzuzufügen.
Laurent Couvidou
Vielleicht möchten Sie einen Blick in die PCL-Bibliothek werfen ( pointclouds.org ). Wenn Sie das Tiefenbild aus dem Kinect konvertieren, erhalten Sie eine Punktwolke, bei der die Kamera am Ursprung entlang der z-Achse zeigt. Sie könnten dann Ransac oder einen anderen Algorithmus verwenden, um nach dem Flugzeug zu suchen.
Exilyth

Antworten:

1

Da die Vektoralgebra GPU-freundlich ist, können Normalisierungen und Punktprodukte verwendet werden, um die vier Ecken der ursprünglichen Ebene wie folgt zu finden:

Bildbeschreibung hier eingeben

Ausgehend vom Projektionspunkt (P), dem projizierten Punkt (B), einem beliebigen Punkt auf der Ebene, der das verzerrte Rechteck (Q) enthält, und dem Normalenvektor zu dieser Ebene (n), dem Schnittpunkt (A) der Linie von P nach B, und die Ebene ist gegeben durch

s = -dot_product(n, P - Q) / dot_product(n, normalized(B - P)) 
A = P + s * normalized(B-P)

Quelle http://geomalgorithms.com/a05-_intersect-1.html Abschnitt Schnittebene

rraallvv
quelle