如何根据少数匹配点将两张图像叠加在一起绘制?
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))]
您的问题包括两个独立的阶段:
- 对齐
- 叠加绘制的图像。
让我们把#2 移开,因为使用 matplotlib
的 pyplot.imshow
您可以将它们绘制在同一轴上并使用 alpha
输入控制 transparency/opacity,或者使用 cv2
的 overlay
选项 -
import cv2
im1_ = im1.copy()
im2_ = im2.copy()
cv2.addWeighted(im1_, 0.5, im2_, 0.5, 0, im2_)
cv2.imshow("Overlay", output)
关于对齐(这是迄今为止更复杂的问题),您需要“处理”其中一张图像,使其与另一张图像最佳匹配。这可能是许多可选映射之一,例如平移、旋转、单应映射等。
首先要注意的一点是,就仅涉及轮班而言,您的比赛彼此并不一致。换句话说,如果我们只考虑
全局偏移,那么第一个匹配估计偏移 (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
接受关键点列表作为输入。
我有两张图片,很像下面的图片,还有一组匹配项 ((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))]
您的问题包括两个独立的阶段:
- 对齐
- 叠加绘制的图像。
让我们把#2 移开,因为使用 matplotlib
的 pyplot.imshow
您可以将它们绘制在同一轴上并使用 alpha
输入控制 transparency/opacity,或者使用 cv2
的 overlay
选项 -
import cv2
im1_ = im1.copy()
im2_ = im2.copy()
cv2.addWeighted(im1_, 0.5, im2_, 0.5, 0, im2_)
cv2.imshow("Overlay", output)
关于对齐(这是迄今为止更复杂的问题),您需要“处理”其中一张图像,使其与另一张图像最佳匹配。这可能是许多可选映射之一,例如平移、旋转、单应映射等。
首先要注意的一点是,就仅涉及轮班而言,您的比赛彼此并不一致。换句话说,如果我们只考虑 全局偏移,那么第一个匹配估计偏移 (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
接受关键点列表作为输入。