[PYTHON] Kamerakalibrierung

Ich fand heraus, dass die folgende Übersetzung auf der Website der Tottori University ist.

[Kamerakalibrierung und 3D-Wiederherstellung](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_calib3d/py_table_of_contents_calib3d/py_table_of_contents_calib3d.html of-content-calib)

Meine beschissene Übersetzung wird nicht mehr benötigt.


"OpenCV-Python Tutorials" in japanischer Übersetzung Camera Calibration Ich habe eine Übersetzung von gemacht. Originaltext in 3.1

Da es sich um eine schlechte Übersetzung handelt, kann es zu Fehlern bei der Übersetzung von Begriffen und der Interpretation von Sätzen kommen. Für ein solides Verständnis "Detaillierter offener Lebenslauf" Es wird dringend empfohlen zu lesen.

Das Originalwerk wurde inzwischen in einer mit OpenCV3 kompatiblen Version veröffentlicht. Learning OpenCV 3 Computer Vision in C++ with the OpenCV Library Ich würde mich freuen, wenn die japanische Übersetzung von

Korrektur: Ich habe die falsche Übersetzung für das kreisförmige Raster angegeben. Neu übersetzt als Kreisraster. (07.05.2016)


Kamerakalibrierung {#tutorial_py_calibration}

Goal

In diesem Abschnitt

Basics

Heutige billige Lochkameras weisen starke Verzerrungen auf. Die beiden Hauptverzerrungen Radiale Verzerrung und Umfangsverzerrung.

Die gerade Linie scheint aufgrund der radialen Verzerrung gebogen zu sein. Der Effekt nimmt zu, wenn Sie sich von der Bildmitte entfernen. Als Beispiel wird unten ein Bild gezeigt. Die beiden Kanten des Schachbretts sind durch die rote Linie dargestellt. Sie werden jedoch feststellen, dass die Grenzen keine geraden Linien sind und nicht mit den roten geraden Linien übereinstimmen. Alle erwarteten geraden Linien wölben sich nach außen. Einzelheiten finden Sie unter [Verzerrung] Bitte fragen Sie (https://ja.wikipedia.org/wiki/%E6%AD%AA%E6%9B%B2%E5%8F%8E%E5%B7%AE).

image

Diese Verzerrung wird ausgedrückt als:

歪みの式

In ähnlicher Weise ist die andere Verzerrung die Umfangsverzerrung, die bei Fotografien auftritt, die mit Linsen aufgenommen wurden, die nicht perfekt parallel zur Bildebene sind. Daher erscheinen einige Bereiche im Bild möglicherweise näher als erwartet. Die Verzerrung wird wie folgt ausgedrückt.

歪みの式2

Kurz gesagt, Sie müssen die folgenden fünf Parameter finden, die als Dehnungskoeffizienten bekannt sind:

distortionCoef.png

Anmerkung des Übersetzers: Die Korrekturformel bei zwei Verzerrungen ist in "Detailliertes OpenCV" S.399 beschrieben.

Außerdem müssen Sie einige Informationen finden. Interne und externe Parameter der Kamera. Interne Parameter sind für jede Kamera spezifisch. Es enthält Informationen wie Brennweite (\ f $ f_x, f_y \ f $) und optisches Zentrum (\ f $ c_x, c_y \ f $). Wird auch als Kameramatrix bezeichnet. Interne Parameter sind nur für die Kamera verfügbar. Sobald sie berechnet wurden, können sie für die zukünftige Verwendung gespeichert werden. Interne Parameter werden durch eine 3x3-Matrix dargestellt.

cameraMatrix.png

Externe Parameter entsprechen Rotations- und Bewegungsvektoren, die die Koordinaten eines 3D-Punkts auf ein anderes Koordinatensystem abbilden.

Bei Stereoanwendungen müssen diese Verzerrungen zuerst korrigiert werden. Alles, was Sie tun müssen, um all diese Parameter zu finden, ist, viele Beispielbilder eines genau definierten Musters (z. B. Schachbrett) bereitzustellen. Suchen Sie mehrere Feature-Punkte (quadratische Ecken des Schachbretts) darauf. Ich kenne die Koordinaten in diesen realen Räumen und ich kenne die Koordinaten im Bild. Mit diesen Daten wird hinter den Kulissen ein mathematisches Problem gelöst, um diesen Verzerrungskoeffizienten zu erhalten. Das ist eine Zusammenfassung des Gesamtbildes. Sie benötigen mindestens 10 Testmuster, um gute Ergebnisse zu erzielen.

Code

Wie oben erwähnt, sind mindestens 10 Testmuster für die Kamerakalibrierung erforderlich. OpenCV enthält mehrere Schachbrettbilder. (Siehe samples / cpp / left01.jpg --left14.jpg) Verwenden Sie es daher. Betrachten Sie zum besseren Verständnis nur ein Schachbrett. Die wichtigen Eingabedaten, die für die Kamerakalibrierung erforderlich sind, sind ein Satz von 3D-Realraumpunkten und entsprechenden 2D-Bildpunkten. Punkte auf dem 2D-Bild können leicht im Bild gefunden werden. (An diesen Bildpunkten berühren sich die beiden schwarzen Quadrate auf dem Schachbrett.)

Anmerkung des Übersetzers: $(opencv)\sources\samples\data Es ist left01.jpg --left14.jpg in.

Was ist mit 3D-Punkten aus dem realen Raum? Diese Bilder wurden von einer festen Kamera aufgenommen und die Schachbretter sind in verschiedenen Positionen und Ausrichtungen platziert. Sie müssen also wissen (X, Y, Z). Der Einfachheit halber befindet sich das Schachbrett jedoch in der XY-Ebene (dh immer Z = 0), und Sie können davon ausgehen, dass sich die Kamera bewegt. Mit dieser Überlegung müssen Sie nur die X- und Y-Werte finden. Bei den Werten von X und Y können Sie einfach mehrere Punkte in der Art von (0,0), (1,0), (2,0), ... übergeben. In diesem Fall erhalten wir den Wert auf der quadratischen Größe (30 mm) des Schachbretts. Sie können also Werte wie (0,0), (30,0), (60,0), ... übergeben und erhalten das Ergebnis in mm. (In diesem Beispiel nehmen wir diese Bilder nicht auf, daher kennen wir die Größe des Quadrats nicht und übergeben die Größe des Quadrats als Einheit.)

3D-Punkte werden als ** Objektpunkte ** und Punkte auf 2D-Bildern als ** Bildpunkte ** bezeichnet.

Setup

Um das Schachbrettmuster zu finden ** cv2.findChessboardCorners () ** Verwenden Sie die Funktion. Sie müssen übergeben, nach welcher Art von Muster Sie suchen, z. B. ein 8x8-Raster oder ein 5x5-Raster. In diesem Beispiel verwenden wir ein 7x6-Raster. (Normalerweise hat ein Schachbrett ein 8x8-Quadrat und 7x7-Innenecken.) Die Funktion gibt mehrere Eckpunkte und ein Retval zurück, das True zurückgibt, wenn ein Muster erkannt wird. Diese Ecken sind in der Reihenfolge von links nach rechts und von oben nach unten angeordnet.

@sa Diese Funktion kann möglicherweise nicht in allen Bildern das gewünschte Muster finden. In diesem Fall ist es eine gute Option, den Code zu schreiben, die Kamera zu aktivieren und jedes Bild das erforderliche Muster überprüfen zu lassen. Wenn Sie das Muster haben, suchen Sie nach der Ecke und speichern Sie sie in der Liste. Lassen Sie eine Lücke, bevor Sie das nächste Bild lesen. Dadurch kann das Schachbrett in einer anderen Ausrichtung eingestellt werden. Setzen Sie diesen Vorgang fort, bis Sie die erforderliche Anzahl guter Muster haben. Selbst im Beispiel hier sind wir uns nicht sicher, wie viele Blätter gut sind, wenn wir von den angegebenen 14 wegdenken. Daher werden alle Bilder gelesen und als gut behandelt.

@sa Anstelle eines Schachbretts können Sie ein kreisförmiges Gitter verwenden. Verwenden Sie in diesem Fall ** cv2.findCirclesGrid () **, um das Muster zu finden. Bei Verwendung eines Kreisgitters wird gesagt, dass eine kleine Anzahl ausreicht.

Sobald Sie eine Ecke gefunden haben, können Sie ** cv2.cornerSubPix () ** verwenden, um die Genauigkeit der Ecke zu verbessern. Sie können Muster mit ** cv2.drawChessboardCorners () ** zeichnen. Alle diese Schritte sind im folgenden Code enthalten.

python


import numpy as np
import cv2
import glob

# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)

# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.

images = glob.glob('*.jpg')

for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, (7,6),None)

    # If found, add object points, image points (after refining them)
    if ret == True:
        objpoints.append(objp)

        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        imgpoints.append(corners)

        # Draw and display the corners
        cv2.drawChessboardCorners(img, (7,6), corners2,ret)
        cv2.imshow('img',img)
        cv2.waitKey(500)

cv2.destroyAllWindows()

Das Folgende ist ein Bild mit dem darauf geschriebenen Muster.

image

Kalibrierung

Nachdem wir nun Objekt- und Bildpunkte haben, können wir kalibrieren. Verwenden Sie zur Kalibrierung ** cv2.calibrateCamera () **. Diese Funktion gibt die Kameramatrix, den Verzerrungsfaktor, die Rotations- und Translationsvektoren und mehr zurück.

python


ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)

