什么是图像对齐

图像对齐(image alignment)又称图像配准(image registration),是一种通过单独变换一张图像或同时两张图像使两张图像上对应的特征点重合的方法。

如何实现图像对齐

  1. 寻找两张图像上的对应点;
  2. 基于对应点得到两张图像之间的单应性矩阵(homography)。

基于 OpenCV Python 的具体实现

import cv2
import matplotlib.pyplot as plt

img1 = cv2.imread('img1.jpg')
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
img2 = cv2.imread('img2.jpg')
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)

plt.figure()
fig, axes = plt.subplots(1, 2)
axes[0].imshow(img1)
axes[0].set_axis_off()
axes[1].imshow(img2)
axes[1].set_axis_off()
fig.tight_layout()

使用ORB检测图像中的特征点,特征点的数量设置为500。

MAX_FEATURES = 500

orb = cv2.ORB_create(MAX_FEATURES)
keypoints1, descriptors1 = orb.detectAndCompute(img1, None)
keypoints2, descriptors2 = orb.detectAndCompute(img2, None)
matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)

image-alignment-basic-introduction-1

根据特征点的匹配度,保留一部分较好的特征点,保留的比例为0.1。

GOOD_MATCH_PERCENT = 0.1

matches = list(matcher.match(descriptors1, descriptors2, None))
matches.sort(key=lambda x: x.distance, reverse=False)
matches = matches[:int(len(matches) * GOOD_MATCH_PERCENT)]

matches_img = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches, None)
plt.figure()
plt.axis('off')
plt.imshow(matches_img)

image-alignment-basic-introduction-2

基于保留的特征点,找出用于图像变换的单应性矩阵。

import numpy as np

points1 = np.zeros((len(matches), 2), dtype=np.float32)
points2 = np.zeros((len(matches), 2), dtype=np.float32)
for i, match in enumerate(matches):
    points1[i, :] = keypoints1[match.queryIdx].pt
    points2[i, :] = keypoints2[match.trainIdx].pt
homography, mask = cv2.findHomography(points1, points2, cv2.RANSAC)
height, width, channels = img2.shape
result_img = cv2.warpPerspective(img1, homography, (width, height))

plt.figure()
plt.axis('off')
plt.imshow(result_img)

image-alignment-basic-introduction-3

参考资料

Feature Based Image Alignment using OpenCV (C++/Python)