[PYTHON] Verwenden Sie die Kamerakalibrierungsdatei mit OpenCvSharp4

Einführung

Guten Abend Ich habe die WEB-Kamera mit OpenCvSharp4 kalibriert, daher werde ich sie als Memorandum belassen. Ich verstehe die Theorie und die Argumentation der Kalibrierung selbst immer noch nicht, daher hat der Code einfach funktioniert. .. ..

Umgebung

WEB-Kamera: FullHD 1080P (2-Millionen-Pixel-Kamera) Erstellung der Kalibrierungsdatei: Python (Python-OpenCV) Berechnung der Kameraobjektivverzerrung: C # (opencvsharp4.windows)

Erstellen einer Kamera-Kalibrierungs-Yaml-Datei mit Python

Ich wollte unbedingt eine Kalibrierungsberechnung mit Opencvsharp durchführen Es ist schwierig, die 3er-Samples umzuleiten, und es war unwahrscheinlich, dass ich mit den 4er-Samples auf meinem Niveau konkurrieren konnte, daher werde ich ruhig mit Python mit Samples rechnen.

Erstellen Sie den folgenden Code und führen Sie ihn aus, indem Sie auf [hier] verweisen (https://qiita.com/ReoNagai/items/5da95dea149c66ddbbdd). Der größte Teil des Kernteils ist das Kopieren. .. .. Nein, ich weiß das wirklich zu schätzen.

CalcCalibration.py


import os
import sys
import numpy as np
import cv2
from time import sleep
from datetime import datetime

FILE_NAME = "calib.yml"
#Anzahl der Referenzbilder
REFERENCE_IMG = 40
#Die Größe einer Seite des Quadrats[cm]
SQUARE_SIZE = 2.0
#Anzahl der Schnittpunkte
PATTERN_SIZE = (8, 13)


def main():
    """
Hauptfunktion
    :return:
    """
    calc_camera()  #Berechnen Sie die Kamera-Verzerrung


def calc_camera():
    """
Funktion zur Berechnung der Kameraverzerrung
    :return:
    """
    pattern_points = np.zeros((np.prod(PATTERN_SIZE), 3), np.float32)  #Chestboard (X.,Y,Z) Festlegen von Koordinaten(Z=0)
    pattern_points[:, :2] = np.indices(PATTERN_SIZE).T.reshape(-1, 2)
    pattern_points *= SQUARE_SIZE
    obj_points = []
    img_points = []

    capture = cv2.VideoCapture(0)
    #Geben Sie die Auflösung an
    #Stellen Sie die Breite des Kamerabildes auf 1920 ein
    capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
    #Stellen Sie die vertikale Breite des Kamerabildes auf 1080 ein
    capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)

    while len(obj_points) < REFERENCE_IMG:
        #Holen Sie sich ein Bild
        ret, img = capture.read()
        height = img.shape[0]
        width = img.shape[1]

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        #Erkennt Schachbrettecken
        ret, corner = cv2.findChessboardCorners(gray, PATTERN_SIZE)
        #Wenn es eine Ecke gibt
        if ret:
            print("detected coner!")
            print(str(len(obj_points) + 1) + "/" + str(REFERENCE_IMG))
            term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1)
            cv2.cornerSubPix(gray, corner, (5, 5), (-1, -1), term)
            img_points.append(corner.reshape(-1, 2))  #Methode anhängen: Fügen Sie am Ende der Liste ein Faktorobjekt hinzu
            obj_points.append(pattern_points)

        cv2.imshow('image', img)
        #Warten Sie 200 ms, da dies jedes Mal beurteilt wird. Es ist hier, um sich zu verzögern
        if cv2.waitKey(200) & 0xFF == ord('q'):
            break

    print("calculating camera parameter...")
    #Interne Parameter berechnen
    rms, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)

    #Berechnungsergebnis anzeigen
    print("RMS = ", rms)
    print("mtx = \n", mtx)
    print("dist = ", dist.ravel())

    #In yml speichern
    f = cv2.FileStorage(FILE_NAME, flags=1)
    f.write('mtx', mtx)
    f.write('dist', dist)
    # f.write('translation', rvecs)
    # f.write('distortion', tvecs)
    f.release()


if __name__ == '__main__':
    main()

