Kamera Kalibration

Einstiegsfragen, Mathematik, Physik, künstliche Intelligenz, Engine Design
Antworten
Dragontear
Beiträge: 5
Registriert: 07.06.2007, 13:38

Kamera Kalibration

Beitrag von Dragontear »

Hallo,

ich hatte dieses Thema schon im Developia Forum geöffnet und wollte es hier nochmal posten. Ich bin mir nicht ganz sicher unter welchen Bereich ist das Tehma packen soll, aber ich hoffe hier ist es erstmal gut aufgehoben.
Im Moment sitze ich an der Kamerakalibration und habe da so ein paar Fragen bezüglich der Vorgehensweise. Als Bibliothek benutze ich OpenCV.

Ich fange erstmal ganz klein an, so dass etwaige Folgefehler sichtbar werden.
http://www.imagebanana.com/view/8urtt1b1/S5002865.JPG
Unten rechts ist das Prinzip einer Lochkamera zu sehen. Der Schnittpunkt beider Gerade ist die Lochblende. So ergibt sich nach Strahlensätzen die Gleichung darunter. Um das alles ein wenig zu vereinfachen wird die Projektionsebene (Imager), nach vorne geschoben. Das sieht man dann in der Zeichnung darunter. An der Mathematik ändert sich nicht viel, nur, dass alles jetzt ein wenig anschaulicher ist. Diese Annahme führt dann zu dem Bild oben links.
Oben rechts sind die Gleichungen für die Koordinaten aufgelistet (Bei der zweiten muss es Y/Z heissen). Erst einmal zu den Konstanten cx und cy.
Die optische Achse(Optical axis) sollte eigentlich in der Mitte der Projektionsebene liegen, so dass der Principal Point den Mittelpunkt dieser Ebene darstellt, aber die Kameras sind niemals so genau konstruiert, dass es auch eintrifft, deswegen geben cx und cy die Verschiebung in die jeweilige Richtung an.

Nun zu der Brennweite (Focal length). Das habe ich nicht ganz verstanden. Es wurde gesagt, dass die individuellen Pixel in einer Projektionsebene bei vielen billig Kameras nie quadratisch, sondern rechteckig sind. Deswegen gibt es weitere Paramter sx und sy die als Einheit Pixel pro Millimeter haben (Pixel/mm), dabei ist Millimeter nur eine Beispielgröße, denn es kann jede beliebige größe haben. Die Brennweite für die x-Koordinate ergibt sich dann also aus dem Produkt der physikalischen Brennweite und sx (fx = sx*F).
Ich habe mir unten links dafür ein Bild gezeichnet. Die Maße gelten für ein Kästchen in horizontaler, sowie vertikaler Richtung. Ich bin mir nicht sicher, ob meine Vorstellung davon richtig ist, denn ich hab eigentlich gar keine Ahnung warum das nötig ist. :?


Nun hat man also ein paar Konstanten, die die Kamera definieren. Um das alles schön zu verpacken werden die Konstanten in eine Matrix gepackt.
http://www.imagebanana.com/view/1pcd20a ... 010048.jpg
Dabei werden homogene Koordinaten benutzt (beim Punkt p ersichtlich). So ergeben sich dann die Gleichungen, die ich oben schon aufgezeigt habe.
Diese Matrix M nennt sich Intrinsics Matrix.
Dazu gesellt sich noch ein Distortion-Vector (im Bild fälschlicherweise Distortion Matrix genannt). Die Herleitung nehme ich einfach mal so hin, da ich von Taylor-Reihen etc. keine Ahnung habe.
http://www.imagebanana.com/view/xkfg3xvx/S5002866.JPG
Es gibt die radiale- und die tangentiale-Verzerrung, die überwiegend eine Rolle spielen.


Nachdem man sich jetzt diesen Problemen entledigt hat, geht man genauer auf die Überführung von Punkten aus der realen Welt in die Projektionseben ein.
http://www.imagebanana.com/view/qza1qm6 ... 010050.jpg
Wie darf ich mir hier aber die Funktion des Translationsvektors t vorstellen? Es wird gesagt, dass er dazu dient die Koordinatenursprünge auf einen Punkt zu bringen, sodass O in C liegt. Heisst es dass der Punkt P0 dann auf der Projektionsebene liegt, also in Pc? Und woher taucht plötzlich das Koordinatensystem des Objekts bzw. des Punktes P0 auf bzw. wie wird es definiert?
Wie kann ich mir außerdem die Rotation erklären? Wozu muss rotiert werden? Werden nicht einfach alle Punkte durch einen Translationsvektor auf die Projektionsebene gebracht?

