19

嗨,已经看过很多教程如何使用两张照片进行简单的图像拼接,这没问题。
但是,当我想从 4-6 张或更多图像中制作全景图时该怎么办?

我有接收图像文件列表的代码(图像按顺序从序列中的第一个图像到最后一个图像)。然后对于每个图像,我计算 SIFT 特征描述符。但是后来我被卡住了,对于两个图像,我会使用 FLANN kd-tree 设置一个匹配器并找到图像之间的匹配并计算 Homography。类似于本教程http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html#py-feature-homography

但我没有在最后显示特征点之间的线条,而是使用此https://stackoverflow.com/a/20355545/622194函数从 2 张图像制作全景图。但是当我想将第三张和第四张图像添加到全景图时,我不确定该怎么做。

编辑:

从答案中,我尝试实现我的图像拼接脚本来计算图像序列中彼此相邻的图像之间的单应矩阵。所以如果我有 I1 I2 I3 和 I4 我现在有 H_12、H_23 和 H_34。然后我开始使用 H_12 缝合 I1 和 I2。然后我想找到累积单应性将 I3 拼接到当前全景图。我 fing H_13 = H_12*H_23 并将图像 3 缝合到当前全景图,但在这里我的全景图像中有非常明显的间隙,当缝合下一张图像时,间隙更大,图像非常拉伸。

谁能告诉我我是否为此使用了正确的方法,或者有人可以发现错误或查看我做错了什么。

4

3 回答 3

16

一步一步,假设你要拼接四个图像I0, I1, I2, I3, 你的目标是计算单应性H_0, H_1, H_2, H_3;

  1. 计算所有成对的单应性H_01, H_02, H_03, H_12, H_13,H_23其中单应性将H_01图像扭曲I0I1, 等等...
  2. 选择一个锚图像,例如I1哪个位置将保持固定,即H_1= 身份
  3. I1根据最大一致匹配数找到更好地对齐的图像,例如I3
  4. 更新H_3= H_1 * inv(H_13)= inv(H_13)=H_31
  5. 找到更好匹配或匹配I1I3图像I2I3
  6. 更新H_2= H_3*H_23
  7. 与上面的图像相同I0
  8. 进行捆绑调整以全局优化对齐

请参阅这篇开创性论文Automatic Panoramic Image Stitching using Invariant Features的第 4 节,以获得深入的解释。

于 2014-07-03T23:13:35.030 回答
5

黑客方法

给定您编写的功能,最简单的方法(尽管不是超级有效)是通过将全景图像与每个连续图像拼接来增加全景图像。像这样的伪代码:

panorama = images[0]
for i in 1:len(images)-1
    panorama = stitch(panorama,images[i])

这种方法基本上试图将下一张图像与当前全景图的任何部分进行匹配。假设每张新图像都在当前全景图的边界上,并且没有太多的透视失真,它应该工作得很好。

数学方法

如果您知道要拼接的顺序,另一种选择是从一个图像到下一个图像中找到 Homography,然后将它们相乘。结果是从该图像到图像 0 的 Homography。

例如:将图像 3 转换为与图像 0 对齐的 H 为 H_03 = H_01 * H_12 * H_23。其中 H_01 是将图像 1 转换为与图像 0 对齐的 H。(根据他们的代码定义 H 的方式,您可能需要颠倒上述乘法顺序。)因此,您将相乘以获得 H_0i,然后使用它来转换图像 i 与图像 0 对齐。

有关为什么要乘以变换的背景,请参阅:变换和矩阵乘法,特别是“变换的组合”部分。

于 2014-07-03T22:48:43.857 回答
1

我在图像之间的间隙方面遇到了类似的问题。您应该做的第一件事是在第一帧将累积的单应矩阵初始化为同一性。然后,对于每个新帧,您应该将其乘以当前帧和下一帧之间的单应矩阵。请注意使用 numpy 矩阵而不是 numpy 数组。IDK 为什么,但他们有不同的乘法例程。

这是我的代码:

def addFramePair(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):        
    (imageA, imageB) = images
    (kpsA, featuresA) = self.detectAndDescribe(imageA)
    (kpsB, featuresB) = self.detectAndDescribe(imageB)

    H = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
    self.accHomography *= np.asmatrix(H)
    result = cv2.warpPerspective(imageA, np.linalg.inv(self.accHomography), (1600, 900))
    return result

imageA 是当前的,imageB 是下一个。

希望这可以帮助。

于 2017-07-07T14:43:24.777 回答