Dieser Artikel nutzt Python und OpenCV für eine Perspektivtransformation: die vier Ecken eines Bildes auf vier neue legen. Kurz: getPerspectiveTransform berechnet die Matrix, warpPerspective verzerrt die Pixel. Das Beispiel ist ein 600×600-Gitter mit einer Silhouette. (Die Beschriftungen in den Abbildungen sind englisch.)

Kernpunkte
| Hierhin | Punkt |
|---|---|
| Was wir tun | Legen Sie fest, wohin die vier Ecken gehen; die Ebene streckt sich zum Trapez |
| Code und Ergebnis | Das Skript unten mit derselben Ordnerlage wie in der Abbildung ausführen |
| Ordner | source_pics und save_pics neben das Skript legen |
| Koordinaten | Oben links ist [0, 0]. Reihenfolge: oben-links → unten-links → unten-rechts → oben-rechts |
| Die übrigen Zeilen | Lesen, Größe, Matrix, Verzerrung, Speichern |
| Ausgabegröße | Pixel außerhalb des dritten Arguments werden abgeschnitten |
| Ihr eigenes Bild | Nur Punktreihenfolge und Ausgabegröße an das gewünschte Rechteck anpassen |
| Eingeschränkte Kamera | Auch schräg liefern die vier Ecken der realen Ebene noch ein Rechteck an Daten |
Eine Perspektivtransformation legt fest, wohin die vier Ecken gehen
Eine affine Transformation (warpAffine) lässt parallele Linien parallel. Eine Perspektivtransformation (getPerspectiveTransform und warpPerspective) kann die vier Ecken unabhängig verschieben, also ein Trapez, das vorn breit und hinten schmal ist. Eine Visitenkarte von oben zum Rechteck richten oder einen Boden in Aufsicht betrachten, gehören zu diesen Funktionen.
Übergeben Sie Eingangs- und Ausgangsecken in derselben Reihenfolge. Dieser Artikel geht die Algebra in der Matrix nicht durch. Wenn Sie wissen, wohin die vier Ecken gehen, können Sie die Funktionen nutzen.
Das Skript und Vorher/Nachher
Zuerst ein laufendes Skript. Die nächsten Abschnitte folgen den Koordinaten und den übrigen Zeilen.
import numpy as np
import cv2
image = cv2.imread("source_pics/test_1.png", cv2.IMREAD_COLOR)
height, width, channels = image.shape[:3]
source_points = np.array([[0, 0], [0, height], [width, height], [width, 0]], dtype=np.float32)
target_points = np.array([[200, 0], [0, 600], [600, 600], [400, 0]], dtype=np.float32)
mat = cv2.getPerspectiveTransform(source_points, target_points)
perspective_image = cv2.warpPerspective(image, mat, (width, height))
cv2.imwrite("save_pics/perspective_image.png", perspective_image)

Dieses Beispiel zieht die Oberkante nach innen, daher ist das Ergebnis ein Trapez, oben schmal und unten breit. Der schwarze Rand ist der Teil der Ausgabefläche außerhalb des verzerrten Vierecks.
Ordner neben das Skript legen