Ich habe für mich bis jetzt nur eine Erklärung für die Rotation gefunden. Wenn der Punkt Q in einem der Quadranten liegt, also nicht in der xz- oder yz-Ebene (z = otpische achse), so muss der Punkt rotiert werden, damit sich die Beziehungen vom ersten Whiteboardbild ergeben und man die Koordinaten für den repräsentativen Punkt q berechnen kann:
http://www.imagebanana.com/view/cth0isq ... 010049.jpg
Rechts sind die beiden Rotationen schon vollführt worden, sodass der Punkt in der jeweiligen Ebene liegt. So ergeben sich die Beziehungen da drüber, die zu den ursprünglichen Formeln im ersten Whiteboardbild führen.

Wenn dies der Fall ist, wozu wird dann noch der Translationsvektor gebraucht, denn er ist ja im endeffekt nichts anderes, als die direkte Verbindungslinie von q und Q und hat mit den Gleichungen des ersten Whiteboardbildes nichts zu tun.


Mir stellt sich also die Frage warum zugleich rotiert und transferiert werden muss.
Alexander Kornrumpf
Moderator
Beiträge: 2114
Registriert: 25.02.2009, 13:37

Re: Kamera Kalibration

Beitrag von Alexander Kornrumpf »

Ich hab das OpenCV Buch jetzt leider nicht hier.
Nun zu der Brennweite (Focal length). Das habe ich nicht ganz verstanden. Es wurde gesagt, dass die individuellen Pixel in einer Projektionsebene bei vielen billig Kameras nie quadratisch, sondern rechteckig sind. Deswegen gibt es weitere Paramter sx und sy die als Einheit Pixel pro Millimeter haben (Pixel/mm), dabei ist Millimeter nur eine Beispielgröße, denn es kann jede beliebige größe haben. Die Brennweite für die x-Koordinate ergibt sich dann also aus dem Produkt der physikalischen Brennweite und sx (fx = sx*F).
Ich habe mir unten links dafür ein Bild gezeichnet. Die Maße gelten für ein Kästchen in horizontaler, sowie vertikaler Richtung. Ich bin mir nicht sicher, ob meine Vorstellung davon richtig ist, denn ich hab eigentlich gar keine Ahnung warum das nötig ist.
Soweit ich mich an das Buch erinnere geht es dabei nicht nur um das Format der individuellen Pixel sondern um das Format der Projektionsfläche an sich, die rechteckig ist. Die einheit Milimeter ist deshalb egal, weil du ja sx[Pixel/Milimeter]*F[Milimeter] rechnest und sich die Einheit kürzt. Was dabei herauskommt ist die Brennweite in Pixeln bei gegebener Auflösung würde ich sagen. Und ich vermute der Grund dafür ist einfach dass man gerne alles in einer Einheit haben würde. Aber ich kann mich natürlich irren.
Und woher taucht plötzlich das Koordinatensystem des Objekts bzw. des Punktes P0 auf bzw. wie wird es definiert?
Ich würde behaupten das Weltkoordinatensystem kannst du frei definieren. Bei allem weiteren geht es einfach um den Zusammenhang zwischen Welt- und Bildkoordinaten. Genaueres kann ich dazu aus dem Stehgreif leider nicht sagen, aber vielleicht hilft die Erkenntnis dass das Weltkoordinatensystem einfach irgendeins ist ja schonmal etwas weiter.
Dragontear
Beiträge: 5
Registriert: 07.06.2007, 13:38

Re: Kamera Kalibration

Beitrag von Dragontear »

Nachdem ich ein wenig mit OpenGL rumgespielt habe ist mir auch der Gedanke gekommen, dass das Weltkoordinatensystem frei definiert werden kann und alles andere dann nur noch in Relation zu diesem steht.
Ich habe auf Youtube eine Reihe von Vorträgen gesehen, die ganz gut auf dieses Thema eingehen.
http://www.youtube.com/watch?v=VYgFAdvD ... re=channel
Interessant wird es ab 41:50. Da beginnt er mit dem was ich oben schon beschrieben habe, außer, dass er die Vereinfachung mit der Projektionsebene nicht macht. Irgednwann führt er aber die "perspective transformation matrix" ein. Mir ist jetzt aber nicht klar, was diese bewirken soll.
Er sagt, dass diese Matrix dafür benutzt wird, um die homogenen Weltkoordinaten in homogene Kamerakoordinaten zu überführen. Dabei ändert sich aber nur der letzte Wert des Vektors zu -k(lambda/Z)+k. Alles andere bleibt so. Wozu ist das nun also nötig?
Dragontear
Beiträge: 5
Registriert: 07.06.2007, 13:38

Re: Kamera Kalibration

Beitrag von Dragontear »

Ich bin langsam echt am Verzweifeln! Ich hab keinen blassen Schimmer wie ich solch ein Beispiel nachprogrammieren soll!
http://www.youtube.com/watch?v=DrXIQfQH ... 1&index=15

