使用OpenCV(Python)拼接多个图像

时间:2014-07-03 20:55:11

标签: opencv computer-vision image-stitching

您已经看过很多教程如何使用两张照片进行简单的图像拼接,这没有问题 但是当我想要制作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缝合到当前的全景图上。我将H_13 = H_12 * H_23并将图像3缝合到当前全景图像,但是在我的全景图像中我得到非常明显的间隙,当缝合下一个图像时,它的间隙更大,图像非常拉伸。这是我的代码http://pastebin.com/dQjhE5VD

任何人都可以告诉我,如果我使用正确的方法,或者有人发现错误或看到我做错了什么。

3 个答案:

答案 0 :(得分:12)

一步一步,假设你要缝合四个图像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将图像I0扭曲成I1等...
  2. 选择一个锚图像,例如I1哪个位置将保持不变,即H_1 =身份
  3. 根据最大数量找到更好地与I1对齐的图像 一致的匹配I3
  4. 更新H_3 = H_1 * inv(H_13)= inv(H_13)= H_31
  5. 找到更符合I1或I3的图像,例如I2匹配I3
  6. 更新H_2 = H_3 * H_23
  7. 与图像I0
  8. 相同
  9. 进行全局优化对齐的捆绑调整
  10. 请参阅此开篇论文Automatic Panoramic Image Stitching using Invariant Features的第4部分,以获得深入解释。

答案 1 :(得分:4)

Hacky方法

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

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是H,它将图像1转换为与图像0对齐。(根据它们的代码定义H的方式,您可能需要反转上面的乘法顺序。)因此,您将乘以获得H_0i然后使用它来转换图像i与图像0对齐。

有关为什么要将变换相乘的背景信息,请参阅:Transformations and Matrix Multiplication特别是"转换的组成"一部分。

答案 2 :(得分: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是下一个。

希望这有帮助。

相关问题