OpenCV,Python:消除拼接图像时的最终变窄

OpenCV, Python: Eliminating eventual narrowing when stitching images

在很大程度上感谢 Whosebug (, , and ) 上的一些很好的答案,我在对齐图像方面取得了一些相当成功。但是,正如您在下面看到的那样,存在一个问题。当我将许多图像拼接在一起时,它们会变得越来越小。

我对为什么会这样的理论是相机不完全垂直于地面,所以当我添加越来越多的图像时,相机不垂直于地面的自然视角导致远图像变小。不过,这很可能是完全错误的。

然而,即使我将第一张图片转换为“好像”它是垂直于地面拍摄的(我认为),失真仍然发生。

优秀的 Whosebug 社区对我如何补救有什么想法吗?

这是我用来拼接图像的过程:

  1. 利用图像角 lat/long 点的知识,使第一张图像垂直于地面。我用来做这个的单应性是“基础”单应性
  2. 使用 goodFeaturesToTrack()calcOpticalFlowPyrLK()
  3. 找出每张图像与最后一张图像之间的共同特征
  4. 使用findHomography()求出两幅图像之间的单应性。然后,将该单应性与所有先前的单应性组合为得到“净”单应性
  5. 应用转换并用我目前所做的最终结果覆盖图像。

有一个主要限制

随着相机的移动,马赛克必须一次构建一个图像。我正在尝试在无人机飞行时创建实时地图,将每张图像与最后一张图像一张一张地拟合。

My theory on why this is going on is that the camera wasn't exactly perpendicular to the ground.

这是一个很好的直觉。如果相机是倾斜的,那么当它向一个物体移动时,该物体在画面中会变大。因此,如果您将其拼接到前一帧,则当前帧需要缩小以适合前一帧中的对象。

完整 3x3 单应性包括 xy 方向的扭曲,但 2x3 仿射变换不包括。要坚持使用当前的管道,您可以尝试寻找仿射或欧几里德(刚性)变换。它们之间的区别是仿射扭曲允许在 xy 方向上分别进行剪切和拉伸,欧氏变换仅进行平移、旋转和均匀缩放。两者都保留平行线,而完全单应性则不保留,因此您最终可能会得到一个正方形图像变得更加梯形的图像,重复此操作会缩小您的图像。仿射扭曲仍然可以只在一个方向收缩,将正方形变成矩形,因此它仍然可能收缩。欧氏变换只能缩放整个正方形,因此它仍然可能会缩小。

当然,它们也不会像 findHomography 那样完美匹配,但它们应该能够让您在不扭曲大小的情况下结束匹配。使用 OpenCV 查找欧几里德或仿射变换有两种选择:

  1. estimateRigidTransform() 而不是 warpPerspective() 以获得带有参数 fullAffine=False 的刚性扭曲或带有 fullAffine=True 的仿射扭曲。

  2. findTransformECC() 带有可选参数 motionType=cv2.MOTION_EUCLIDEANmotionType=cv2.MOTION_AFFINE(但仿射是默认值,因此无需指定)。

您可以在它们的文档页面上查看这些算法之间的区别,或者尝试两种算法以查看最适合您的算法。

如果这也不奏效,您可以尝试估计使帧变形为完全垂直于地面的单应性。如果这样做,您可以先尝试将其应用于所有帧 ,然后匹配图像。否则,您可能想要转向更高级的方法,而不是仅在每帧之间找到单应性。