python - 如何根据几个点匹配将两张图像叠加在一起?
问题描述
我有两个图像,很像下面的图像,还有一组匹配项((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
'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)
关于对齐(这是迄今为止更复杂的问题),您需要“处理”其中一张图像,使其与另一张图像最匹配。这可能是许多可选映射之一,例如平移、旋转、单应映射等。
首先要注意的是,就仅涉及轮班而言,您的匹配项彼此不一致。换句话说,如果我们只考虑全局偏移,那么第一个匹配估计偏移 (15, 16),而第二个匹配估计偏移 (-6, -5)。根据所需图像拟合的保真度,只需平均这两个估计值并相应地转换图像就足够了。
如果这还不够,那么您隐含地假设正在进行一些更复杂的映射或扭曲,并且这些映射通常需要两个以上的点来估计它们的参数。(我认为你可以用两点做的最大值是“相似性”,其中包括平移、旋转和缩放的组合)。
更一般地说,也许您想考虑使用opencv
函数来匹配它们,以查找关键点(例如通过 SIFT)和/或查找实际映射。请参阅本示例教程,尽管还有其他更直接的方法不需要显式通过关键点。这是使用 ECC(增强相关系数)的一个很好的起点。
更具体地说,如果您有足够的点,您可以使用cv2.findHomography
which 接受关键点列表作为输入。
推荐阅读
- mysql - 使用 if-then-else 触发(MYSQL)不起作用
- html-email - 电子邮件模板:暗模式
- python - 比较 >= 列,然后根据比较删除另一列,减 1 并执行直到满足条件
- c++ - 与 stdio 同步会使程序 i/o 非交互式?
- graphql - GraphQL 查询合并
- excel - 循环浏览可见工作表
- python - 带有可选参数的 Python argparse 自定义操作
- rabbitmq - 添加 Volo.Abp.EventBus.RabbitMQ 包时运行 asp.net 样板应用程序时出错
- php - PHP 7.3 - Laravel 7 - 有没有办法伪造运行一个函数,确保它不会出错,然后才真正运行它?
- javascript - Javascript-制作一个自定义命名的变量