首页 > 解决方案 > 如何根据几个点匹配将两张图像叠加在一起?

问题描述

我有两个图像,很像下面的图像,还有一组匹配项((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))]

在此处输入图像描述

标签: pythonmatplotlibpython-imaging-library

解决方案


您的问题包括两个不同的阶段:

  1. 结盟
  2. 覆盖绘制的图像。

让我们把 #2 排除在外,因为使用matplotlib'spyplot.imshow你可以将它们绘制在同一轴上并使用alpha输入来控制透明度/不透明度,或者使用cv2'soverlay选项 -

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)和/或查找实际映射。请参阅本示例教程,尽管还有其他更直接的方法不需要显式通过关键点。是使用 ECC(增强相关系数)的一个很好的起点。

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


推荐阅读