OpenCV Vogelperspektive ohne Datenverlust

Ich verwende OpenCV, um eine Vogelperspektive der aufgenommenen Bilder zu erhalten. Dies geschieht durch die Bereitstellung eines Schachbrettmusters in der Ebene, das die Vogelperspektive bildet.

Obwohl es so aussieht, als ob die Kamera auf dieser Ebene bereits hübsch ist, muss sie perfekt sein, um die Beziehung zwischen Pixeln und Zentimetern zu bestimmen.

In der nächsten Phase werden die Captures-Frames verzogen. Es gibt das erwartete Ergebnis:

Durch diese Umwandlung gehen jedoch Daten außerhalb des Schachbrettmusters verloren. Ich muss das Bild drehen, anstatt ein bekanntes Viereck zu verzerren.

Frage Wie drehe ich ein Bild um einen Kamerawinkel, so dass es von oben nach unten ist?

Etwas Code, um zu veranschaulichen, was ich gerade mache:

Size chessboardSize = new Size(12, 8); // Size of the chessboard

Size captureSize = new Size(1920, 1080); // Size of the captured frames

Size viewSize = new Size((chessboardSize.width / chessboardSize.height) * captureSize.height, captureSize.height); // Size of the view

MatOfPoint2f imageCorners; // Contains the imageCorners obtained in a earlier stage

Mat H; // Homography

Der Code, der die Ecken findet:

Mat grayImage = new Mat();
//Imgproc.resize(source, temp, new Size(source.width(), source.height()));
Imgproc.cvtColor(source, grayImage, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(grayImage, grayImage, 0.0, 255.0, Imgproc.THRESH_OTSU);
imageCorners = new MatOfPoint2f();
Imgproc.GaussianBlur(grayImage, grayImage, new Size(5, 5), 5); 
boolean found = Calib3d.findChessboardCorners(grayImage, chessboardSize, imageCorners, Calib3d.CALIB_CB_NORMALIZE_IMAGE + Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_FILTER_QUADS);

if (found) {

    determineHomography();
}

Der Code, der die Homographie bestimmt:

Point[] data = imageCorners.toArray();

if (data.length < chessboardSize.area()) {
    return;
}

Point[] roi = new Point[] {

    data[0 * (int)chessboardSize.width - 0], // Top left
    data[1 * (int)chessboardSize.width - 1], // Top right
    data[((int)chessboardSize.height - 1) * (int)chessboardSize.width - 0], // Bottom left
    data[((int)chessboardSize.height - 0) * (int)chessboardSize.width - 1], // Bottom right
};

Point[] roo = new Point[] {
    new Point(0, 0),
    new Point(viewSize.width, 0),
    new Point(0, viewSize.height),
    new Point(viewSize.width, viewSize.height)
};

MatOfPoint2f objectPoints = new MatOfPoint2f(), imagePoints = new MatOfPoint2f();

objectPoints.fromArray(roo);
imagePoints.fromArray(roi);

Mat H = Imgproc.getPerspectiveTransform(imagePoints, objectPoints);

Schließlich werden die erfassten Frames verzogen:

Imgproc.warpPerspective(capture, view, H, viewSize);

Antworten auf die Frage(2)

Ihre Antwort auf die Frage