Die Anzahl der Referenzbilder, die Größe einer Seite des Quadrats, die Anzahl der Schnittpunkte und die Einstellungen für die Kameraauflösung Je nach Umgebung einstellen. Dieses Mal habe ich [hier] erstellt (https://drive.google.com/file/d/1A56mjyobKN3cLkFkPgokO8qCoDXUdXIC/view?usp=sharing), es im Format A4 gedruckt und auf einer Kunststoffplatte verwendet. Da eine Seite des Quadrats 20 mm beträgt, beträgt sie 2,0 cm, und die Schnittpunkte sind 8 in horizontaler Richtung und 13 in vertikaler Richtung. Die Verzerrungsberechnung wird durchgeführt, während Sie sich gleichmäßig bewegen, wie in ↓ gezeigt. ![img_20200401012008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168779/fe2471c8-f19c-d3da-44e6-82e2ab4cb49a.jpeg) ![img_20200401012013.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168779/6abf5305-4be0-2c42-4ab7-7d3b7aa234b7.jpeg) ![img_20200401012017.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168779/390faef9-27ed-1da9-1faf-8445a2821ff1.jpeg)

Wenn die Ecken von 40 Schachbrettern erkannt werden können, wird die Verzerrung berechnet. Sie können das Ergebnis wie unten gezeigt überprüfen. Gleichzeitig können Sie sehen, dass "calib.yml" ausgegeben wird. image.png

calib.yml


%YAML:1.0
---
mtx: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 7.7958988893525259e+02, 0., 9.8266449367809537e+02, 0.,
       7.7847873908657630e+02, 5.7636196300911377e+02, 0., 0., 1. ]
dist: !!opencv-matrix
   rows: 1
   cols: 5
   dt: d
   data: [ -1.8378651673412880e-01, 4.1014929211162864e-02,
       -1.2046811513395908e-03, -4.8516056956278577e-04,
       -4.8595996923656995e-03 ]

Lesen Sie die Yaml-Datei mit OpenCvSharp4 und führen Sie eine Verzerrungskorrektur durch

Installieren Sie zunächst opencvsharp. Aus irgendeinem Grund verursachte OpenCvSharp4 auf der Oberseite zur Laufzeit einen DLL-Ladefehler. Installieren Sie OpenCvSharp4.WIndows.

image.png Bereiten Sie nach Abschluss der Installation "calib.yml" und ein Image zur Überprüfung vor. Führen Sie den folgenden Code aus.

Program.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;

namespace CameraCalibrationSample
{
    class Program
    {
        static void Main(string[] args)
        {
            const string ImagePath = @"./img/";
            const string YamlFilePath = @"calib.yml";

            // (1)Kalibrierungsbild(Vor der Korrektur)Wird geladen
            string[] imagePaths = System.IO.Directory.EnumerateFiles(ImagePath, "*", System.IO.SearchOption.AllDirectories).ToArray();
            int imageNum = imagePaths.Length;

            Mat[] srcImg = new Mat[imageNum];
            for (int i = 0; i < imageNum; i++)
            {
                srcImg[i] = Cv2.ImRead(imagePaths[i], ImreadModes.Color);
                Mat src = Cv2.ImRead(imagePaths[i], ImreadModes.Color);

                //Lesen Sie die yml-Datei und erhalten Sie die Berechnungsparameter
                using (var fs = new FileStorage(YamlFilePath, FileStorage.Mode.Read))
                {
                    var mtx = fs["mtx"].ReadMat();
                    var dist = fs["dist"].ReadMat();

                    Mat calib = new Mat();
                    Cv2.Undistort(src, calib, mtx, dist);
                    Cv2.ImShow("src", srcImg[i]);
                    Cv2.ImShow("calib", calib);
                    OpenCvSharp.Cv2.WaitKey(0);
                }
            }

            Cv2.DestroyAllWindows();
        }
    }
}

Wenn die Verzerrungsberechnung gut funktioniert, sieht es wie ↓ aus. ・ Vor der Korrektur image.png

·Nach der Korrektur image.png

Sie können sehen, dass es richtig korrigiert wurde. Du hast es geschafft! (^ O ^)

Am Ende

