Last modified: Apr 21, 2025 By Alexander Williams
Python Image Perspective Correction Guide
Image perspective correction is a useful technique in computer vision. It helps fix distorted images caused by camera angles. This guide shows how to do it in Python.
Table Of Contents
- What Is Perspective Correction?
- Required Libraries
- Step 1: Load and Prepare the Image
- Step 2: Detect Edges and Corners
- Step 3: Find the Document Contour
- Step 4: Define Source and Destination Points
- Step 5: Apply Perspective Transformation
- Step 6: Save and Display Results
- Complete Code Example
- Common Issues and Solutions
- Advanced Applications
- Conclusion
What Is Perspective Correction?
Perspective correction fixes skewed images. It makes them appear as if taken straight-on. This is useful for document scanning or object recognition.
Common applications include fixing photos of documents, whiteboards, or license plates. The process involves transforming the image to remove perspective distortion.
Required Libraries
We'll use OpenCV and NumPy for this task. Install them using pip if you haven't already.
pip install opencv-python numpy
Step 1: Load and Prepare the Image
First, we load the image using OpenCV. Convert it to grayscale for easier processing.
import cv2
import numpy as np
# Load image
image = cv2.imread('skewed_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
Step 2: Detect Edges and Corners
We need to find the document's corners. Use edge detection and contour finding for this.
# Edge detection
edges = cv2.Canny(gray, 50, 150)
# Find contours
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
For more on edge detection, see our Python Image Analysis Guide.
Step 3: Find the Document Contour
We look for the largest quadrilateral contour. This should be our document.
# Sort contours by area and get the largest
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1]
# Approximate the contour
peri = cv2.arcLength(contours[0], True)
approx = cv2.approxPolyDP(contours[0], 0.02 * peri, True)
Step 4: Define Source and Destination Points
We need to map the skewed corners to a rectangle. This creates our transformation.
# Source points (skewed corners)
src_points = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])
# Destination points (rectangle)
height = max(np.linalg.norm(src_points[0] - src_points[1]),
np.linalg.norm(src_points[2] - src_points[3]))
width = max(np.linalg.norm(src_points[1] - src_points[2]),
np.linalg.norm(src_points[3] - src_points[0]))
dst_points = np.float32([[0, 0], [width, 0], [width, height], [0, height]])
Step 5: Apply Perspective Transformation
Use cv2.getPerspectiveTransform and cv2.warpPerspective to correct the image.
# Get transformation matrix
matrix = cv2.getPerspectiveTransform(src_points, dst_points)
# Apply transformation
result = cv2.warpPerspective(image, matrix, (int(width), int(height)))
Step 6: Save and Display Results
Finally, save the corrected image and display both versions.
# Save result
cv2.imwrite('corrected_image.jpg', result)
# Display images
cv2.imshow('Original', image)
cv2.imshow('Corrected', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Complete Code Example
Here's the complete code for easy copying. It includes all steps in one script.
import cv2
import numpy as np
# Load image
image = cv2.imread('skewed_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Edge detection and contours
edges = cv2.Canny(gray, 50, 150)
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Find document contour
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1]
peri = cv2.arcLength(contours[0], True)
approx = cv2.approxPolyDP(contours[0], 0.02 * peri, True)
# Define points
src_points = np.float32([approx[0][0], approx[1][0], approx[2][0], approx[3][0]])
height = max(np.linalg.norm(src_points[0] - src_points[1]),
np.linalg.norm(src_points[2] - src_points[3]))
width = max(np.linalg.norm(src_points[1] - src_points[2]),
np.linalg.norm(src_points[3] - src_points[0]))
dst_points = np.float32([[0, 0], [width, 0], [width, height], [0, height]])
# Transform and save
matrix = cv2.getPerspectiveTransform(src_points, dst_points)
result = cv2.warpPerspective(image, matrix, (int(width), int(height)))
cv2.imwrite('corrected_image.jpg', result)
Common Issues and Solutions
1. No contours found: Adjust the Canny edge thresholds or blur the image first.
2. Wrong contour selected: Check the contour sorting or add area filtering.
3. Poor quality output: Ensure good lighting when capturing the original image.
For related techniques, see our Python Image Cropping Guide.
Advanced Applications
Perspective correction can be combined with other techniques. For example, you could create image collages with corrected perspectives.
It's also useful in image recognition systems where perspective matters.
Conclusion
Python makes perspective correction easy with OpenCV. The process involves detecting edges, finding contours, and applying transformations.
This technique is valuable for document scanning, object recognition, and many computer vision applications. With practice, you can adapt it to various real-world scenarios.