Ich lasse mir die intrinische Matrix und den Distortion-Vektor, wie im Buchbeispiel erst einmal in einer Intitialisierungsphase berechnen. Danach suche ich in jeden Frame nach den Punkten des Schachbretts mittel cvFindChessboardCorners(). Bei den Objektpunkte, definiere ich die linke obere Ecke des Schachbretts als den Ursprung des Weltkoordinatensystems. Der nächste Punkte ist dann (1/0/0), der zweite (2/0/0) usw.
Wenn ich ein Weltkoordinatensystem definiert habe und die Punkte auf jedem Frame gefunden habe, dann kann ich mir von der Funktion cvFindExtrinsicCameraParams2(), den Translationsvektor und den Rotationsvektor berechnen lassen, der das Kamerkoordinatensystem auf das Weltkoordinatensystem legt.

Wie schon gesagt habe ich die Objektpunkte nur einmal definiert, suche aber in jedem Frame die Punkte des Schachbretts und rufe dann cvFindExtrinsicCameraParams2() auf.

Code: Alles auswählen

cvFindChessboardCorners(image, board_sz, corners, &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);

for(int j = 0; j < board_n; j++){
           CV_MAT_ELEM(*image_points, float,j,0) = corners2[j].x;
           CV_MAT_ELEM(*image_points, float,j,1) = corners2[j].y;
}
cvFindExtrinsicCameraParams2(object_points, image_points, intrinsic_matrix, distortion_coeffs, rotation, translation);
Der Rotationsvektor wird im Buch so definiert, dass er die Achse im 3D Raum angibt, um die rotiert wurde. Sein Betrag ist der jeweilige Winkel. Also mache ich folgendes:

Code: Alles auswählen

float theta = sqrt((CV_MAT_ELEM(*rotation, float, 0, 0)*CV_MAT_ELEM(*rotation, float, 0, 0))+
                              (CV_MAT_ELEM(*rotation, float, 1, 0)*CV_MAT_ELEM(*rotation, float, 1, 0))+
                              (CV_MAT_ELEM(*rotation, float, 2, 0)*CV_MAT_ELEM(*rotation, float, 2, 0)));

Chessboard->setRot(theta, CV_MAT_ELEM(*rotation, float, 0, 0), CV_MAT_ELEM(*rotation, float, 1, 0), CV_MAT_ELEM(*rotation, float, 2, 0));
Durch die Funktion setRot(), wird nichts anderes gemacht als glRotate() aufgerufen.
Das Problem ist nur, dass sich das Schachbrett einfach nicht bewegen möchte, es will nicht rotieren. Wenn ich den Wert von theta mit 10 multipliziere, dann dreht es sich total verrückt.
Ich stehe am Ende meines Lateins. Schon seit Wochen stöbere ich im Internet rum und lese Artikel für Artikel und es will nicht funktionieren. Es ist langsam echt ermüdend, wenn man einfach keine Erfolge sieht. :cry:
Dragontear
Beiträge: 5
Registriert: 07.06.2007, 13:38

Re: Kamera Kalibration

Beitrag von Dragontear »

Endlich ist es geschafft! Der Fehler lag ganz wo anders.

Mein Schachbrett enthält 48 Punkte, also habe ich 48 Koordinaten in R³, die mein Weltkoordinatensystem beschreiben, beginnend mit (0/0/0), (1/0/0) usw. (wie im letzten Post beschrieben). Pro Frame werden dann ebenfalls respektive 48 Punkte in R² gefunden. Diese Punkte habe ich meinen Funktionen wie oben beschrieben übergeben, damit sie mir die Translation und Rotation berechnen.
Das Problem lag darin, dass ich, als ich das Beispiel aus dem Buch kopiert habe, für die Matrixdeklaration Copy und Paste benutzt habe und die größe der beiden Matrizen bei 48*48 Punkten belassen habe, da ich noch nicht genau wusste wie das ganze Geschehen funktioniert. Nunja, dann haben die Funktionen versucht den Rotations- und Translationsvektor mit den 48 übergebenen Punkten zu berechnen, aber eben auch mit den restlichen 47*48 Nulleinträgen in der jeweiligen matrix. :roll:

Ich könnte mich schwarzärgern, dass es solch ein dummer Fehler war, aber das bringt ja nichts. Ich bin einfach nur froh, dass es funktioniert. :D

Hier habe ich noch ein Video davon hochgeladen:
http://www.youtube.com/watch?v=bV-jAnQ-tvw

Edit: Sorry für den Dreifachpost. Wenn ein Moderator möchte, kann er alle drei in einen packen. :)
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4260
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Kamera Kalibration

Beitrag von Chromanoid »

Ich finde das mit dem Dreifachpost gut. So sieht man wie du dich zur Lösung gekämpft hast - das motiviert andere dir gleich zu tun - gerade weil du deine Gedanken hier kontinuierlich niedergeschrieben hast.
Antworten