KlassenKlassenKlassenKlassen | | | | Operatoren

camera_calibrationT_camera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration (Operator)

Name

camera_calibrationT_camera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration — Bestimmen aller Kameraparameter durch simultane Ausgleichsrechnung.

Signatur

camera_calibration( : : NX, NY, NZ, NRow, NCol, StartCamParam, NStartPose, EstimateParams : CameraParam, NFinalPose, Errors)

Herror T_camera_calibration(const Htuple NX, const Htuple NY, const Htuple NZ, const Htuple NRow, const Htuple NCol, const Htuple StartCamParam, const Htuple NStartPose, const Htuple EstimateParams, Htuple* CameraParam, Htuple* NFinalPose, Htuple* Errors)

Herror camera_calibration(const HTuple& NX, const HTuple& NY, const HTuple& NZ, const HTuple& NRow, const HTuple& NCol, const HTuple& StartCamParam, const HTuple& NStartPose, const HTuple& EstimateParams, HTuple* CameraParam, HTuple* NFinalPose, HTuple* Errors)

void CameraCalibration(const HTuple& NX, const HTuple& NY, const HTuple& NZ, const HTuple& NRow, const HTuple& NCol, const HTuple& StartCamParam, const HTuple& NStartPose, const HTuple& EstimateParams, HTuple* CameraParam, HTuple* NFinalPose, HTuple* Errors)

static HTuple HPose::CameraCalibration(const HTuple& NX, const HTuple& NY, const HTuple& NZ, const HTuple& NRow, const HTuple& NCol, const HTuple& StartCamParam, const HPoseArray& NStartPose, const HTuple& EstimateParams, HPoseArray* NFinalPose, HTuple* Errors)

HTuple HPose::CameraCalibration(const HTuple& NX, const HTuple& NY, const HTuple& NZ, const HTuple& NRow, const HTuple& NCol, const HTuple& StartCamParam, const HString& EstimateParams, HPose* NFinalPose, double* Errors) const

HTuple HPose::CameraCalibration(const HTuple& NX, const HTuple& NY, const HTuple& NZ, const HTuple& NRow, const HTuple& NCol, const HTuple& StartCamParam, const char* EstimateParams, HPose* NFinalPose, double* Errors) const

void HOperatorSetX.CameraCalibration(
[in] VARIANT NX, [in] VARIANT NY, [in] VARIANT NZ, [in] VARIANT NRow, [in] VARIANT NCol, [in] VARIANT StartCamParam, [in] VARIANT NStartPose, [in] VARIANT EstimateParams, [out] VARIANT* CameraParam, [out] VARIANT* NFinalPose, [out] VARIANT* Errors)

VARIANT HPoseX.CameraCalibration(
[in] VARIANT NX, [in] VARIANT NY, [in] VARIANT NZ, [in] VARIANT NRow, [in] VARIANT NCol, [in] VARIANT StartCamParam, [in] VARIANT NStartPose, [in] VARIANT EstimateParams, [out] VARIANT* NFinalPose, [out] VARIANT* Errors)

static void HOperatorSet.CameraCalibration(HTuple NX, HTuple NY, HTuple NZ, HTuple NRow, HTuple NCol, HTuple startCamParam, HTuple NStartPose, HTuple estimateParams, out HTuple cameraParam, out HTuple NFinalPose, out HTuple errors)

static HTuple HPose.CameraCalibration(HTuple NX, HTuple NY, HTuple NZ, HTuple NRow, HTuple NCol, HTuple startCamParam, HPose[] NStartPose, HTuple estimateParams, out HPose[] NFinalPose, out HTuple errors)

HTuple HPose.CameraCalibration(HTuple NX, HTuple NY, HTuple NZ, HTuple NRow, HTuple NCol, HTuple startCamParam, string estimateParams, out HPose NFinalPose, out double errors)

Beschreibung

camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration führt die eigentliche Kalibrierung der Kamera durch. Dazu werden die bekannten 3D-Modellpunkte (mit Koordinaten NXNXNXNXNXNX, NYNYNYNYNYNY, NZNZNZNZNZNZ) ins Bild projiziert und die Summe der Abstandsquadrate zwischen den so gewonnenen Projektionen und ihren korrespondierenden Bildpunkten (mit Koordinaten NRowNRowNRowNRowNRowNRow, NColNColNColNColNColNCol) minimiert.

Konvergiert dieses Bündelausgleichsverfahren, so sind damit die exakten internen (CameraParamCameraParamCameraParamCameraParamCameraParamcameraParam) und externen (NFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPose) Kameraparameter der Kamera bestimmt worden. Als Startwerte für das Ausgleichsverfahren dienen die Parameter StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam und NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose. Da mit Hilfe dieses Operators Bild-Modell-Korrespondenzen simultan abgeglichen werden können, die aus unterschiedlichen Bildern stammen, wird dieses Verfahren auch als Multibildkalibrierung bezeichnet.

Ganz allgemein bedeutet Kamerakalibrierung, diejenigen Parameter exakt zu bestimmen, die die (optische) Abbildung eines beliebigen 3D-Weltpunktes p(w) im Raum auf ein (Sub-)Pixel [r,c] im Bild modellieren. Dies ist insbesondere von Bedeutung, wenn aus dem Kamerabild die ursprüngliche räumliche Lage von irgendwelchen Gegenständen im Bild bestimmt werden soll, beispielsweise bei der Vermessung von Werkstücken.

Zu Grunde liegendes 3D-Kameramodell

Die Abbildung besteht aus mehreren Schritten: Zuerst wird der Punkt p(w) vom Welt- in das Kamerakoordinatensystem transformiert (Punkte in Form von homogenen Vektoren, vgl. affine_trans_point_3daffine_trans_point_3dAffineTransPoint3daffine_trans_point_3dAffineTransPoint3dAffineTransPoint3d):

  /      \     / x \     /        \   /      \
  | p(c) |  =  | y |  =  |  R   t | * | p(w) |
  |      |     | z |     |        |   |      |
  \  1   /     \ 1 /     \ 0 0  1 /   \  1   /

Dann wird der Punkt in die Bildebene, d.h. auf den Sensor-Chip projiziert.

Für die Modellierung dieses Abbildungsvorganges, der durch die Kombination von Kamera, Objektiv und Framegrabber festgelegt ist, stellt HALCON die folgenden drei 3D-Kameramodelle zur Verfügung:

Lochkamera mit Flächensensor:

Die Kombination einer Kamera mit Flächensensor mit einem zentralperspektivisch abbildenden Objektiv, das radiale und tangentiale Verzeichnung aufweisen kann.

Telezentrische Kamera mit Flächensensor:

Die Kombination einer Kamera mit Flächensensor mit einem telezentrischen, also parallel abbildenden Objektiv, das radiale und tangentiale Verzeichnung aufweisen kann.

Lochkamera mit Zeilensensor:

Die Kombination einer Kamera mit Zeilensensor mit einem zentralperspektivisch abbildenden Objektiv, das radiale Verzeichnung aufweisen kann.

