5 Best Ways to Rotate an Image in OpenCV Python

πŸ’‘ Problem Formulation: You have an image in your Python application that you need to rotate to a certain angle, maintaining the image’s quality and perspective. For instance, you might have a photo captured in portrait mode that you want to display in landscape mode without cropping or distorting the content. The goal is to learn different methods to rotate this image using OpenCV library in Python, with the desired output being the same image oriented at a specified angle.

Method 1: Using getRotationMatrix2D and warpAffine

This method utilizes two functions from the OpenCV library. cv2.getRotationMatrix2D() creates a rotation matrix, which defines the rotation parameters such as the center of the image, rotation angle, and scale factor. cv2.warpAffine() applies the rotation to the image using the rotation matrix derived from the previous function.

Here’s an example:

import cv2

# Load the image
image = cv2.imread('image.jpg')

# Compute the center of the image
image_center = tuple(i/2 for i in image.shape[1::-1])

# Compute the rotation matrix
rotation_mat = cv2.getRotationMatrix2D(image_center, 45, 1.0)

# Perform the actual rotation and display the image
rotated_image = cv2.warpAffine(image, rotation_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
cv2.imshow('Rotated Image', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output of this code snippet will be a window displaying ‘image.jpg’ rotated by 45 degrees around its center.

This snippet loads the image, calculates the center, creates a rotation matrix to rotate the image by 45 degrees without changing the scale (1.0), and finally applies this rotation matrix to output the rotated image.

Method 2: Rotating Without Cropping

Rotating an image without cropping involves additional steps to calculate the new width and height to accommodate the rotated image completely. This method ensures that no part of the image is lost after rotation. After calculating the new dimensions, cv2.warpAffine() is used as before.

Here’s an example:

import cv2
import numpy as np

# Load the image
image = cv2.imread('image.jpg')

# Get image dimensions
(h, w) = image.shape[:2]

# Compute the center of the image
center = (w / 2, h / 2)

# Rotate the image by 45 degrees without cropping
M = cv2.getRotationMatrix2D(center, 45, 1)
cos = np.abs(M[0, 0])
sin = np.abs(M[0, 1])

# Compute the new bounding dimensions of the image
nW = int((h * sin) + (w * cos))
nH = int((h * cos) + (w * sin))

# Adjust the rotation matrix to take into account translation
M[0, 2] += (nW / 2) - center[0]
M[1, 2] += (nH / 2) - center[1]

# Perform the actual rotation and display the image
rotated = cv2.warpAffine(image, M, (nW, nH))
cv2.imshow('Rotated Without Cropping', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output of this code snippet will be a window displaying ‘image.jpg’ rotated by 45 degrees without any cropping.

This code first calculates the new dimensions needed to avoid cropping. It then updates the rotation matrix to accommodate for the translation and finally applies this adjusted rotation to get the non-cropped rotated image.

Method 3: Using cv2.rotate

The cv2.rotate() function is a simple way to rotate an image by 90-degree increments. This method is less flexible than the getRotationMatrix2D and warpAffine combination because it does not allow for arbitrary rotation angles, but it is more straightforward for angles that are multiples of 90.

Here’s an example:

import cv2

# Load the image
image = cv2.imread('image.jpg')

# Rotate the image by 90 degrees clockwise
rotated_image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)

# Display the image
cv2.imshow('Rotated Image 90 CW', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output of this code snippet will be a window displaying ‘image.jpg’ rotated by 90 degrees in the clockwise direction.

This code snippet simply loads the image and applies the cv2.rotate() function to rotate it by 90 degrees clockwise, which is one of the pre-defined rotation options in OpenCV.

Method 4: Rotate with resize

Rotating with resizing involves rotating the image by an arbitrary angle with scaling. This is useful when an image requires both rotation and size adjustment. This method also uses getRotationMatrix2D() and warpAffine(), with the addition of the scaling parameter within the rotation matrix.

Here’s an example:

import cv2

# Load the image
image = cv2.imread('image.jpg')

# Compute the center of the image
image_center = tuple(i/2 for i in image.shape[1::-1])

# Compute the rotation matrix with 0.75 scale factor
rotation_mat = cv2.getRotationMatrix2D(image_center, 45, 0.75)

# Perform the rotation with resizing
rotated_image = cv2.warpAffine(image, rotation_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
cv2.imshow('Rotated with Resize', rotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output of this code example is an image that is both rotated by 45 degrees and scaled down to 75% of its original size.

This code rotates the image at a 45-degree angle while simultaneously resizing it to 75% of its original size, showcasing how to combine rotation and scaling in one transformation step.

Bonus One-Liner Method 5: Using PIL

For those who prefer working with the Python Imaging Library (PIL), there’s a straightforward one-liner method to rotate images. Although this is not strictly OpenCV, PIL is commonly used in conjunction with OpenCV and provides a convenient rotate method.

Here’s an example:

from PIL import Image

# Load the image
image = Image.open('image.jpg')

# Rotate the image by 45 degrees
rotated_image = image.rotate(45)

# Save or display the image
rotated_image.show()

Output of this code will be a window popping up with ‘image.jpg’ rotated by 45 degrees.

This succinct code snippet opens the image using PIL’s Image module and applies the rotate() function to easily rotate the image to a specified angle.

Summary/Discussion

  • Method 1: getRotationMatrix2D and warpAffine. Strengths: offers precise control over rotation with a specified angle and optional scaling. Weaknesses: more complex than some other methods due to multi-step process.
  • Method 2: Rotating Without Cropping. Strengths: ensures full image is preserved after rotation. Weaknesses: requires more calculations and adjustments to the rotation matrix to prevent cropping.
  • Method 3: Using cv2.rotate. Strengths: easy to use for 90-degree increments. Weaknesses: not suitable for arbitrary rotation angles.
  • Method 4: Rotate with resize. Strengths: Combines rotation and resizing in one operation. Weaknesses: Needs fine-tuning when choosing the scale factor to prevent distortion.
  • Bonus Method 5: Using PIL. Strengths: extremely straightforward for simple rotations. Weaknesses: this is not an OpenCV method, which might not suit all workflows.