首页 文章

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

提问于
浏览
13

您已经看过很多教程如何使用两张照片进行简单的图像拼接,这没有问题 .
但是当我想要制作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 回答

  • 12

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

    • 计算所有成对单应性H_01,H_02,H_03,H_12,H_13,H_23,其中单应性H_01将图像I0变形为I1等...

    • 选择一个锚图像,例如I1哪个位置将保持不变,即H_1 =身份

    • 根据最大匹配数匹配查找更好地与I1对齐的图像,例如I3

    • 更新H_3 = H_1 * inv(H_13)= inv(H_13)= H_31

    • 找到更符合I1或I3的图像,例如I2与I3匹配

    • 更新H_2 = H_3 * H_23

    • 与图像I0相同

    • 进行捆绑调整以全局优化对齐

    有关深入解释,请参阅这篇开创性论文的第4部分Automatic Panoramic Image Stitching using Invariant Features .

  • 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具体为"Composition of tranformations"部分 .

  • 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是下一个 .

    希望这可以帮助 .

相关问题