1. OpenCV-Monokularkamera-Kalibrierungsprozess
- Bestimmen Sie anhand der Größe der Kalibrierplatte die Koordinaten der Kalibrierplatte in der realen Welt
- Machen Sie Fotos von der Kalibrierungstafel aus verschiedenen Blickwinkeln
- Verwenden Sie findChessboardCorners von opencv, um die Eckkoordinaten jeder Kalibrierungstafel zu berechnen
- Verwenden Sie die Schnittstelle „CalibrateCamera“ von opencv, um die Kameraparameter entsprechend den 3D-Koordinaten und Pixelkoordinaten der Eckpunkte zu kalibrieren
2. Definieren Sie die Koordinaten der Kalibrierplatte in der realen Welt
Es gibt zwei Möglichkeiten, auf die Kalibrierungstafel zu schießen:
- Befestigen Sie die Kamera und bewegen Sie die Kalibrierungsplatte, um Aufnahmen aus verschiedenen Winkeln zu ermöglichen
- Befestigen Sie die Kalibrierungstafel, bewegen Sie die Kamera und fotografieren Sie die Kalibrierungstafel aus verschiedenen Winkeln
Hier nehmen wir an, die zweite Methode zu verwenden, die Kalibrierungstafel zu fixieren, das Weltkoordinatensystem zu fixieren, einen beliebigen Eckpunkt auf der Kalibrierungstafel als Ursprung des Weltkoordinatensystems auszuwählen, die x- und y-Achsen liegen entlang der Ebene der Kalibrierungstafel , und die z-Achse steht senkrecht zur Ebene der Kalibrierplatte. Da sich die Kalibrierplatte immer auf der xy-Ebene befindet, ist z=0 für alle Punkte auf der Ebene der Kalibrierplatte.
Als nächstes müssen Sie die Kalibrierungstafel aus verschiedenen Winkeln aufnehmen. Beim Fotografieren der Kalibrierungstafel müssen Sie Folgendes beachten:
- Der Abstand zwischen der Kalibrierplatte und der Kamera sollte sicherstellen, dass mindestens 20 % der Bildebene von der Kalibrierplatte abgedeckt werden
- Machen Sie mindestens 10–20 Bilder
- Versuchen Sie, unkomprimierte Bildformate wie PNG zu verwenden, um in einem Durchgang eine höhere Präzision zu erzielen
- Schießen Sie die Kalibrierungsplatte relativ zur Kamera in verschiedene Richtungen, und der Ablenkungswinkel der Kalibrierungsplatte relativ zur Kameraebene sollte möglichst weniger als 45° betragen
- Verändern Sie das Bild nicht, indem Sie das aufgenommene Bild beispielsweise nicht zuschneiden
- Verwenden Sie während des Aufnahmevorgangs nicht die Methode des Autofokus und ändern Sie während des Aufnahmevorgangs nicht die Brennweite
- Das aufgenommene Kalibrierungsplattenmuster nimmt so viel wie möglich des Rahmens ein, und die Linsenverzerrung nimmt radial mit dem Abstand von der Mitte zu, was nicht über den gesamten Rahmen hinweg gleichmäßig ist. Um die Linsenverzerrung zu erfassen, muss das Muster den Rand abdecken das aufgenommene Bild.
3. Kalibrierungslösung
- Finden Sie zunächst die 2D-Koordinaten der Kalibrierungstafel. Die entsprechende API lautet:
retval, Corners = cv2.findChessboardCorners(image, patternSize, flags)
Bild: Ein einzelnes Schachbrett-Kalibrierungsbild, muss ein 8-Bit-Graustufen- oder Farbbild sein
PatternSize: Schachbrettgitterspalte, die Anzahl der inneren Eckpunkte pro Zeile (points_per_row, points_per_column)
Ecken: Gibt das erkannte Eckarray aus
Flags: Definiert die Art und Weise, Ecken zu finden
cv2.cornerSubPix(Bild, Ecken, Winsize, ZeroZone, Kriterien)
Bild: Ein einzelnes Schachbrett-Kalibrierungsbild, muss ein 8-Bit-Graustufen- oder Farbbild sein
Ecken: Geben Sie die Anfangskoordinaten der Eckpunkte ein
winSize: halbe Länge des Suchfensters
Kriterien: Abbruchkriterien für Iterationen der Eckpunktoptimierung. Eines ist die maximale Anzahl von Iterationen der Eckpunktoptimierung cv2.TERM_CRITERIA_MAX_ITER und das andere ist, dass die Bewegungsverschiebung der Eckpunkte kleiner als cv2.TERM_CRITERIA_EPS ist
- Im zweiten Schritt der Kamerakalibrierung lautet die entsprechende API:
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2. CalibrateCamera(objectPoints, imagePoints,imageSize)
objectPoints: ein Vektor aus dreidimensionalen Eckpunkten
imagePoints: ein Vektor von 2D-Punktkoordinaten
ImageSize: Bildauflösung
cameraMatrix: Kamerainterne Parametermatrix
distCoefs: Verzerrungsparameter
rvecs: Rotationsmatrix
tvecs: Übersetzungsmatrix
retval: RMS-Neuprojektionsfehler
4. Verzerrungskorrektur
Nach der Kalibrierung kann eine Bildverzerrungskorrektur durchgeführt werden, einschließlich der folgenden API:
newCameraMatrix, validPixROI = cv2. getOptimalNewCameraMatrix(cameraMatrix,distCoeffs, imageSize, alpha[, newImgSize[, centerPrinciplePoint]])
cameraMatrix: interne Referenz der Kamera
distCoeffs: Eingabevektor der Verzerrungsparameter
imageSzie: Die Auflösung des Originalbildes
Alpha: Steuert die Pixelbeibehaltungsmethode der Verzerrungskorrektur. Alpha = 0 zeigt an, dass alle Pixel des korrigierten Bildes gültig sind. Alpha = 1: Das korrigierte Bild behält alle Pixel des Originalbilds bei
newCameraMatrix: Basierend auf freien Skalierungsparametern, optimierten kamerainternen Parametern
validPixROI: Der gültige Pixelbereich des korrigierten Bildes
dist = cv2.undist(src, cameraMatrix, disCoeffs[, newCameraMatrix]), diese Funktion entspricht der Überlagerung der folgenden beiden Funktionen.
src: das zu korrigierende Originalbild
cameraMatrix: interne Referenz der Kamera
distCoeffs: Vektor der Verzerrungsparameter
dst: Ausgabebild nach Verzerrungskorrektur
newCameraMatrix: Die interne Kamerareferenz, die dem zu korrigierenden Bild entspricht
map1, map2 = cv2.initUndistortRectifymap(cameraMatrix, distCoeffs, R, newCameraMatrix, size,m1type)
cameraMatrix: interne Referenz der Kamera
distCoeffs: Verzerrungsparameter
R: optional, 3*3 gleichgerichtete Transformationsmatrix
newcameraMatrix: neue kamerainterne Parameter, im Allgemeinen gleich der cameraMatrix im Monokular
Größe: korrigierte Bildgröße
map1: die erste Mapping-Matrix, mapx(x,y)
Map2: die erste Mapping-Matrix, Mapy(x,y)
dst = cv .remap(src, map1,map2, interpolation[,dst[,borderMode[,borderValue]]])
src: Originalbild
dst: das zugeordnete Bild, das dieselbe Größe und denselben Datentyp wie src hat
Karte1: Die erste Zuordnungsmatrix, die x-Koordinate von src entspricht dst (x, y).
Map2: Die zweite Mapping-Matrix, die Y-Koordinate von src entspricht dst (x, y)
Interpolation: Interpolationsmethode, lineare Interpolation usw.
borderMode: Die Verarbeitungsmethode des Randwerts
borderValue: borderMode ist die tägliche Aufladung, wenn der feste Wert gefüllt ist, der Standardwert ist 0