Homographies - iffatAGheyas/computer-vision-handbook GitHub Wiki

πŸ”„ Homographies and Transformations

A homography is the most general planar (projective) transformation, mapping points from one plane to another. In computer vision, it aligns two images of the same flat surface taken from different viewpoints.


🧠 What Is a Homography?

  • It’s a 3x3 matrix H that warps one image to align with another.
  • Used to model perspective changes (camera tilt, view shifts).
  • Maps any 4 non-collinear points in one plane to 4 points in another.

Real-World Use Cases

Use Case What Homography Does
Panorama Stitching Warps one image to align with another
AR Projection Projects virtual objects onto real surfaces
Image Rectification Removes perspective distortion

πŸ”’ What Does a Homography Matrix Look Like?

It’s denoted H:

image

🐍 Full Code: Feature Matching + Homography (SIFT + FLANN)

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 1. Load and extract features
img1 = cv2.imread("bird1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("bird2.jpg", cv2.IMREAD_GRAYSCALE)
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 2. Match with FLANN + Lowe's ratio test
index_params = dict(algorithm=cv2.FLANN_INDEX_KDTREE, trees=5)
flann = cv2.FlannBasedMatcher(index_params, dict(checks=50))
matches = flann.knnMatch(des1, des2, k=2)
good = [m for m,n in matches if m.distance < 0.7*n.distance]

# 3. Compute homography
src_pts = np.float32([ kp1[m.queryIdx ].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

# 4. Warp image1 to align with image2
h, w = img2.shape
warp = cv2.warpPerspective(cv2.imread("bird1.jpg"), H, (w, h))

# 5. Visualise matches and warped result
plt.figure(figsize=(16,6))
plt.subplot(1,2,1)
plt.imshow(cv2.cvtColor(cv2.drawMatches(
    cv2.imread("bird1.jpg"), kp1,
    cv2.imread("bird2.jpg"), kp2,
    good, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS
), cv2.COLOR_BGR2RGB))
plt.title("Matched Keypoints (FLANN + SIFT)")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(cv2.cvtColor(warp, cv2.COLOR_BGR2RGB))
plt.title("Image 1 Warped to Align with Image 2")
plt.axis("off")
plt.tight_layout()
plt.show()

image

πŸ“‹ Recap: What This Code Does

Step Description
1–2 Load images, detect SIFT features & compute descriptors
3–4 Match descriptors with FLANN & apply Lowe’s ratio test
5–6 Extract matched keypoint coordinates & compute the 3Γ—3 homography
7 Warp the first image using warpPerspective()
8–9 Visualise the matched keypoints and the warped image

🌐 Geometric Transformations β€” The Big Picture

Any operation that changes position, shape, or orientation of pixels.

Transformation What It Does Matrix Size
Translation Move image left/right/up/down 2Γ—3
Rotation Rotate around a point 2Γ—3
Scaling Zoom in/out 2Γ—3
Affine Transform Preserve straight lines & parallelism 2Γ—3
Homography General 2D→2D transform (projective) 3×3

🐍 Code: Example of Affine Transformation

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load the image
image = cv2.imread('bird1.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # Convert to RGB for correct display in matplotlib

# Image dimensions
h, w = image.shape[:2]

# Define a 3Γ—3 affine transformation matrix in homogeneous coordinates
# This example applies: scale, shear, rotate a bit, and translate
affine_matrix_3x3 = np.array([
    [1.2, 0.2, 50],   # a little scale and shear + translation in x
    [-0.2, 1.1, 30],  # a little rotation and scale + translation in y
    [0, 0, 1]         # homogeneous row
], dtype=np.float32)

# Extract the 2Γ—3 part for cv2.warpAffine (since it expects 2x3)
affine_matrix_2x3 = affine_matrix_3x3[:2, :]

# Apply the affine transformation
transformed = cv2.warpAffine(image, affine_matrix_2x3, (w, h))

# Show the original and transformed image side-by-side
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("Original Image")
plt.imshow(image)
plt.axis('off')

plt.subplot(1, 2, 2)
plt.title("Affine Transformed Image")
plt.imshow(transformed)
plt.axis('off')

plt.tight_layout()
plt.show()

image

πŸ”– Homography β€” A Special Geometric Transformation

  • Most general planar transform
  • Models perspective (e.g. camera tilt)
  • Maps any 4 points in one plane to 4 points in another

Q&A

Question Answer
Is homography a geometric transformation? βœ… Yes β€” it’s a type of geometric transform
Are all geometric transforms homographies? ❌ No β€” simpler transforms (scaling, rotation) are not

Visual Example

  • Affine transforms cannot correct perspective distortion
  • Homographies straighten a tilted photo of a page, making it appear head-on

βœ… Summary

Term Definition
Geometric Transformation Any operation that repositions image pixels
Homography Most general 2D transform (represented by a 3Γ—3 matrix)
Use Cases Align images, correct perspective, stitch panoramas