Verzerrung

Ich fand heraus, dass ich es versuchte. Nehmen Sie nun ein Foto auf und korrigieren Sie die Verzerrung in diesem Foto. Es gibt zwei Methoden für OpenCV. Es ist unten gezeigt. Zuvor können Sie jedoch ** cv2.getOptimalNewCameraMatrix () ** verwenden, um die Kameramatrix basierend auf dem freien Skalierungsparameter zu verbessern. Wenn Sie den Parameter alpha = 0 skalieren, gibt die Funktion das verzerrungskorrigierte Bild so zurück, dass die nicht gewünschten Pixel minimiert werden. Daher möchten Sie möglicherweise einige Pixel in den Ecken des Bildes entfernen. Wenn Alpha = 1 ist, bleiben alle Pixel erhalten und der Teil ohne die Originaldaten wird zu einem schwarzen Bild. Die Funktion gibt auch den ROI des Bildes zurück und kann zum Zuschneiden des Ergebnisses verwendet werden.

Nehmen wir nun ein neues Bild (wir verwenden hier left12.jpg, das erste Bild in diesem Kapitel).

python


img = cv2.imread('left12.jpg')
h,  w = img.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))

Anmerkung des Übersetzers: left12.jpg kann unter der folgenden URL abgerufen werden. Https://github.com/rajatsaxena/OpenCV