Es gibt einige Unterschiede im Code zwischen der 3. und 4. Serie, und selbst wenn ich versuchte, das Beispiel der alten Version mit 4 neu zu schreiben, war der Schwellenwert hoch. .. .. Es gibt Beispielquellen für C ++ und Python auf der offiziellen Website des ursprünglichen OpenCV, aber es ist ziemlich schwierig für mich, sie durch C # zu ersetzen. Dieses Mal habe ich das Schreiben des Berechnungsteils in C # aufgegeben und beschlossen, ihn nur dann in C # zu schreiben, wenn die Korrekturparameter verwendet werden. Trotzdem hat es lange gedauert, da die Art und Weise, Dateispeicher zu schreiben, zwischen 3 und 4 Serien sehr unterschiedlich war. Wenn Sie sich Wiki richtig ansehen, können Sie es sofort sehen, aber es hat lange gedauert, es zu bemerken, da ich nur 3 Serienmuster verfolgt habe. Ich hätte es richtig untersuchen sollen.

Referenzquelle

Danke für die obige URL. https://qiita.com/ReoNagai/items/5da95dea149c66ddbbdd https://github.com/shimat/opencvsharp/wiki/FileStorage https://stackoverrun.com/ja/q/11850575 http://hima-tubusi.blogspot.com/2016/02/opencvsharp_3.html https://qiita.com/Kazuhito/items/cc6b8a0bd75cf9689bf9 https://www.learnopencv.com/camera-calibration-using-opencv/

Recommended Posts

Verwenden Sie die Kamerakalibrierungsdatei mit OpenCvSharp4
Verwenden Sie eine Point Grey-Kamera mit Python (PyCapture2).
Kamerakalibrierung
Kamerakalibrierung und Verwendung mit opencv-python [chang method]
Verwenden Sie mecab-ipadic-neologd mit igo-python
Verwenden Sie ansible mit cygwin
Verwenden Sie pipdeptree mit virtualenv
[Python] Verwenden Sie JSON mit Python
Verwenden Sie Mock mit Pytest
Verwenden Sie den Indikator mit pd.merge
Dateivorgang mit open - "../"
Verwenden Sie Gentelella mit Django
Verwenden Sie Mecab mit Python 3
Verwenden Sie Tensorboard mit Chainer
Verwenden Sie DynamoDB mit Python
Verwenden Sie pip mit MSYS2
Verwenden Sie Python 3.8 mit Anaconda
Verwenden Sie Copyright mit Spacemacs
Datei-Upload mit Django
Verwenden Sie Python mit Docker
Verwenden Sie TypeScript mit Django-Kompressor
Verwenden Sie WENIGER mit Django
Verwenden Sie MySQL mit Django
[Windows] [Python] Kamerakalibrierung des Fischaugenobjektivs mit OpenCV
Kamerakalibrierung visuell verstehen
Verwenden Sie Enum mit SQLAlchemy
Verwenden Sie Tensorboard mit NNabla
Verwenden Sie GPS mit Edison
Verwenden Sie nim mit Jupyter
Verwenden Sie die Trello-API mit Python
Verwenden Sie gemeinsam genutzten Speicher mit gemeinsam genutzten Bibliotheken
Verwenden Sie benutzerdefinierte Tags mit PyYAML
Verwenden Sie Richtungsdiagramme mit networkx
Verwenden Sie TensorFlow mit Intellij IDEA
Verwenden Sie die Twitter-API mit Python
Verwenden Sie pip mit Jupyter Notebook
Kameraerfassung mit Python + OpenCV
Zeichnen Sie eine netCDF-Datei mit Python
Verwenden Sie DATE_FORMAT mit dem SQLAlchemy-Filter
Verwenden Sie TUN / TAP mit Python
Schnelle Dateiübertragung mit Stoff
Verwenden Sie SSL mit Sellerie + Redis
Verwenden Sie Cython mit Jupyter Notebook
Verwenden Sie Maxout + CNN mit Pylearn2
Verwenden Sie WDC-433SU2M2 mit Manjaro Linux
Verwenden Sie OpenBLAS mit numpy, scipy
Verwenden Sie die Unterschall-API mit Python3
Datei-Upload mit Flask + jQuery
Verwenden von Sonicwall NetExtener mit Systemd
Laden Sie die CSV-Datei mit Python herunter
Verwenden Sie prefetch_related bequem mit Django
Erstellen Sie eine Xlsx-Datei mit XlsxWriter
Verwenden Sie einen AWS-Interpreter mit Pycharm
Verwenden von Bokeh mit IPython Notebook
Verwenden Sie Python-ähnliche Bereiche mit Rust