HOWTO · Python
How to Rotate an Image in OpenCV
This article teaches you to rotate an image using the rotate() and warpAffine() function of OpenCV.
On this page
In Python, OpenCV provides two ways to rotate an image. Use cv2.rotate() for a right-angle turn; use cv2.warpAffine() with cv2.getRotationMatrix2D() for another angle or when you need to control the transform center and scale. Both functions operate on image arrays. The examples define small arrays in code, so they do not depend on an external image file. Install OpenCV and NumPy to run the OpenCV examples.
Use OpenCV rotate() for 90°, 180°, and 270° rotations
cv2.rotate() takes an image array and one of three orientation constants. Use cv2.ROTATE_90_CLOCKWISE for a clockwise quarter-turn, cv2.ROTATE_90_COUNTERCLOCKWISE for a counterclockwise quarter-turn (the same orientation as 270° clockwise), or cv2.ROTATE_180 for a half-turn. A quarter-turn swaps width and height; a half-turn keeps them. This example applies all three choices to a small image array and prints each result shape. If OpenCV or NumPy is not installed, it prints a setup reminder instead.
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]}")
The following list example is a separate illustration of the coordinate rearrangement. Run this example:
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']]
The labeled cells make the direction and dimension change visible without a display window; the OpenCV example reports dimensions as width by height even though NumPy stores an image shape as height, width, and channels. For a file, pass an array returned by cv2.imread() to cv2.rotate() and check that the read succeeded first. Use cv2.rotate() only for these right-angle orientations; it does not accept an arbitrary angle.
Use OpenCV warpAffine() for arbitrary-angle rotations
cv2.getRotationMatrix2D(center, angle, scale) returns a 2-by-3 affine matrix. center is an (x, y) point, angle is in degrees (positive values rotate counterclockwise in OpenCV image coordinates), and scale multiplies the image size: 1.0 keeps it, a value below 1.0 shrinks it, and a value above 1.0 enlarges it. cv2.warpAffine(image, matrix, (width, height)) applies the matrix onto a destination canvas; its size argument is ordered width, then height. This example rotates a 120-by-80 image by 30° around its center and keeps the original canvas dimensions, so corners may be clipped. It prints a setup reminder if the required packages are unavailable.
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]}")
The example deliberately keeps the original (width, height) destination, so the output has the same dimensions and rotated corners outside that canvas are clipped. To retain the full image, calculate a larger destination from the rotated bounds and adjust the matrix translation to move the transformed center to the new canvas center; increasing only the destination dimensions leaves the transform anchored at its original coordinates.
warpAffine() fills destination pixels that do not map to a source pixel. The default cv2.BORDER_CONSTANT uses a constant fill (black by default); set borderValue to choose another color. cv2.BORDER_REPLICATE extends the nearest source edge pixels. cv2.BORDER_TRANSPARENT leaves corresponding destination pixels unchanged, so initialize the destination when using it; the mode does not automatically reproduce the source border. See the OpenCV border-mode reference for available modes.