1. Verwenden Sie ** cv2.undistort () **

Dies ist eine schnelle Prozedur. Rufen Sie die Funktion auf und schneiden Sie das Ergebnis mit dem oben angegebenen ROI aus.

python


# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)

2. Verwendung der Neuzuordnung

Dies ist ein Kreisverkehr. Suchen Sie zunächst die Zuordnungsfunktion vom verzerrten Bild zum verzerrten korrigierten Bild. Verwenden Sie dann diese Remap-Funktion.

python


# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)

# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)

Beide Methoden ergeben das gleiche Ergebnis. Siehe die Ergebnisse unten.

image

Im resultierenden Bild sehen Sie, dass alle Kanten gerade sind. Jetzt können Sie die Kameramatrix und den Verzerrungskoeffizienten für die spätere Verwendung mit den Schreibfunktionen von Numpy (np.savez, np.savetxt usw.) speichern.

Neuprojektionsfehler

Ein Reprojektionsfehler ist ein guter Weg, um zu bewerten, wie genau die gefundenen Parameter sind. Es ist wünschenswert, dass der Wert so nahe wie möglich bei 0 liegt. Verwenden Sie bei gegebenen internen Parametern, Verzerrung, Drehung und parallelem Verlauf zunächst ** cv2.projectPoints () **, um Objektpunkte in Bildpunkte zu konvertieren. Dann wird die Norm der Differenz zwischen dem Konvertierungsergebnis und dem Eckenerkennungsalgorithmus (Ergebnis) berechnet. Um den Durchschnittsfehler zu erhalten, berechnen Sie den arithmetischen Durchschnitt des Fehlers für alle kalibrierten Bilder.

python


mean_error = 0
for i in xrange(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
    tot_error += error

print "total error: ", mean_error/len(objpoints)

Additional Resources

Nachtrag des Übersetzers "Kamerakalibrierung unter Verwendung eines Polynommodells hoher Ordnung eines Ultraweitwinkelobjektivs mit geringer Verzerrung" http://www.roboken.esys.tsukuba.ac.jp/~ohya/pdf/Robomech2014-KNS.pdf

Exercises

-# Try camera calibration with circular grid.


** Beilage durch Übersetzer **

Ergänzung zur "Kamerakalibrierung" von OpenCV-Python-Tutorials Ich habe einen separaten Artikel als gemacht.

Liste der Beispielquellen für OpenCV 2.4.0 (Beispiele / cpp)

https://github.com/YusukeSuzuki/opencv_sample_list_jp/blob/master/samples_cpp.rst Es ist auch nützlich, Beispielprogramme zu lesen, die sich auf Stereo in C ++ beziehen.

Tsai-Modell

Tsai Camera Calibration http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/DIAS1/ pyTsai - automated camera calibration in Python https://github.com/Csega/pyTsai/blob/master/doc/index.rst

Recommended Posts

Kamerakalibrierung
Kamerakalibrierung visuell verstehen
Verwenden Sie die Kamerakalibrierungsdatei mit OpenCvSharp4
Erstellen Sie ein Schachbrettmuster für die Kamerakalibrierung
Kamerakalibrierung und Verwendung mit opencv-python [chang method]
WEB Kameraaufnahme
Ergänzung zur "Kamerakalibrierung" von OpenCV-Python-Tutorials
[Windows] [Python] Kamerakalibrierung des Fischaugenobjektivs mit OpenCV