特征匹配实战:SIFT/ORB 算法、图像拼接

📂 所属阶段:第一阶段 — 图像处理基石(传统 CV 篇)
🔗 相关章节:边缘检测与轮廓提取 · 从全连接到卷积


1. SIFT 特征

import cv2
import numpy as np

img = cv2.imread("photo.jpg")

# 创建 SIFT 检测器
sift = cv2.SIFT_create()

# 检测关键点和描述符
keypoints, descriptors = sift.detectAndCompute(img, None)

# 绘制关键点
img_with_kp = cv2.drawKeypoints(img, keypoints, None)

cv2.imshow("SIFT Keypoints", img_with_kp)
cv2.waitKey(0)

2. ORB 特征(轻量级)

import cv2

img = cv2.imread("photo.jpg")

# 创建 ORB 检测器
orb = cv2.ORB_create(nfeatures=500)

# 检测关键点和描述符
keypoints, descriptors = orb.detectAndCompute(img, None)

# 绘制关键点
img_with_kp = cv2.drawKeypoints(img, keypoints, None)

cv2.imshow("ORB Keypoints", img_with_kp)
cv2.waitKey(0)

3. 特征匹配

import cv2
import numpy as np

img1 = cv2.imread("photo1.jpg")
img2 = cv2.imread("photo2.jpg")

# 创建 SIFT 检测器
sift = cv2.SIFT_create()

# 检测关键点和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 特征匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)

# Lowe's ratio test
good_matches = []
for match_pair in matches:
    if len(match_pair) == 2:
        m, n = match_pair
        if m.distance < 0.75 * n.distance:
            good_matches.append(m)

# 绘制匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None)

cv2.imshow("Matches", img_matches)
cv2.waitKey(0)

4. 图像拼接

import cv2
import numpy as np

img1 = cv2.imread("photo1.jpg")
img2 = cv2.imread("photo2.jpg")

# 特征检测和匹配(省略代码)
# ...

# 计算单应矩阵
H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

# 图像配准
height, width = img2.shape[:2]
warped = cv2.warpPerspective(img1, H, (width + img1.shape[1], height))

# 拼接
result = warped.copy()
result[0:height, 0:width] = img2

cv2.imshow("Stitched", result)
cv2.waitKey(0)

5. 小结

特征匹配工作流:

1. 特征检测:SIFT(精准)或 ORB(快速)
2. 特征匹配:BFMatcher 或 FLANN
3. 几何验证:RANSAC 去除异常匹配
4. 应用:图像拼接、3D 重建、目标追踪

SIFT vs ORB:
- SIFT:精准但慢,有专利限制
- ORB:快速且免费,精度略低

💡 记住:特征匹配是 CV 中最重要的技术之一,广泛应用于图像拼接、3D 重建、目标追踪等。


🔗 扩展阅读