Für Kameras mit Flächensensor besteht der Abbildungsvorgang des in Kamerakoordinaten gegebenen Punktes p(c) auf ein (Sub-)Pixel [r,c] im Bild aus den folgenden Schritten: Zuerst wird der Punkt in die Bildebene, d.h. auf den Sensor-Chip projiziert. Falls als Kameramodell das einer Lochkamera mit Flächensensor verwendet wird, d.h. falls die Brennweite in CameraParamCameraParamCameraParamCameraParamCameraParamcameraParam mit einem Wert größer als 0 übergeben wurde, wird die Projektion mit den folgenden Gleichungen beschrieben:

           / x \
    p(c) = | y |
           \ z /

    u = Focus * x / z
    v = Focus * y / z

Falls die Brennweite in CameraParamCameraParamCameraParamCameraParamCameraParamcameraParam als 0 übergeben wird, wird als Kameramodell eine telezentrische Kamera mit Flächensensor verwendet, d.h. es wird angenommen, dass die Optik des Kameraobjektives eine Parallelprojektion der Weltpunkte durchführt. Die entsprechenden Gleichungen sind dann:

           / x \
    p(c) = | y |
           \ z /

    u = x
    v = y

Für beide Kameraarten mit Flächensensor kann die Verzeichnung entweder mit dem Divisionsmodell oder mit dem Polynommodell modelliert werden. Das Divisionsmodell verwendet einen Parameter (Kappa), um die radiale Verzeichnung zu modellieren.

Die folgenden Gleichungen werden verwendet, um mit Hilfe des Divisionsmodells die in der Bildebene gegebenen verzeichneten Koordinaten in Koordinaten ohne Verzeichnungen zu transformieren:

   u = u' / (1+Kappa*(u'^2+v'^2)
   v = v' / (1+Kappa*(u'^2+v'^2)

Diese Gleichungen lassen sich analytisch invertieren. Dies führt zu den folgenden Gleichungen, die dazu verwendet werden, mit Hilfe des Divisionsmodells an Koordinaten ohne Verzeichnungen die Verzeichnung anzubringen:

   u' = (2*u) / (1+sqrt(1-4*Kappa*(u^2+v^2)))
   v' = (2*v) / (1+sqrt(1-4*Kappa*(u^2+v^2)))

