Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
http://m.c-plusplus.net

  
C++ Forum :: C++ (alle ISO-Standards) ::  Kamerakalibrierung in OpenCV     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Abix
Unregistrierter




Beitrag Abix Unregistrierter 17:40:48 15.09.2010   Titel:   Kamerakalibrierung in OpenCV            Zitieren

Hallo,

momentan sitze ich an der Kamerakalibrierung in OpenCV und möchte das Beispiel in diesem Video nachprogrammieren:
http://www.youtube.com/wa ....... p;playnext=1&index=15

Soweit ich das mit der Kamerakalibrierung verstanden habe, wird eine intrinsiche Matrix berechnet, die die Kamera beschreibt. Diese Matrix enthält die Brennweite der Kamera für x- und y- Richtung, sowie die Offsets, die die optische Achse auf das Zentrum der Projektionsebene, den Imager, bringen.
Hinzu gesellt sich eine extrinsische Matrix, die eine Rotation und Translation des Kamerakoordinatensystems beschreibt, so dass diese auf dem Weltkoordinatensystem liegt. Damit die Berechnung möglich wird, hält man ein planares Objekt in die Kamera, wie z.b. ein Schachbrett. Die einzelnen Ecken werden gefunden und diesen ordnet der Benutzer dann bestimmte Koordinatenwerte im Weltkoordinatensystem zu. So legt das Schachbrett also das Weltkoordinatensystem fest.
Bei der Mathematik hinter diesem ganzen Geschehen werden grob gesagt die homogenen Weltkoordinaten in homogene Kamerakoordinaten überführt, die dann wiederum auf die gefundenen Punkte im Imager überführt werden, also dem Frame von der Kamera. Da man die Werte der Weltkoordinaten und die Punkte auf dem Imager schon kennt, können alle anderen Unbekannten, wir Rotationswinkel, Brennweite etc. bei genug Informationen (dies wären die gefundenen Punkte des Schachbretts in jedem Frame) berechnet werden.

Das erstmal vorweg, damit etwaige Verständnisfehler des Ganzen ersichtlich werden.
Bei meinem Beispiel lege ich für die linke obere Ecke des Schachbretts den Ursprung des Weltkoordinatensystems fest. Der nächste Punkt liegt dann bei (1/0/0), der zweite dann bei (2/0/0) usw. In einer Initialisierungsphase berechne ich die instrinsiche Matrix. Diesen Codeabschnitt habe ich aus dem Buchbeispiel und gehe davon aus, dass dieses auch richtig ist.

Danach nehme ich mir in einer Schleife jeden Frame und suche dort die Koordinaten des Schachbretts und speichere diese in einer Matrix, die ich dann dazu verwende, um die extrinsischen Werte zu berechnen:
Code:
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);


In der Dokumentation steht, dass der Rotationsvektor eine Achse im 3D-Raum darstellt, um die das Objekt gedreht wurde. Sein Betrag ist der Rotationswinkel gegen den Uhrzeigersinn. Also mache ich nun folgendes:

Code:
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));


Der Mehtodenaufruf meines Schachbretts ruft nichts anderes als die OpenGL-Funktion glRotatef() auf, die den übergebenen Vektor automatisch normiert, wenn es dieser nicht schon ist.
Diese Operationen mache ich Frame für Frame.

Das Problem aber nun ist, dass sich rein gar nicht tut! Das Schachbrett will im 3D-Fenster nicht rotieren. Ich habe einfach keine Ahnung warum. :confused:
Abix
Unregistrierter




Beitrag Abix Unregistrierter 21:46:33 15.09.2010   Titel:              Zitieren

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 Doppelpost. Wenn ein Moderator möchte, kann er alle zwei in einen packen. :)
Cool!
Unregistrierter




Beitrag Cool! Unregistrierter 22:12:47 15.09.2010   Titel:              Zitieren

Sehr beeindruckend!
Senna
Unregistrierter




Beitrag Senna Unregistrierter 17:02:57 07.12.2010   Titel:   ViewPoint Änderung            Zitieren

Hey,

ich hab mal ne Frage zu dem Fenster in dem du das Schachbrett im Raum anzeigst. Und zwar änderst du während deines Videos mal die ViewDirection. Wie machst du das? bzw, wie berechnest du dann die neue perspektive?

Im Endeffekt ist das doch nur eine Rot und trans der Kamera oder? nur woher weiß ich denn die korrekten Daten dieser in der 3d Welt?

Grüße
Senna
C++ Forum :: C++ (alle ISO-Standards) ::  Kamerakalibrierung in OpenCV   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.