π‘ 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.