Das Polynommodell verwendet drei Parameter (K1, K2, K3), um die radiale Verzeichnung zu modellieren und zwei Parameter (P1, P2), um die tangentiale Verzeichnung zu modellieren. Die folgenden Gleichungen werden verwendet, um mit Hilfe des Polynommodells die in der Bildebene gegebenen verzeichneten Koordinaten in Koordinaten ohne Verzeichnungen zu transformieren:

   u = u' + u'*(K1*r^2 + K2*r^4 + K3*r^6) +
            2*P1*u'*v' + P2*(r^2 + 2*u'^2)

   v = v' + v'*(K1*r^2 + K2*r^4 + K3*r^6) +
            P1*(r^2 + 2*v'^2) + 2*P2*u'*v'

   with: r = sqrt(u'^2+v'^2)

Diese Gleichungen sind nicht analytisch invertierbar. Daher müssen die verzeichneten Koordinaten numerisch aus den Koordinaten ohne Verzeichnungen bestimmt werden.

Welches der beiden Verzeichnungsmodelle verwendet wird, hängt von der Anzahl der Werte ab, die im Parameter StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam übergeben werden: Wenn StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam 8 Werte enthält, wird das Divisionsmodell verwendet. Wenn StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam 12 Werte enthält, wird das Polynommodell verwendet.

Zum Schluss wird der Punkt vom Koordinatensystem der Bildebene ins Pixelkoordinatensystem transformiert:

    c = u' / Sx + Cx
    r = v' / Sy + Cy

Für Kameras mit Zeilensensor muss auch die Relativbewegung zwischen Kamera und Objekt modelliert werden. In HALCON werden hierzu die folgenden Annahmen getroffen:

  1. Die Kamera bewegt sich mit konstanter Geschwindigkeit entlang einer Geraden.

  2. Die Orientierung der Kamera ist konstant.

  3. Die Relativbewegung ist für alle Bilder gleich.

Diese Bewegung wird durch den Bewegungsvektor V = (Vx,Vy,Vz) beschrieben. Dieser Vektor muss in der Einheit [Meter/Bildzeile] im Kamerakoordinatensystem gegeben sein. Er beschreibt die Bewegung der Kamera in Bezug auf ein unbewegtes Objekt. Dies ist äquivalent zu der Annahme einer unbewegten Kamera und einem Objekt, das sich entlang -V bewegt.

Das Kamerakoordinatensystem ist für Kameras mit Zeilensensor folgendermaßen definiert. Der Ursprung liegt im Projektionszentrum. Die z-Achse ist mit der optischen Achse identisch und ist so orientiert, dass alle Punkte, die von der Kamera aus sichtbar sind, positive z-Koordinaten haben. Die y-Achse ist senkrecht zur Sensorzeile und zur z-Achse. Sie ist so orientiert, dass der Bewegungsvektor eine positive y-Komponente hat. Die x-Achse ist senkrecht zur y- und z-Achse. Sie ist so orientiert, dass x-, y- und z-Achse ein rechtshändiges Koordinatensystem bilden.

Da sich die Kamera während der Bildaufnahme über das Objekt bewegt, bewegt sich auch das Kamerakoordinatensystem relativ zum Objekt. Das bedeutet, dass jede Bildzeile von einer anderen Position aus aufgenommen wird, dass es also prinzipiell für jede Bildzeile eine eigene Pose gibt. Zur Vereinfachung beziehen sich in HALCON alle Transformationen zwischen Weltkoordinaten und Kamerakoordinaten auf die Pose der ersten Bildzeile. Die Bewegung V wird bei der Projektion des Punktes p(c) in das Bild berücksichtigt. Infolgedessen wird von den Operatoren find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose und camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration auch nur die Pose der ersten Bildzeile zurückgegeben.

Für Lochkameras mit Zeilensensor ist die Abbildung des Punktes p(c), der im Kamerakoordinatensystem der ersten Bildzeile gegeben ist, auf ein (Sub-)Pixel [r,c] im Bild folgendermaßen definiert:

Mit

           / x \
    p(c) = | y |,
           \ z /

muss das folgende Gleichungssystem nach m, u' und t aufgelöst werden:

    m * D * u' = x - t * Vx
   -m * D * pv = y - t * Vy
    m * Focus  = z - t * Vz

mit

                   1
    D  = -----------------------
         1 + Kappa*(u'*u' + pv*pv)

    pv = Sy*Cy

Dies beinhaltet bereits die Kompensation der radialen Verzeichnung. Für Lochkameras mit Zeilensensor ist nur das Divisionsmodell verfügbar.

Zum Schluss wird der Punkt ins Pixelkoordinatensystem transformiert:

    c = u' / Sx + Cx
    r = t

Kameraparameter

Innerhalb der insgesamt 14 bzw. 18 Kameraparameter für Kameras mit Flächensensor (abhängig von dem verwendeten Verzeichnungsmodell) bzw. der 17 Kameraparameter für Kameras mit Zeilensensor unterscheidet man zwischen internen und externen Kameraparametern:

Interne Kameraparameter:

Sie beschreiben die Beschaffenheit der verwendeten Kamera und beschreiben somit vor allem die interne Sensorgröße und die Abbildungseigenschaften der verwendeten Kombination von Objektiv, Kamera und Framegrabber.

Für Kameras mit Flächensensor sind das gemäß dem oben beschriebenen Kameramodell die folgenden Parameter (8 Parameter wenn die Verzeichnung mit dem Divisionsmodell modelliert wird und 12 Parameter wenn das Polynommodell verwendet wird):

Focus:

Brennweite des Objektivs. 0 für telezentrische Objektive. newline Entweder:

Kappa (K):

Verzeichnungskoeffizient zur Modellierung der radialen Verzeichnung mit dem Divisionsmodell (wegzulassen, wenn das Polynommodell verwendet wird). newline Oder:

K1, K2, K3, P1, P2:

Verzeichnungskoeffizienten zur Modellierung der radialen und tangentialen Verzeichnung mit dem Polynommodell (wegzulassen, wenn das Divisionsmodell verwendet wird).

Sx:

Skalierungsfaktor. Entspricht bei Lochkameras dem horizontalen Abstand zweier benachbarter Zellen auf dem Sensor und bei telezentrischen Kameras der horizontalen Pixelgröße in Weltkoordinaten. Vorsicht: Bei Unterabtastung des Bildes erhöht sich dieser Wert!

Sy:

Skalierungsfaktor. Entspricht bei Lochkameras dem vertikalen Abstand zweier benachbarter Zellen auf dem Sensor und bei telezentrischen Kameras der vertikalen Pixelgröße in Weltkoordinaten. Da in der Regel das Bildsignal zeilensynchron ausgelesen wird, ist dieser Wert durch die Größe des Sensors exakt festgelegt und muss daher bei Lochkameras nicht durch die Kalibrierung bestimmt werden. Vorsicht: Bei Unterabtastung des Bildes erhöht sich dieser Wert!

Cx:

Spaltenkoordinate des Kamerahauptpunktes (optisches Zentrum der radialen Verzeichnung).

Cy:

Zeilenkoordinate des Kamerahauptpunktes (optisches Zentrum der radialen Verzeichnung).

ImageWidth:

Breite des abgetasteten Bildes. Vorsicht: Bei Unterabtastung des Bildes erniedrigt sich dieser Wert!

ImageHeight:

Höhe des abgetasteten Bildes. Vorsicht: Bei Unterabtastung des Bildes erniedrigt sich dieser Wert!

Für Kameras mit Zeilensensor sind das gemäß dem oben beschriebenen Kameramodell die folgenden 11 Parameter:

Focus:

Brennweite des Objektivs.

Kappa:

Verzeichnungskoeffizient zur Modellierung der radialen Verzeichnung mit dem Divisionsmodell.

Sx:

Skalierungsfaktor, entspricht dem horizontalen Abstand zweier benachbarter Zellen auf der Sensorzeile. Vorsicht: Bei Unterabtastung des Bildes erhöht sich dieser Wert!

Sy:

Skalierungsfaktor, der im Rahmen der Kalibrierung nur in der Form pv = Sy*Cy auftritt. pv beschreibt den Abstand des Kamerahauptpunktes von der Sensorzeile in der Einheit [Meter]. Vorsicht: Bei Unterabtastung des Bildes erhöht sich der Wert von Sy!

Cx:

Spaltenkoordinate des Kamerahauptpunktes (optisches Zentrum der radialen Verzeichnung).

Cy:

Abstand des Kamerahauptpunktes (optisches Zentrum der radialen Verzeichnung) von der Sensorzeile in der Einheit [Bildzeilen].

ImageWidth:

Breite des abgetasteten Bildes. Vorsicht: Bei Unterabtastung des Bildes erniedrigt sich dieser Wert!

ImageHeight:

Höhe des abgetasteten Bildes. Vorsicht: Bei Unterabtastung des Bildes erniedrigt sich dieser Wert!

Vx:

X-Komponente des Bewegungsvektors.

Vy:

Y-Komponente des Bewegungsvektors.

Vz:

Z-Komponente des Bewegungsvektors.

Bitte beachten Sie, dass die Bezeichnung Focus im Allgemeinen nicht der realen Brennweite entspricht, wenn die Objektweite nicht unendlich ist. Der Einfachheit halber wird hier aber nicht zwischen Brennweite und Bildweite unterschieden.

Bitte beachten Sie, dass für alle Operatoren, die Kameraparameter als Eingabe verwenden, die Werte der Kameraparameter geprüft werden, ob sie die folgenden Restriktionen erfüllen:

      Sx          >  0
      Sy          >= 0
      Focus       >= 0
      ImageWidth  >  0
      ImageHeight >  0
      

Für manche Operatoren gibt es kleine Unterschiede in den Restriktionen. Im Speziellen für Operatoren, die Kameras mit telezentrischem Objektiv nicht unterstützen gilt folgende Restriktion:

      Focus > 0
     

Für Operatoren, die Lochkameras mit Zeilensensor nicht unterstützen, gelten folgende Restriktionen:

     Sy             >  0
     Vx^2+Vy^2+Vz^2 != 0
     

externe Kameraparameter:

Diese 6 Parameter beschreiben die 3D-Lage (Pose) des Welt- relativ zum Kamerakoordinatensystems. Bei Kameras mit Zeilensensor bezieht sich die Pose des Weltkoordinatensystems auf das Kamerakoordinatensystem der ersten Bildzeile. Drei Parameter beschreiben die Position, drei die Orientierung (siehe create_posecreate_poseCreatePosecreate_poseCreatePoseCreatePose für mehr Informationen). camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration verarbeitet alle verschieden Darstellungstypen für NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose.

Bei Benutzung der Standard-Kalibrierplatte definiert deren Koordinatensystem das Weltkoordinatensystem. Es ist im Mittelpunkt der Kalibrierkörperoberfläche platziert, die z-Achse zeigt in den Kalibrierkörper hinein, die x-Achse nach rechts und die y-Achse nach unten.

Zusätzliche Information über die Kalibrierung

Die folgenden Abschnitte befassen sich jeweils mit einzelnen Fragen, die sich bei der Verwendung von camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration stellen und sollen daher sowohl dem Verständnis als auch als Leitfaden für die eigene Anwendung dienen.

Wie erzeuge ich einen geeigneten Kalibrierkörper?

Die wohl einfachste Methode, die internen Kameraparameter einer Kamera zu ermitteln, ist die Verwendung der Standard-Kalibrierplatte, wie ihn der Operator gen_caltabgen_caltabGenCaltabgen_caltabGenCaltabGenCaltab erzeugt. Hochgenaue Kalibrierkörper können Sie in verschiedenen Größen und Materialien über Ihren lokalen HALCON-Vertrieb erhalten. Für den Nahbereich der Kamera genügt es vielleicht sogar, diesen Kalibrierkörper auf einem DIN A4 Laserdrucker auszugeben und auf einen festen Pappkarton aufzuziehen. Für den Fernbereich -- insbesondere bei der Verwendung eines Weitwinkelobjektivs -- wird so ein Kalibrierkörper zu klein sein. Hier bietet es sich an, die PostScript-Datei auf einem großformatigen Tintenstrahldrucker ausgeben und anschließend z.B. auf Aluminium aufziehen zu lassen. Wichtig ist dabei vor allem, dass die Koordinaten der Marken in der Kalibrierkörperbeschreibungsdatei so genau wie möglich mit dem wirklichen Kalibrierkörper übereinstimmen. Daher sollte unbedingt der gedruckte Kalibrierkörper nachgemessen und die Kalibrierkörperbeschreibungsdatei entsprechend modifiziert werden!

Wie nehme ich eine Menge von geeigneten Bildern auf?

Ist eine Standard-Kalibrierplatte vorhanden, so kann folgendermaßen vorgegangen werden: Mit der zu kalibrierenden Kombination aus Objektiv (mit definierter Entfernungseinstellung), Kamera und Framegrabber wird der Kalibrierkörper aufgenommen, vgl. open_framegrabberopen_framegrabberOpenFramegrabberopen_framegrabberOpenFramegrabberOpenFramegrabber bzw. grab_imagegrab_imageGrabImagegrab_imageGrabImageGrabImage. Dabei sollte folgendes berücksichtigt werden:

Wie extrahiere ich die Kalibrierkörpermarken aus den Bildern?

Im Falle der Verwendung der Standard-Kalibrierplatte können mit Hilfe der Operatoren find_caltabfind_caltabFindCaltabfind_caltabFindCaltabFindCaltab und find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose für jedes einzelne aufgenommene Bild die Koordinaten der Kalibrierkörpermarkenmittelpunkte sowie eine grobe Schätzung der externen Kameraparameter bestimmt werden. Die Konkatenation dieser Werte kann dann direkt als Startwert für die externen Kameraparameter (NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose) für camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration verwendet werden.

Diejenigen Bilder, auf denen die Suche nach dem Kalibrierkörper (find_caltabfind_caltabFindCaltabfind_caltabFindCaltabFindCaltab) gescheitert ist bzw. für die der Operator find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose nicht die Markenpunkte detektieren konnte, sollten natürlich nicht in die Eingabeparameter von camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration eingehen.

Welches Verzeichnungsmodell soll ich verwenden?

Für Kameras mit Flächensensor stehen zwei unterschiedliche Verzeichnungsmodelle zur Verfügung: das Divisionsmodell und das Polynommodell. Das Divisionsmodell verwendet einen Parameter, um die radiale Verzeichnung zu modellieren, während das Polynommodell fünf Parameter verwendet, um die radiale Verzeichnung und die tangentiale Verzeichnung zu modellieren (siehe oben).

Der Vorteil des Divisionsmodells ist, dass die Korrektur der Verzeichnung schneller ist, insbesondere, wenn Weltkoordinaten in ein verzeichnetes Bild projiziert werden und die Verzeichnung somit in der umgekehrten Richtung angebracht werden muss. Desweiteren liefert das Divisionsmodell typischerweise stabilere Ergebnisse, wenn nur wenige Kalibrierbilder verwendet werden oder das Sichtfeld nicht ausreichend durch Kalibrierkörper abgedeckt ist. Der Hauptvorteil des Polynommodells ist, dass es die Verzeichnung genauer modellieren kann, weil einerseits Terme höherer Ordnung zur Modellierung der radialen Verzeichnung verwendet werden und andererseits auch die tangentiale Verzeichnung modelliert wird.

Normalerweise sollte das Divisionsmodell für die Kalibrierung verwendet werden. Reicht die Genauigkeit der Kalibrierung nicht aus, kann das Polynommodell verwendet werden. Hierbei ist dann aber darauf zu achten, dass durch die Folge von Kalibrierbildern das gesamte Gebiet abgedeckt werden muss, in dem später gemessen werden soll. Die Verzeichnungskorrektur kann außerhalb des Gebietes, das durch Kalibrierkörper abgedeckt ist, fehlerhaft sein. Dies gilt sowohl für die Bildränder als auch für Bereiche innerhalb des Bildes, die nicht durch einen Kalibrierkörper abgedeckt sind.

Woher nehme ich geeignete Startwerte für die internen Kameraparameter?

Der Operator find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose zur Ermittlung von Startwerten für die externen Kameraparameter (NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose) sowie der Operator camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration benötigen Startwerte für die internen Kameraparameter. Diese können in einem geeigneten Format als Datei zur Verfügung stehen (siehe read_cam_parread_cam_parReadCamParread_cam_parReadCamParReadCamPar). Eine solche Datei kann entweder durch den Operator write_cam_parwrite_cam_parWriteCamParwrite_cam_parWriteCamParWriteCamPar erzeugt oder auch per Hand editiert werden.

Bei Kameras mit Flächensensor gilt für die Startwerte der einzelnen Parameter folgendes:

Focus:

Startwert ist gleich der nominalen Brennweite des verwendeten Objektivs, also beispielsweise 0.008,m. newline Entweder:

Kappa:

Als Startwert den Wert 0.0 verwenden (wegzulassen, wenn das Polynommodell verwendet wird). newline Oder: Als Startwert für jeden der fünf Parameter 0.0 verwenden (wegzulassen, wenn das Divisionsmodell verwendet wird).

Sx:

Der Startwert für den horizontalen Abstand zweier benachbarter Zellen hängt von der Größe des Chips in der Kamera ab (vgl. technische Daten der Kamera). Man unterscheidet dabei zwischen 1/3"-Chips (z.B. SONY XC-73, SONY XC-777), 1/2"-Chips (z.B. SONY XC-999, Panasonic WV-CD50) und 2/3"-Chips (z.B. SONY DXC-151, SONY XC-77). Hinweise: Bei Unterabtastung des Bildes erhöht sich der Wert für Sx entsprechend! Geeignete Startwerte sind z.B.: begin(verbatim) Vollbild (768*576) Unterabtastung (384*288) 1/3"-Chip 0.0000055 m 0.0000110 m 1/2"-Chip 0.0000086 m 0.0000172 m 2/3"-Chip 0.0000110 m 0.0000220 m end(verbatim) Der Wert für Sx wird kalibriert, da das Videosignal einer Kamera in der Regel nicht pixelsynchron abgetastet wird.

Sy:

Da die handelsüblichen Kameras annähernd quadratische Pixel haben, gelten für Sy dieselben Werte wie für Sx. Der Wert für Sy wird normalerweisefür Lochkameras NICHT kalibriert, da das Videosignal einer Kamera in der Regel zeilensynchron abgetastet wird und somit der Startwert gleich dem gesuchten endgültigen Wert entspricht. Geeignete Startwerte sind: begin(verbatim) Vollbild (768*576) Unterabtastung (384*288) 1/3"-Chip 0.0000055 m 0.0000110 m 1/2"-Chip 0.0000086 m 0.0000172 m 2/3"-Chip 0.0000110 m 0.0000220 m end(verbatim)

Cx und Cy:

Startwerte für die Koordinaten des Kamerahauptpunktes sind die halbe Bildbreite bzw. -höhe. Hinweis: Bei Unterabtastung des Bildes verringern sich die Werte entsprechend! Geeignete Startwerte sind: begin(verbatim) Vollbild (768*576) Unterabtastung (384*288) Cx 384.0 192.0 Cy 288.0 144.0 end(verbatim)

ImageWidth und ImageHeight:

Diese beiden Parameter werden durch die Framegrabberanbindung gesetzt und werden daher natürlich nicht kalibriert. Geeignete Startwerte sind: begin(verbatim) Vollbild (768*576) Unterabtastung (384*288) ImageWidth 768 384 ImageHeight 576 288 end(verbatim)

Bei Kameras mit Zeilensensor gilt für die Startwerte der einzelnen Parameter folgendes:

Focus:

Startwert ist gleich der nominalen Brennweite des verwendeten Objektivs, also beispielsweise 0.008,m.

Kappa:

Als Startwert den Wert 0.0 verwenden.

Sx:

Der Startwert für den Abstand zweier benachbarter Zellen kann den technischen Daten der Kamera entnommen werden. Typische Startwerte sind 7e-6 m, 10e-6 m und 14e-6 m. Hinweise: Bei Unterabtastung des Bildes erhöht sich der Wert für Sx entsprechend!

Sy:

Der Startwert für die Größe einer Zelle senkrecht zur Richtung der Sensorzeile kann ebenfalls den technischen Daten der Kamera entnommen werden. Typische Startwerte sind 7e-6 m, 10e-6 m und 14e-6 m. Der Wert für Sy wird für Zeilenkameras NICHT kalibriert, da er ausschließlich in der Form pv = Sy*Cy auftritt und daher nicht getrennt von Cy bestimmt werden kann.

Cx:

Der Startwert für die x-Koordinate des Kamerahauptpunktes ist die halbe Bildbreite, d.h. die halbe Anzahl von Pixeln des Zeilensensors. Hinweis: Bei Unterabtastung des Bildes verringern sich der Wert für Cx entsprechend! Geeignete Startwerte sind: begin(verbatim) Bildbreite: 1024 2048 4096 8192 Cx: 512 1024 2048 4096 end(verbatim)

Cy:

Der Startwert für die y-Koordinate des Kamerahauptpunktes ist normalerweise 0.

ImageWidth und ImageHeight:

Diese beiden Parameter werden durch die Framegrabberanbindung gesetzt und werden daher nicht kalibriert.

Vx, Vy, Vz:

Die Startwerte für die x-, y- und z-Komponente des Bewegungsvektors hängen vom Aufbau des gesamten Aufnahmesystems ab. Blickt die Kamera beispielsweise senkrecht auf ein Fließband, und ist dabei so um ihre optische Achse gedreht, dass die Sensorzeile senkrecht zur Bewegungsrichtung des Fließbandes steht, dass also die y-Achse des Kamerakoordinatensystems parallel zur Bewegungsrichtung des Fließbandes ausgerichtet ist, so sind die Startwerte Vx = Vz = 0. Der Startwert für Vy lässt sich dann aus der Aufnahme eines Objektes dessen Größe bekannt ist (z.B. Kalibrierplatte, Lineal) folgendermaßen bestimmen:

Vy = LM / LR Mit:LM = Länge des Objektes in Bewegungsrichung in Objektkoordinaten [Meter] LR = Länge des Objektes in Bewegungsrichtung in Bildkoordinaten (Bildzeilen]

Wird die Kamera gegenüber diesem Aufbau z.B. um 30 Grad um die optische Achse, also die z-Achse des Kamerakoordinatensystems gedreht, so sind die oben bestimmten Startwerte folgendermaßen zu verändern:

                   Vx_rot_z & = & sin(30) * Vy
                   Vy_rot_z & = & cos(30) * Vy
                   Vz_rot_z & = & Vz = 0
                 

Wenn die Kamera gegenüber dem ursprünglichen Aufbau z.B. um -20 Grad um die x-Achse des Kamerakoordinatensystems gedreht wird, so ergeben sich folgende Startwerte:

                   Vx_rot_x & = & Vx = 0
                   Vy_rot_x & = & cos(20) * Vy
                   Vz_rot_x & = & sin(20) * Vy
                 

Die Qualität der Startwerte für Vx, Vy und Vz ist entscheidend für den Erfolg der gesamten Kalibrierung. Werden zu schlechte Startwerte verwendet, kann dies zum Abbruch der Kamerakalibrierung führen.

Welche der Kameraparameter werden geschätzt?

Mit dem Eingabeparameter EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams kann man angeben, welche der gesuchten Kameraparameter geschätzt werden sollen. Üblicherweise ist dieser Wert gleich 'all'"all""all""all""all""all", d.h. alle 6 externen Kameraparameter (Translation und Rotation) und alle internen Kameraparameter werden bestimmt. Falls die internen Parameter schon bestimmt worden sind (z.B. durch einen früheren Aufruf von camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration), ist es oftmals interessant, lediglich die 3D-Lage (Pose) des Weltkoordinatensystems in Kamerakoordinaten zu bestimmen. In diesem Fall kann in EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams der Wert 'pose'"pose""pose""pose""pose""pose" übergeben werden. Dies hat denselben Effekt wie EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams = ['alpha','beta','gamma','transx','transy','transz']["alpha","beta","gamma","transx","transy","transz"]["alpha","beta","gamma","transx","transy","transz"]["alpha","beta","gamma","transx","transy","transz"]["alpha","beta","gamma","transx","transy","transz"]["alpha","beta","gamma","transx","transy","transz"]. Andernfalls enthält EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams ein Tupel von Strings, die die Kombination von Parametern, die geschätzt werden soll, enthält. Es ist auch möglich, Parameter die nicht geschätzt werden sollen über ein vorgesetztes '~' Zeichen im String auszuschießen. Die Werte ['pose','~transx']["pose","~transx"]["pose","~transx"]["pose","~transx"]["pose","~transx"]["pose","~transx"] beispielsweise haben denselben Effekt wie ['alpha','beta','gamma','transy','transz']["alpha","beta","gamma","transy","transz"]["alpha","beta","gamma","transy","transz"]["alpha","beta","gamma","transy","transz"]["alpha","beta","gamma","transy","transz"]["alpha","beta","gamma","transy","transz"]. ['all','~focus']["all","~focus"]["all","~focus"]["all","~focus"]["all","~focus"]["all","~focus"] zum Beispiel schätzt alle internen und externen Parameter bis auf die Brennweite. Das '~' Präfix kann mit Ausnahme von 'all' jedem Parameterwert vorangestellt werden.

Wie sieht die Reihenfolge der einzelnen Parameter aus?

Die Länge des Tupels NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose korrespondiert mit der Anzahl der Kalibrierungsbilder, d.h. werden beispielsweise 15 Aufnahmen eines Kalibrierkörpers verwendet, so ergibt sich die Länge des Tupels NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose zu 15*7=105 (15 mal je 7 externe Kameraparameter). Die ersten 7 Werte entsprechen daher der Lage des Kalibrierkörpers im 1. Bild, die nächsten 7 derjenigen im 2. Bildes usw.

Die dadurch festgelegte Anzahl Kalibrierungsbilder muss auch bei den Tupeln mit den Koordinaten der 3D-Modellmarkenpunkte bzw. der extrahierten 2D-Markenpunkte berücksichtigt werden. Bei einer Anzahl von 15 Kalibrierungsbildern müssen daher die Tupel NRowNRowNRowNRowNRowNRow und NColNColNColNColNColNCol 15-mal so viele Werte aufweisen wie die Tupel mit den 3D-Modellmarkenpunkten (NXNXNXNXNXNX, NYNYNYNYNYNY und NZNZNZNZNZNZ). Sind beispielsweise 49 Markenpunkte pro Bild vorhanden, so haben die Tupel NXNXNXNXNXNX, NYNYNYNYNYNY und NZNZNZNZNZNZ jeweils die Länge 15*49=735, die Tupel NRowNRowNRowNRowNRowNRow und NColNColNColNColNColNCol haben dagegen die Länge 49. Die Reihenfolge der Werte in NRowNRowNRowNRowNRowNRow und NColNColNColNColNColNCol erfolgt dabei bildweise, d.h. bei 49 Marken korrespondiert der erste 3D-Modellpunkt mit dem 1., 50., 99., 148., 197., 246. etc. extrahierten 2D-Markenpunkt.

Die 3D-Modellpunkte können mit dem Operator caltab_pointscaltab_pointsCaltabPointscaltab_pointsCaltabPointsCaltabPoints aus einer Kalibrierkörperbeschreibungsdatei gelesen werden. Startwerte für die Lagen des Kalibrierkörpers können für jedes betrachtete Bild mit dem Operator find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose ermittelt werden. Das Tupel NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose ergibt sich dann als Konkatenation dieser einzelnen Kameralagen.

Was bedeuten die Ausgabeparameter?

Falls die Kamerakalibrierung erfolgreich verlaufen ist, d.h. das Bündelausgleichsverfahren konvergiert ist, sind in den Ausgabeparametern CameraParamCameraParamCameraParamCameraParamCameraParamcameraParam und NFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPose die auf diese Weise ermittelten genauen Werte für die internen und externen Kameraparameter enthalten. Die Länge des Tupels NFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPose entspricht dann derjenigen von NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose.

Die Darstellungstypen von NFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPose entsprechen dem Darstellungstyp der des ersten Tupels aus NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose (siehe create_posecreate_poseCreatePosecreate_poseCreatePoseCreatePose). Der Darstellungstyp kann jedoch mit convert_pose_typeconvert_pose_typeConvertPoseTypeconvert_pose_typeConvertPoseTypeConvertPoseType gewandelt werden.

Anhand des durchschnittlichen Fehlers (ErrorsErrorsErrorsErrorsErrorserrors) kann die erzielte Genauigkeit der Kalibrierung abgeschätzt werden. Der Fehler (Root-Mean-Square-Fehler der Position) wird in Pixel angegeben.

Muss man einen planaren Kalibrierkörper verwenden?

Nein. Der Operator camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration ist so ausgelegt, dass er mit den Eingabetupeln NXNXNXNXNXNX, NYNYNYNYNYNY, NZNZNZNZNZNZ, NRowNRowNRowNRowNRowNRow und NColNColNColNColNColNCol beliebige 3D/2D-Korrespondenzen erhält, vgl. obigen Abschnitt über die Länge von NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose.

Es ist daher prinzipiell egal, wie man auf die nötigen 3D-Modellmarkenpunkte und die korrespondierenden extrahierten 2D-Markenpunkte ermittelt hat. Somit ist es einerseits möglich, auch einen 3D-Kalibrierkörper zu verwenden. Andererseits kann man auch beliebige markante Punkte (natürliche Landmarken) verwenden, deren Position in der Welt bekannt sind. Falls man dann EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams auf 'pose'"pose""pose""pose""pose""pose" setzt, kann man diese Weise mit camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration die Lage eines beliebigen Objektes in Kamerakoordinaten ermitteln! Hierzu sind dann mindestens drei 3D/2D-Korrespondenzen als Eingabe anzugeben. NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose kann z.B. direkt über create_posecreate_poseCreatePosecreate_poseCreatePoseCreatePose generiert werden, vgl. auch Programmbeispiel dort.

Achtung

Die Ausgleichsrechnung der Kalibrierung hängt von den Startwerten für die internen (StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam) und externen (NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose) Kameraparameter ab. Anhand der zurückgegebenen durchschnittlichen Fehler (ErrorsErrorsErrorsErrorsErrorserrors) kann die Genauigkeit der Kalibrierung abgeschätzt werden. Die Fehler (Abweichungen in x- und y-Koordinate) werden in Pixel angegeben.

Bei der Kalibrierung von Kameras mit Zeilensensor ist es möglich, als Startwert für den internen Kameraparameter Sy den Wert 0.0 zu verwenden. In diesem Fall ist es allerdings nicht möglich, die Position des Bildhauptpunktes in y-Richtung zu bestimmen. Daher muss EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams den Term '~cy'"~cy""~cy""~cy""~cy""~cy" enthalten. Der effektive Abstand des Bildhauptpunktes von der Sensorzeile ist dann immer pv = Sy*Cy = 0.0.

Parallelisierung

Parameter

NXNXNXNXNXNX (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen x-Koordinaten der Kalibriermarken (in Meter).

NYNYNYNYNYNY (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen y-Koordinaten der Kalibriermarken (in Meter).

NZNZNZNZNZNZ (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen z-Koordinaten der Kalibriermarken (in Meter).

NRowNRowNRowNRowNRowNRow (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen Zeilen-Koordinaten der extrahierten Kalibriermarken (in Pixel).

NColNColNColNColNColNCol (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen Spalten-Koordinaten der extrahierten Kalibriermarken (in Pixel).

StartCamParamStartCamParamStartCamParamStartCamParamStartCamParamstartCamParam (input_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Startwerte für die internen Kameraparameter.

Parameteranzahl: StartCamParam == 8 || StartCamParam == 11 || StartCamParam == 12

NStartPoseNStartPoseNStartPoseNStartPoseNStartPoseNStartPose (input_control)  pose(-array) HPose, HTupleHTupleHTupleHPoseX, VARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen Startwerten der externen Kameraparameter.

EstimateParamsEstimateParamsEstimateParamsEstimateParamsEstimateParamsestimateParams (input_control)  string(-array) HTupleHTupleHTupleVARIANTHtuple (string) (string) (HString) (char*) (BSTR) (char*)

Zu schätzenden Kameraparameter.

Defaultwert: 'all' "all" "all" "all" "all" "all"

Werteliste: 'all'"all""all""all""all""all", 'alpha'"alpha""alpha""alpha""alpha""alpha", 'beta'"beta""beta""beta""beta""beta", 'camera'"camera""camera""camera""camera""camera", 'cx'"cx""cx""cx""cx""cx", 'cy'"cy""cy""cy""cy""cy", 'focus'"focus""focus""focus""focus""focus", 'gamma'"gamma""gamma""gamma""gamma""gamma", 'kappa'"kappa""kappa""kappa""kappa""kappa", 'poly'"poly""poly""poly""poly""poly", 'poly_rad_2'"poly_rad_2""poly_rad_2""poly_rad_2""poly_rad_2""poly_rad_2", 'poly_rad_4'"poly_rad_4""poly_rad_4""poly_rad_4""poly_rad_4""poly_rad_4", 'poly_rad_6'"poly_rad_6""poly_rad_6""poly_rad_6""poly_rad_6""poly_rad_6", 'poly_tan_2'"poly_tan_2""poly_tan_2""poly_tan_2""poly_tan_2""poly_tan_2", 'pose'"pose""pose""pose""pose""pose", 'sx'"sx""sx""sx""sx""sx", 'sy'"sy""sy""sy""sy""sy", 'transx'"transx""transx""transx""transx""transx", 'transy'"transy""transy""transy""transy""transy", 'transz'"transz""transz""transz""transz""transz", 'vx'"vx""vx""vx""vx""vx", 'vy'"vy""vy""vy""vy""vy", 'vz'"vz""vz""vz""vz""vz"

CameraParamCameraParamCameraParamCameraParamCameraParamcameraParam (output_control)  number-array HTupleHTupleHTupleVARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Interne Kameraparameter.

NFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPoseNFinalPose (output_control)  pose(-array) HPose, HTupleHTupleHTupleHPoseX, VARIANTHtuple (real / integer) (double / int / long) (double / Hlong) (double / Hlong) (double / Hlong) (double / Hlong)

Geordnetes Tupel mit allen externen Kameraparametern.

ErrorsErrorsErrorsErrorsErrorserrors (output_control)  real(-array) HTupleHTupleHTupleVARIANTHtuple (real) (double) (double) (double) (double) (double)

Durchschnittlicher Fehler in Pixel.

Beispiel (HDevelop)

*  read calibration images
read_image(Image1, 'calib-01')
read_image(Image2, 'calib-02')
read_image(Image3, 'calib-03')
*  find calibration pattern
find_caltab(Image1, Caltab1, 'caltab.descr', 3, 112, 5)
find_caltab(Image2, Caltab2, 'caltab.descr', 3, 112, 5)
find_caltab(Image3, Caltab3, 'caltab.descr', 3, 112, 5)
*  find calibration marks and start poses
find_marks_and_pose(Image1, Caltab1, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord1, CCoord1, \
                    StartPose1)
find_marks_and_pose(Image2, Caltab2, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord2, CCoord2, \
                    StartPose2)
find_marks_and_pose(Image3, Caltab3, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord3, CCoord3, \
                    StartPose3)
*  read 3D positions of calibration marks
caltab_points('caltab.descr', NX, NY, NZ)
*  camera calibration
camera_calibration(NX, NY, NZ, [RCoord1, RCoord2, RCoord3], \
                   [CCoord1, CCoord2, CCoord3], \
                   [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                   [StartPose1, StartPose2, StartPose3], 'all', \
                   CameraParam, NFinalPose, Errors)
*  write internal camera parameters to file
write_cam_par(CameraParam, 'campar.dat')

Beispiel (HDevelop)

*  read calibration images
read_image(Image1, 'calib-01')
read_image(Image2, 'calib-02')
read_image(Image3, 'calib-03')
*  find calibration pattern
find_caltab(Image1, Caltab1, 'caltab.descr', 3, 112, 5)
find_caltab(Image2, Caltab2, 'caltab.descr', 3, 112, 5)
find_caltab(Image3, Caltab3, 'caltab.descr', 3, 112, 5)
*  find calibration marks and start poses
find_marks_and_pose(Image1, Caltab1, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord1, CCoord1, \
                    StartPose1)
find_marks_and_pose(Image2, Caltab2, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord2, CCoord2, \
                    StartPose2)
find_marks_and_pose(Image3, Caltab3, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord3, CCoord3, \
                    StartPose3)
*  read 3D positions of calibration marks
caltab_points('caltab.descr', NX, NY, NZ)
*  camera calibration
camera_calibration(NX, NY, NZ, [RCoord1, RCoord2, RCoord3], \
                   [CCoord1, CCoord2, CCoord3], \
                   [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                   [StartPose1, StartPose2, StartPose3], 'all', \
                   CameraParam, NFinalPose, Errors)
*  write internal camera parameters to file
write_cam_par(CameraParam, 'campar.dat')

Beispiel (HDevelop)

*  read calibration images
read_image(Image1, 'calib-01')
read_image(Image2, 'calib-02')
read_image(Image3, 'calib-03')
*  find calibration pattern
find_caltab(Image1, Caltab1, 'caltab.descr', 3, 112, 5)
find_caltab(Image2, Caltab2, 'caltab.descr', 3, 112, 5)
find_caltab(Image3, Caltab3, 'caltab.descr', 3, 112, 5)
*  find calibration marks and start poses
find_marks_and_pose(Image1, Caltab1, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord1, CCoord1, \
                    StartPose1)
find_marks_and_pose(Image2, Caltab2, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord2, CCoord2, \
                    StartPose2)
find_marks_and_pose(Image3, Caltab3, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord3, CCoord3, \
                    StartPose3)
*  read 3D positions of calibration marks
caltab_points('caltab.descr', NX, NY, NZ)
*  camera calibration
camera_calibration(NX, NY, NZ, [RCoord1, RCoord2, RCoord3], \
                   [CCoord1, CCoord2, CCoord3], \
                   [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                   [StartPose1, StartPose2, StartPose3], 'all', \
                   CameraParam, NFinalPose, Errors)
*  write internal camera parameters to file
write_cam_par(CameraParam, 'campar.dat')

Beispiel (C++ (HALCON 5.0-10.0))

HTuple StartCamPar, NX, NY, NZ;
HTuple RCoord1, CCoord1, StartPose1;
HTuple RCoord2, CCoord2, StartPose2;
HTuple RCoord3, CCoord3, StartPose3;
HTuple StartPoses, RCoords, CCoords;
HTuple CameraParam, NFinalPose, Errors;
// read calibration images
HImage Image1("calib-01");
HImage Image2("calib-02");
HImage Image3("calib-03");
// find calibration pattern
HRegion Caltab1 = Image1.FindCaltab("caltab.descr", 3, 112, 5);
HRegion Caltab2 = Image2.FindCaltab("caltab.descr", 3, 112, 5);
HRegion Caltab3 = Image3.FindCaltab("caltab.descr", 3, 112, 5);
// find calibration marks and start poses
StartCamPar[7] = 576;          // ImageHeight
StartCamPar[6] = 768;          // ImageWidth
StartCamPar[5] = 288;          // Cy
StartCamPar[4] = 384;          // Cx
StartCamPar[3] = 0.000011;     // Sy
StartCamPar[2] = 0.000011;     // Sx
StartCamPar[1] = 0.0;          // Kappa
StartCamPar[0] = 0.008;        // Focus
RCoord1 = Image1.FindMarksAndPose(Caltab1, "caltab.descr", StartCamPar,
                                  128, 10, &CCoord1, &StartPose1);
RCoord2 = Image2.FindMarksAndPose(Caltab2, "caltab.descr", StartCamPar,
                                  128, 10, &CCoord2, &StartPose2);
RCoord3 = Image3.FindMarksAndPose(Caltab3, "caltab.descr", StartCamPar,
                                  128, 10, &CCoord3, &StartPose3);
// read 3D positions of calibration marks
caltab_points("caltab.descr", &NX, &NY, &NZ);
// camera calibration
StartPoses = (StartPose1.Append(StartPose2)).Append(StartPose3);
RCoords = (RCoord1.Append(RCoord2)).Append(RCoord3);
CCoords = (CCoord1.Append(CCoord2)).Append(CCoord3);
camera_calibration(NX, NY, NZ, RCoords, CCoords, StartCamPar, StartPoses,
                   "all", &CameraParam, &NFinalPose, &Errors);
// write internal camera parameters to file
write_cam_par(CameraParam, "campar.dat");

Beispiel (HDevelop)

*  read calibration images
read_image(Image1, 'calib-01')
read_image(Image2, 'calib-02')
read_image(Image3, 'calib-03')
*  find calibration pattern
find_caltab(Image1, Caltab1, 'caltab.descr', 3, 112, 5)
find_caltab(Image2, Caltab2, 'caltab.descr', 3, 112, 5)
find_caltab(Image3, Caltab3, 'caltab.descr', 3, 112, 5)
*  find calibration marks and start poses
find_marks_and_pose(Image1, Caltab1, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord1, CCoord1, \
                    StartPose1)
find_marks_and_pose(Image2, Caltab2, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord2, CCoord2, \
                    StartPose2)
find_marks_and_pose(Image3, Caltab3, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord3, CCoord3, \
                    StartPose3)
*  read 3D positions of calibration marks
caltab_points('caltab.descr', NX, NY, NZ)
*  camera calibration
camera_calibration(NX, NY, NZ, [RCoord1, RCoord2, RCoord3], \
                   [CCoord1, CCoord2, CCoord3], \
                   [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                   [StartPose1, StartPose2, StartPose3], 'all', \
                   CameraParam, NFinalPose, Errors)
*  write internal camera parameters to file
write_cam_par(CameraParam, 'campar.dat')

Beispiel (HDevelop)

*  read calibration images
read_image(Image1, 'calib-01')
read_image(Image2, 'calib-02')
read_image(Image3, 'calib-03')
*  find calibration pattern
find_caltab(Image1, Caltab1, 'caltab.descr', 3, 112, 5)
find_caltab(Image2, Caltab2, 'caltab.descr', 3, 112, 5)
find_caltab(Image3, Caltab3, 'caltab.descr', 3, 112, 5)
*  find calibration marks and start poses
find_marks_and_pose(Image1, Caltab1, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord1, CCoord1, \
                    StartPose1)
find_marks_and_pose(Image2, Caltab2, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord2, CCoord2, \
                    StartPose2)
find_marks_and_pose(Image3, Caltab3, 'caltab.descr', \
                    [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                    128, 10, 18, 0.9, 15.0, 100.0, RCoord3, CCoord3, \
                    StartPose3)
*  read 3D positions of calibration marks
caltab_points('caltab.descr', NX, NY, NZ)
*  camera calibration
camera_calibration(NX, NY, NZ, [RCoord1, RCoord2, RCoord3], \
                   [CCoord1, CCoord2, CCoord3], \
                   [0.008, 0.0, 0.000011, 0.000011, 384, 288, 768, 576], \
                   [StartPose1, StartPose2, StartPose3], 'all', \
                   CameraParam, NFinalPose, Errors)
*  write internal camera parameters to file
write_cam_par(CameraParam, 'campar.dat')

Ergebnis

Sind die Parameterwerte korrekt und konnten die gesuchten Kameraparameter durch das Bündelausgleichsverfahren bestimmt werden, dann liefert camera_calibrationcamera_calibrationCameraCalibrationcamera_calibrationCameraCalibrationCameraCalibration den Wert 2 (H_MSG_TRUE). Gegebenenfalls wird eine Fehlerbehandlung durchgeführt

Vorgänger

find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose, caltab_pointscaltab_pointsCaltabPointscaltab_pointsCaltabPointsCaltabPoints, read_cam_parread_cam_parReadCamParread_cam_parReadCamParReadCamPar

Nachfolger

write_posewrite_poseWritePosewrite_poseWritePoseWritePose, pose_to_hom_mat3dpose_to_hom_mat3dPoseToHomMat3dpose_to_hom_mat3dPoseToHomMat3dPoseToHomMat3d, disp_caltabdisp_caltabDispCaltabdisp_caltabDispCaltabDispCaltab, sim_caltabsim_caltabSimCaltabsim_caltabSimCaltabSimCaltab

Alternativen

calibrate_camerascalibrate_camerasCalibrateCamerascalibrate_camerasCalibrateCamerasCalibrateCameras

Siehe auch

find_caltabfind_caltabFindCaltabfind_caltabFindCaltabFindCaltab, find_marks_and_posefind_marks_and_poseFindMarksAndPosefind_marks_and_poseFindMarksAndPoseFindMarksAndPose, disp_caltabdisp_caltabDispCaltabdisp_caltabDispCaltabDispCaltab, sim_caltabsim_caltabSimCaltabsim_caltabSimCaltabSimCaltab, write_cam_parwrite_cam_parWriteCamParwrite_cam_parWriteCamParWriteCamPar, read_cam_parread_cam_parReadCamParread_cam_parReadCamParReadCamPar, create_posecreate_poseCreatePosecreate_poseCreatePoseCreatePose, convert_pose_typeconvert_pose_typeConvertPoseTypeconvert_pose_typeConvertPoseTypeConvertPoseType, write_posewrite_poseWritePosewrite_poseWritePoseWritePose, read_poseread_poseReadPoseread_poseReadPoseReadPose, pose_to_hom_mat3dpose_to_hom_mat3dPoseToHomMat3dpose_to_hom_mat3dPoseToHomMat3dPoseToHomMat3d, hom_mat3d_to_posehom_mat3d_to_poseHomMat3dToPosehom_mat3d_to_poseHomMat3dToPoseHomMat3dToPose, caltab_pointscaltab_pointsCaltabPointscaltab_pointsCaltabPointsCaltabPoints, gen_caltabgen_caltabGenCaltabgen_caltabGenCaltabGenCaltab, calibrate_camerascalibrate_camerasCalibrateCamerascalibrate_camerasCalibrateCamerasCalibrateCameras

Modul

Calibration


KlassenKlassenKlassenKlassen | | | | Operatoren