如何根据少数匹配点将两张图像叠加在一起绘制?

How can I plot two images on top of one another based on few point matches?

我有两张图片,很像下面的图片,还有一组匹配项 ((x_1, y_1), (x_2, y_2)),其中 (x_1, y_1) 是第一张图片上的一个点,(x_2, y_2) 是第二张图片上的一个点第二张图片。我想根据我拥有的点匹配将图像叠加在一起,以便每个匹配点直接位于彼此之上。图像可能不会以相同的角度定向,因此计算像素偏移和使用 PIL 的 paste() 函数将不起作用,至少在没有更多预处理的情况下是这样。在我的例子中,一张图片是彩色的,我可以让它更不透明以将它们绘制在彼此之上。

from PIL import Image

img1 = Image.open('Rutland.jpg')
img2 = Image.open('Rutland2.jpg')

# matching pixels across the two images
point_matches = [((1988, 1029), (2003, 1045)), ((4091, 3901), (4085, 3896))]

您的问题包括两个独立的阶段:

  1. 对齐
  2. 叠加绘制的图像。

让我们把#2 移开,因为使用 matplotlibpyplot.imshow 您可以将它们绘制在同一轴上并使用 alpha 输入控制 transparency/opacity,或者使用 cv2overlay 选项 -

import cv2

im1_ = im1.copy()
im2_ = im2.copy()
cv2.addWeighted(im1_, 0.5, im2_, 0.5, 0, im2_)
cv2.imshow("Overlay", output)

关于对齐(这是迄今为止更复杂的问题),您需要“处理”其中一张图像,使其与另一张图像最佳匹配。这可能是许多可选映射之一,例如平移、旋转、单应映射等。

首先要注意的一点是,就仅涉及轮班而言,您的比赛彼此并不一致。换句话说,如果我们只考虑 (\Delta{x},\Delta{y}) 全局偏移,那么第一个匹配估计偏移 (15, 16),而第二个匹配估计偏移 (-6, -5)。根据所需图像拟合的保真度,仅对这两个估计进行平均并相应地转换图像就足够了。
如果这还不够,那么您就隐含地假设正在进行一些更复杂的映射或扭曲,并且这些映射通常需要两个以上的点来估计它们的参数。 (我认为你可以用两个点做的最大是“相似性”,它包括平移、旋转和缩放的组合)。

更笼统地说,也许您想考虑使用 opencv 函数匹配它们,以查找关键点(例如通过 SIFT) and/or 以查找实际映射。请参阅 this example tutorial, although there are other, more direct methods that don't require going explicitly through keypoints. This 是使用 ECC(增强相关系数)的良好起点。

更具体地说,如果你有足够的点,你可以使用 cv2.findHomography 接受关键点列表作为输入。