Panorama Creation, Homography Estimation, and Feature Matching
Module: Computer Vision | Difficulty: Premium
Homography Matrix
Maps points between two planes:
with 8 degrees of freedom (up to scale).
Direct Linear Transform (DLT)
For each correspondence :
RANSAC Algorithm
Repeat times:
- Sample 4 random correspondences
- Compute via DLT
- Count inliers where
- Keep best model
where = confidence, = inlier ratio, = 4.
Multi-Band Blending (Laplacian Pyramid)
| Method | Accuracy | Speed | Robustness |
|---|---|---|---|
| APAP | High | Medium | High |
| AutoStitch | High | Fast | Medium |
| SeamCut | High | Slow | Very High |
| StitchFormer | Very High | Fast | Very High |
import cv2
import numpy as np
def find_matches(img1, img2, n_features=5000):
sift = cv2.SIFT_create(nfeatures=n_features)
kp1, des1 = sift.detectAndCompute(
cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY), None)
kp2, des2 = sift.detectAndCompute(
cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY), None)
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = [m for m, n in matches if m.distance < 0.75 * n.distance]
pts1 = np.float32([kp1[m.queryIdx].pt for m in good])
pts2 = np.float32([kp2[m.trainIdx].pt for m in good])
return pts1, pts2, good
def compute_homography_ransac(pts1, pts2, threshold=5.0, max_iters=2000):
best_H = None
best_inliers = 0
n = len(pts1)
for _ in range(max_iters):
idx = np.random.choice(n, 4, replace=False)
H, _ = cv2.findHomography(pts1[idx], pts2[idx])
if H is None:
continue
pts1_h = np.hstack([pts1, np.ones((n, 1))])
projected = (H @ pts1_h.T).T
projected = projected[:, :2] / projected[:, 2:3]
errors = np.linalg.norm(projected - pts2, axis=1)
inliers = (errors < threshold).sum()
if inliers > best_inliers:
best_inliers = inliers
best_H = H
return best_H
def stitch_images(img1, img2, H):
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
result = cv2.warpPerspective(img2, H, (w1 + w2, max(h1, h2)))
result[:h1, :w1] = img1
return result
Research Insight: Traditional stitching pipelines (detect, match, estimate, blend) are being replaced by learned approaches like StitchFormer, which jointly optimize feature extraction and alignment. The key challenge in multi-image stitching is drift accumulation from sequential pairwise homography estimation. Global bundle adjustment minimizes the reprojection error across all images simultaneously, producing geometrically consistent panoramas. Multi-band blending avoids seams by fusing images at different spatial frequencies.