HOWTO · Python

OpenCV Bild drehen

In diesem Artikel erfahren Sie, wie Sie ein Bild mithilfe der Funktionen `rotate()` und `warpAffine()` von OpenCV drehen.

Auf dieser Seite

In Python bietet OpenCV zwei Möglichkeiten, ein Bild zu drehen. Verwenden Sie cv2.rotate() für eine Drehung um einen rechten Winkel. Für andere Winkel oder wenn Sie Drehzentrum und Skalierung festlegen möchten, verwenden Sie cv2.warpAffine() zusammen mit cv2.getRotationMatrix2D(). Beide Funktionen arbeiten mit Bildarrays. Die Beispiele erstellen kleine Arrays direkt im Code und benötigen daher keine externe Bilddatei. Installieren Sie OpenCV und NumPy, um die OpenCV-Beispiele auszuführen.

OpenCV rotate() für Drehungen um 90°, 180° und 270° verwenden

cv2.rotate() erhält ein Bildarray und eine von drei Konstanten für die Ausrichtung. Verwenden Sie cv2.ROTATE_90_CLOCKWISE für eine Vierteldrehung im Uhrzeigersinn, cv2.ROTATE_90_COUNTERCLOCKWISE für eine Vierteldrehung gegen den Uhrzeigersinn (dieselbe Ausrichtung wie 270° im Uhrzeigersinn) oder cv2.ROTATE_180 für eine halbe Drehung. Bei einer Vierteldrehung werden Breite und Höhe vertauscht; bei einer halben Drehung bleiben sie gleich. Dieses Beispiel wendet alle drei Möglichkeiten auf ein kleines Bildarray an und gibt jeweils die Ergebnisform aus. Ist OpenCV oder NumPy nicht installiert, wird stattdessen ein Hinweis zur Einrichtung ausgegeben.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

try:
    import cv2
    import numpy as np
except ImportError:
    print("Install opencv-python and numpy to run this example.")
else:
    image = np.zeros((2, 3, 3), dtype=np.uint8)  # 2 rows, 3 columns, 3 color channels
    rotations = {
        "clockwise": cv2.ROTATE_90_CLOCKWISE,
        "counterclockwise": cv2.ROTATE_90_COUNTERCLOCKWISE,
        "half-turn": cv2.ROTATE_180,
    }
    for name, orientation in rotations.items():
        rotated = cv2.rotate(image, orientation)
        print(f"{name}: {rotated.shape[1]}x{rotated.shape[0]}")

Das folgende Listenbeispiel veranschaulicht unabhängig davon, wie die Koordinaten neu angeordnet werden. Führen Sie das Beispiel aus:

image = [["A", "B", "C"], ["D", "E", "F"]]
rotated = [list(row) for row in zip(*image[::-1])]
print(f"original: {len(image[0])}x{len(image)}")
print(f"rotated: {len(rotated[0])}x{len(rotated)}")
print("rows:", rotated)
original: 3x2
rotated: 2x3
rows: [['D', 'A'], ['E', 'B'], ['F', 'C']]

Dreispaltiges Originalbild neben seiner Drehung um 90° im Uhrzeigersinn mit zwei Spalten und drei Zeilen

Die beschrifteten Zellen veranschaulichen die Drehrichtung und die geänderten Abmessungen, ohne dass ein Anzeigefenster erforderlich ist. Das OpenCV-Beispiel gibt die Abmessungen als Breite mal Höhe aus, obwohl NumPy die Bildform als Höhe, Breite und Kanalzahl speichert. Für eine Bilddatei übergeben Sie ein von cv2.imread() zurückgegebenes Array an cv2.rotate() und prüfen zuerst, ob das Einlesen erfolgreich war. Verwenden Sie cv2.rotate() nur für diese Drehungen um rechte Winkel; beliebige Winkel werden nicht unterstützt.

OpenCV warpAffine() für Drehungen um beliebige Winkel verwenden

cv2.getRotationMatrix2D(center, angle, scale) gibt eine affine 2-mal-3-Matrix zurück. center ist ein Punkt (x, y), angle wird in Grad angegeben (positive Werte drehen in den Bildkoordinaten von OpenCV gegen den Uhrzeigersinn), und scale skaliert die Bildgröße: 1.0 lässt sie unverändert, ein Wert unter 1.0 verkleinert sie und ein Wert über 1.0 vergrößert sie. cv2.warpAffine(image, matrix, (width, height)) wendet die Matrix auf eine Zielbildfläche an; das Größenargument erwartet zuerst die Breite und dann die Höhe. Dieses Beispiel dreht ein 120 mal 80 Pixel großes Bild um 30° um seinen Mittelpunkt und behält die ursprünglichen Abmessungen der Bildfläche bei, sodass Ecken abgeschnitten werden können. Sind die erforderlichen Pakete nicht verfügbar, gibt das Beispiel einen Einrichtungshinweis aus.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

try:
    import cv2
    import numpy as np
except ImportError:
    print("Install opencv-python and numpy to run this example.")
else:
    height, width = 80, 120
    image = np.zeros((height, width, 3), dtype=np.uint8)
    center = (width / 2, height / 2)
    angle = 30
    scale = 1.0
    matrix = cv2.getRotationMatrix2D(center, angle, scale)
    rotated = cv2.warpAffine(image, matrix, (width, height))
    print(f"input canvas: {width}x{height}")
    print(f"rotated canvas: {rotated.shape[1]}x{rotated.shape[0]}")

Rechteckiges Originalbild neben seiner Drehung um 30° auf derselben Bildfläche mit abgeschnittenen Eckbereichen

Das Beispiel behält absichtlich die ursprüngliche Zielgröße (width, height) bei. Die Ausgabe hat dadurch dieselben Abmessungen, und gedrehte Ecken außerhalb dieser Bildfläche werden abgeschnitten. Um das ganze Bild zu erhalten, berechnen Sie anhand der gedrehten Begrenzungen eine größere Zielbildfläche und passen die Translation der Matrix so an, dass der transformierte Mittelpunkt im Mittelpunkt der neuen Fläche liegt. Werden nur die Abmessungen der Zielfläche vergrößert, bleibt die Transformation an ihren ursprünglichen Koordinaten verankert.

warpAffine() füllt Zielpixel, denen kein Quellpixel zugeordnet ist. cv2.BORDER_CONSTANT verwendet standardmäßig eine konstante Füllfarbe (standardmäßig Schwarz); mit borderValue können Sie eine andere Farbe festlegen. cv2.BORDER_REPLICATE verlängert die nächstgelegenen Pixel am Quellbildrand. cv2.BORDER_TRANSPARENT lässt die entsprechenden Zielpixel unverändert. Initialisieren Sie daher die Zielfläche, wenn Sie diesen Modus verwenden; er stellt den ursprünglichen Bildrand nicht automatisch wieder her. Eine Übersicht der verfügbaren Modi finden Sie in der OpenCV-Referenz zu Randmodi.