๐ก Problem Formulation: Affine transformation in image processing refers to altering an image to correct for distortions or to apply certain effects. When using OpenCV in Python, developers often need to apply affine transformations to shift, scale, rotate or skew images. This article walks through five methods to do this on an input image, aiming for a transformed output based on provided transformation matrices.
Method 1: Using warpAffine for Translation
This method leverages OpenCV’s warpAffine
function to translate an image. Translation involves moving the image along the X and Y axes. This requires a transformation matrix which specifies the pixel shift in each direction.
Here’s an example:
import cv2 import numpy as np # Load the image image = cv2.imread('input.jpg') # Define translation matrix tx, ty = 100, 50 # shift 100 pixels on X and 50 pixels on Y axis trans_mat = np.float32([[1, 0, tx], [0, 1, ty]]) # Apply the warpAffine function translated_img = cv2.warpAffine(image, trans_mat, (image.shape[1], image.shape[0])) # Save the output cv2.imwrite('translated_image.jpg', translated_img)
The output is an image shifted 100 pixels right and 50 pixels down from its original position.
In this code snippet, warpAffine
takes three arguments: the original image, the transformation matrix, and the size of the output image. It outputs the translated image which is saved to the file system.
Method 2: Rotating an Image
Rotation of an image by a certain angle around a pivot point can be accomplished with an appropriate rotation matrix. OpenCV’s getRotationMatrix2D
can be used to create this matrix by specifying the center, angle, and scale factor.
Here’s an example:
import cv2 import numpy as np image = cv2.imread('input.jpg') height, width = image.shape[:2] # Specify the rotation center, the rotation angle, and the scale factor. center = (width//2, height//2) angle = 45 scale = 1 # Get the rotation matrix rot_mat = cv2.getRotationMatrix2D(center, angle, scale) # Rotate original image rotated_img = cv2.warpAffine(image, rot_mat, (width, height)) cv2.imwrite('rotated_image.jpg', rotated_img)
The output is the original image rotated 45 degrees about its center point.
The code creates a rotation matrix for a 45-degree rotation around the image’s central pixel, preserving the original size with no scaling. It then applies the warpAffine
function to perform the rotation.
Method 3: Scaling an Image
Scaling changes the size of an image. To scale using OpenCV’s warpAffine
, a scaling matrixโcomprising scaling factors along the X and Y axesโand the function itself are needed.
Here’s an example:
import cv2 import numpy as np image = cv2.imread('input.jpg') # Scaling factors sx, sy = 1.5, 1.5 # Scaling matrix scale_mat = np.float32([[sx, 0, 0], [0, sy, 0]]) # Scaling the image scaled_img = cv2.warpAffine(image, scale_mat, (int(image.shape[1]*sx), int(image.shape[0]*sy))) cv2.imwrite('scaled_image.jpg', scaled_img)
The output is the original image enlarged by 1.5 times along both axes.
The code snippet demonstrates enlarging an image by a factor of 1.5 in both dimensions, using the warpAffine
function to apply the scaling matrix.
Method 4: Skewing or Shearing an Image
Skewing, also known as shearing, distorts an image along either the X-axis or Y-axis. You must define a shearing matrix for this transformation. OpenCV applies this transformation using the warpAffine
function.
Here’s an example:
import cv2 import numpy as np image = cv2.imread('input.jpg') height, width = image.shape[:2] # Shearing factor for x-axis shx = 0.2 # Shearing matrix shear_mat = np.float32([[1, shx, 0], [0, 1, 0]]) # Shear the image sheared_img = cv2.warpAffine(image, shear_mat, (int(width + height*shx), height)) cv2.imwrite('sheared_image.jpg', sheared_img)
The output is a sheared image with a horizontal skew.
This code snippet applies horizontal shearing to the input image creating an output image that appears horizontally skewed by a factor defined by shx
.
Bonus One-Liner Method 5: Complete Affine Transformation
For a complete affine transformation customizing rotation, scaling, and translation, a combined matrix can be created and applied with warpAffine
.
Here’s an example:
import cv2 import numpy as np image = cv2.imread('input.jpg') # Combined affine transformation matrix affine_mat = np.float32([[1.5, 0.5, 100], [0.5, 1.5, 50]]) # Apply affine transformation transformed_img = cv2.warpAffine(image, affine_mat, (int(image.shape[1]*1.5 + image.shape[0]*0.5), int(image.shape[0]*1.5 + image.shape[1]*0.5))) cv2.imwrite('affine_transformed_image.jpg', transformed_img)
The output is an image that has been scaled, rotated, and translated based on the parameters in the affine transformation matrix.
This one-liner code snippet applies a complete affine transformation, which simultaneously performs scaling, rotation, and translation as specified by the combined transformation matrix.
Summary/Discussion
- Method 1: WarpAffine for Translation. Simple and effective for moving an image within the frame. Limited to shifting without altering image dimensions.
- Method 2: Rotating an Image. Allows for rotation around a point with a customizable scale. Limited to rotations and requires calculation of the rotation matrix.
- Method 3: Scaling an Image. Easy to adjust image size. Uniform scaling might not be ideal for all aspects or dimensions.
- Method 4: Skewing or Shearing an Image. Good for artistic effects or correcting perspective distortions. Can be nonintuitive to set the right shearing factor.
- Bonus Method 5: Complete Affine Transformation. Highly flexible with combined transformations. Complexity increases as transformation becomes more intricate.