Pfade im Code sind relativ zu dem test_1.py, das Sie ausführen. Das gelesene Bild ist source_pics/test_1.png; die geschriebene Datei ist save_pics/perspective_image.png. Bei eigenen Dateien die Namen angleichen oder die Pfadzeichenketten ändern.
Schlägt imread fehl, ist image None und die nächste Zeile, image.shape, bricht ab. Vor dem Lauf Ordnernamen und das aktuelle Arbeitsverzeichnis prüfen.
Koordinaten beginnen bei [0, 0] oben links
source_points = np.array([[0, 0], [0, height], [width, height], [width, 0]], dtype=np.float32)
target_points = np.array([[200, 0], [0, 600], [600, 600], [400, 0]], dtype=np.float32)
Die Arrays stehen in dieser Reihenfolge. Der Ursprung liegt nicht unten, wie auf Millimeterpapier.
| Reihenfolge | source_points | target_points |
|---|---|---|
| Oben links | [0, 0] | [200, 0] |
| Unten links | [0, height] | [0, 600] |
| Unten rechts | [width, height] | [600, 600] |
| Oben rechts | [width, 0] | [400, 0] |
Dieses Beispiel ist 600×600, daher sind height und width beide 600. Ausgefüllt sehen die Arrays so aus.
source_points = np.array([[0, 0], [0, 600], [600, 600], [600, 0]], dtype=np.float32)
target_points = np.array([[200, 0], [0, 600], [600, 600], [400, 0]], dtype=np.float32)
![Vier-Ecken-Karte einer Perspektivtransformation, bezogen auf source_points und target_points. Mit Ursprung oben links verkürzt Einziehen der Oberkante die Oberseite. [0, 0] und [600, 0] gehen nach [200, 0] und [400, 0].](https://toolcluster.app/wp-content/uploads/2026/08/opencv-perspective-coords.png)
Die beiden oberen Punkte rücken nach innen, die Oberkante wird kürzer. Die beiden unteren bleiben. Ändern Sie die Zahlen, und dieselbe Vier-Ecken-Zuordnung ergibt ein anderes Trapez.
Stimmen Eingangs- und Ausgangsreihenfolge nicht überein, verdreht sich die Zuordnung. Beide als oben-links → unten-links → unten-rechts → oben-rechts schreiben. Punkte auf einer mathematischen y-Achse (oben positiv) lassen das Bild auf dem Kopf stehen.
Was die übrigen Zeilen tun
Imports
import numpy as np
import cv2
NumPy hält die Punktarrays. OpenCVs cv2 liest, schreibt und verzerrt Bilder.
Bild lesen
image = cv2.imread("source_pics/test_1.png", cv2.IMREAD_COLOR)
cv2.imread lädt test_1.png aus source_pics, neben dem Skript, in Farbe, in image.
Bildgröße
height, width, channels = image.shape[:3]
shape liefert Höhe, Breite und Kanalzahl. Dieses Beispiel nutzt die Kanäle nicht, aber die Anzahl der entpackten Werte muss passen, daher werden alle drei genommen.
Die Zahl der Variablen an die Zahl der entpackten Werte anpassen.
Punkte für die Matrix
source_points = np.array([[0, 0], [0, height], [width, height], [width, 0]], dtype=np.float32)
target_points = np.array([[200, 0], [0, 600], [600, 600], [400, 0]], dtype=np.float32)
Jeweils vier XY-Punkte. Auf diesem Quellbild ist [height, width] [600, 600], daher enthalten die Arrays:
source_points = [[ 0. 0.]
[ 0. 600.]
[600. 600.]
[600. 0.]]
target_points = [[200. 0.]
[ 0. 600.]
[600. 600.]
[400. 0.]]
Das sind die Koordinaten aus der Abbildung. Die Verzerrung nutzt diese Zuordnung.
Die Transformationsmatrix
mat = cv2.getPerspectiveTransform(source_points, target_points)
cv2.getPerspectiveTransform berechnet die Matrix aus den vier Eingangsecken und den vier Ausgangsecken. In diesem Beispiel sind die Werte:
mat = [[ 3.33333333e-01 -3.33333333e-01 2.00000000e+02]
[ 0.00000000e+00 3.33333333e-01 0.00000000e+00]
[ 0.00000000e+00 -1.11111111e-03 1.00000000e+00]]
Die Bedeutung jedes Eintrags brauchen Sie hier nicht. Gehen die Ecken dorthin, wo Sie sie wollten, den Rückgabewert an die nächste Zeile übergeben.
Die Verzerrung
perspective_image = cv2.warpPerspective(image, mat, (width, height))
cv2.warpPerspective nimmt das Quellbild, die Matrix sowie Ausgabebreite und -höhe. Dieses Beispiel verkürzt nur eine Kante, daher bleibt die Ausgabegröße (width, height), wie die Quelle. Die echte Größe an den transformierten Koordinaten festlegen.
Speichern
cv2.imwrite("save_pics/perspective_image.png", perspective_image)
cv2.imwrite schreibt perspective_image.png nach save_pics, neben dem Skript. Den Ordner zuerst anlegen; ohne ihn schlägt das Schreiben fehl.
Ist die Ausgabe zu klein, wird der Überstand abgeschnitten
Lassen Sie die Ausgabe bei 600×600 und nehmen Sie Punkte wie diese, dann verlässt der gedehnte obere Teil die Fläche.
source_points = np.array([[200, 0], [0, 600], [600, 600], [400, 0]], dtype=np.float32)
target_points = np.array([[0, 0], [0, 600], [600, 600], [600, 0]], dtype=np.float32)
![Zuschnitt bei zu kleiner Ausgabefläche, gezeigt an Punkten außerhalb des Rahmens. Erklärt, dass das dritte Argument von warpPerspective die geschriebene Bildgröße ist. Die ursprünglichen [0, 0] und [600, 0] liegen außerhalb 600×600, oben wird geschnitten.](https://toolcluster.app/wp-content/uploads/2026/08/opencv-perspective-output-crop-en.png)
Das dritte Argument ist die Größe des Bildes, das Sie schreiben, nicht die Größe der verzerrten Welt. Pixel, deren Punkte außerhalb dieses Rechtecks liegen, sind weg. Um sie zu behalten, die Ausgabe zuerst vergrößern oder target-Punkte wählen, die alle hineinpassen.
Liegt ein target-x oder -y jenseits von Ausgabebreite oder -höhe und bleibt das dritte Argument bei der Quellgröße, wird abgeschnitten. Sieht es geschnitten aus, zuerst Punkte und Ausgabegröße vergleichen.
Dieselben Schritte gelten für eigene Fotos
Bleibt die Vier-Ecken-Reihenfolge, arbeiten dieselben zwei Funktionen auch auf Fotos, die kein Gitter sind. Nur die target-Zahlen und die Ausgabegröße an das gewünschte Rechteck anpassen.
Auch wenn die Kamera schräg sitzt, liefern vier Ecken noch ein Rechteck
Sie haben eine kurze Kette gemacht: Eingangsecken den Ausgangsecken zuordnen, die Matrix lösen, auf die Ausgabefläche schreiben. Die Funktionen sind auf dem Gitter und auf einem Foto vom Boden dieselben. Vor Ort ändern sich nur die Punktwahl und die Ausgabegröße.
Wenn die Kameraposition von der Maschine festliegt
An Anlagen und Prüfständen können Sie die Kamera oft nicht senkrecht über dem Teil platzieren. Abdeckungen, Leitungen, Schutze und Roboterreichweite stehen zuerst; das Objektiv wird danach hineingezwängt. Messen oder lesen Sie das Bild so, bleibt ein Trapez, vorn breit und hinten schmal, und Längen und Lagen sind verzerrt.
Ordnen Sie die vier Ecken zu, und Sie gewinnen das Rechteck der gewünschten Ebene zurück, ohne den Rahmen neu zu bauen. Datenerfassung bleibt möglich, wenn die Kamerapose strukturell eingeschränkt ist. Der eigentliche Kniff ist, die Punkte auf die vier Ecken der physischen Ebene zu legen, nicht auf die vier Ecken des Bildschirms. Eine Werkstückecke, eine Vorrichtungsbohrung, eine Bodenfuge — jeder Punkt, den Sie später wieder zeigen können — und die Schritte dieses Artikels gelten unverändert.
Sie müssen die Mathematik nicht selbst schreiben
OpenCV ist eine Implementierung für diese Aufgabe. Die Punkte mit NumPy zu legen und an OpenCVs getPerspectiveTransform und warpPerspective zu übergeben, heißt eine gepflegte Implementierung zu nutzen statt die Algebra selbst zu schreiben. Diese Wahl ist nicht auf OpenCV beschränkt. Rund um Bildverarbeitung, Numerik, Kommunikation und Steuerung gibt es für dieselbe Arbeit bereits Implementierungen, die andere pflegen und versionieren. Diesen Code zu lesen und zu nutzen bringt Sie schneller zu den Maschinengrenzen zurück, als die projektive Mathematik von Grund auf abzuleiten.
Nutzen reicht. Treffen Sie auf ein Loch oder etwas Unklares, können Sie es melden, die Doku richten oder einen Patch schicken. Wie viel Sie zurückgeben, unterscheidet sich. Auch null stellt Sie noch auf die Seite, die diese Arbeit am Laufen hält, indem Sie auf die nächste Version warten. Das Werkzeug an Ihre Maschine anpassen und bei Bedarf etwas zurückgeben. Diese Schleife nutzt Ingenieurzeit besser, als eine vollständige Eigenentwicklung zu tragen.
Auch mit schräger Kamera machen vier Ecken noch ein Rechteck an Daten. Danach ist die eigentliche Arbeit, zu messen, zu lesen und zu behalten, was auf diesem Rechteck liegt.

Schreibe einen Kommentar