OpenCV,Python:消除拼接图像时的最终变窄
OpenCV, Python: Eliminating eventual narrowing when stitching images
在很大程度上感谢 Whosebug (, , and ) 上的一些很好的答案,我在对齐图像方面取得了一些相当成功。但是,正如您在下面看到的那样,存在一个问题。当我将许多图像拼接在一起时,它们会变得越来越小。
我对为什么会这样的理论是相机不完全垂直于地面,所以当我添加越来越多的图像时,相机不垂直于地面的自然视角导致远图像变小。不过,这很可能是完全错误的。
然而,即使我将第一张图片转换为“好像”它是垂直于地面拍摄的(我认为),失真仍然发生。
优秀的 Whosebug 社区对我如何补救有什么想法吗?
这是我用来拼接图像的过程:
- 利用图像角 lat/long 点的知识,使第一张图像垂直于地面。我用来做这个的单应性是“基础”单应性
- 使用
goodFeaturesToTrack()
和 calcOpticalFlowPyrLK()
找出每张图像与最后一张图像之间的共同特征
- 使用
findHomography()
求出两幅图像之间的单应性。然后,将该单应性与所有先前的单应性组合为得到“净”单应性
- 应用转换并用我目前所做的最终结果覆盖图像。
有一个主要限制
随着相机的移动,马赛克必须一次构建一个图像。我正在尝试在无人机飞行时创建实时地图,将每张图像与最后一张图像一张一张地拟合。
My theory on why this is going on is that the camera wasn't exactly perpendicular to the ground.
这是一个很好的直觉。如果相机是倾斜的,那么当它向一个物体移动时,该物体在画面中会变大。因此,如果您将其拼接到前一帧,则当前帧需要缩小以适合前一帧中的对象。
完整 3x3
单应性包括 x
和 y
方向的扭曲,但 2x3
仿射变换不包括。要坚持使用当前的管道,您可以尝试寻找仿射或欧几里德(刚性)变换。它们之间的区别是仿射扭曲允许在 x
和 y
方向上分别进行剪切和拉伸,欧氏变换仅进行平移、旋转和均匀缩放。两者都保留平行线,而完全单应性则不保留,因此您最终可能会得到一个正方形图像变得更加梯形的图像,重复此操作会缩小您的图像。仿射扭曲仍然可以只在一个方向收缩,将正方形变成矩形,因此它仍然可能收缩。欧氏变换只能缩放整个正方形,因此它仍然可能会缩小。
当然,它们也不会像 findHomography
那样完美匹配,但它们应该能够让您在不扭曲大小的情况下结束匹配。使用 OpenCV 查找欧几里德或仿射变换有两种选择:
estimateRigidTransform()
而不是 warpPerspective()
以获得带有参数 fullAffine=False
的刚性扭曲或带有 fullAffine=True
的仿射扭曲。
findTransformECC()
带有可选参数 motionType=cv2.MOTION_EUCLIDEAN
或 motionType=cv2.MOTION_AFFINE
(但仿射是默认值,因此无需指定)。
您可以在它们的文档页面上查看这些算法之间的区别,或者尝试两种算法以查看最适合您的算法。
如果这也不奏效,您可以尝试估计使帧变形为完全垂直于地面的单应性。如果这样做,您可以先尝试将其应用于所有帧 ,然后匹配图像。否则,您可能想要转向更高级的方法,而不是仅在每帧之间找到单应性。
在很大程度上感谢 Whosebug (
我对为什么会这样的理论是相机不完全垂直于地面,所以当我添加越来越多的图像时,相机不垂直于地面的自然视角导致远图像变小。不过,这很可能是完全错误的。
然而,即使我将第一张图片转换为“好像”它是垂直于地面拍摄的(我认为),失真仍然发生。
优秀的 Whosebug 社区对我如何补救有什么想法吗?
这是我用来拼接图像的过程:
- 利用图像角 lat/long 点的知识,使第一张图像垂直于地面。我用来做这个的单应性是“基础”单应性
- 使用
goodFeaturesToTrack()
和calcOpticalFlowPyrLK()
找出每张图像与最后一张图像之间的共同特征
- 使用
findHomography()
求出两幅图像之间的单应性。然后,将该单应性与所有先前的单应性组合为得到“净”单应性 - 应用转换并用我目前所做的最终结果覆盖图像。
有一个主要限制
随着相机的移动,马赛克必须一次构建一个图像。我正在尝试在无人机飞行时创建实时地图,将每张图像与最后一张图像一张一张地拟合。
My theory on why this is going on is that the camera wasn't exactly perpendicular to the ground.
这是一个很好的直觉。如果相机是倾斜的,那么当它向一个物体移动时,该物体在画面中会变大。因此,如果您将其拼接到前一帧,则当前帧需要缩小以适合前一帧中的对象。
完整 3x3
单应性包括 x
和 y
方向的扭曲,但 2x3
仿射变换不包括。要坚持使用当前的管道,您可以尝试寻找仿射或欧几里德(刚性)变换。它们之间的区别是仿射扭曲允许在 x
和 y
方向上分别进行剪切和拉伸,欧氏变换仅进行平移、旋转和均匀缩放。两者都保留平行线,而完全单应性则不保留,因此您最终可能会得到一个正方形图像变得更加梯形的图像,重复此操作会缩小您的图像。仿射扭曲仍然可以只在一个方向收缩,将正方形变成矩形,因此它仍然可能收缩。欧氏变换只能缩放整个正方形,因此它仍然可能会缩小。
当然,它们也不会像 findHomography
那样完美匹配,但它们应该能够让您在不扭曲大小的情况下结束匹配。使用 OpenCV 查找欧几里德或仿射变换有两种选择:
estimateRigidTransform()
而不是warpPerspective()
以获得带有参数fullAffine=False
的刚性扭曲或带有fullAffine=True
的仿射扭曲。findTransformECC()
带有可选参数motionType=cv2.MOTION_EUCLIDEAN
或motionType=cv2.MOTION_AFFINE
(但仿射是默认值,因此无需指定)。
您可以在它们的文档页面上查看这些算法之间的区别,或者尝试两种算法以查看最适合您的算法。
如果这也不奏效,您可以尝试估计使帧变形为完全垂直于地面的单应性。如果这样做,您可以先尝试将其应用于所有帧 ,然后匹配图像。否则,您可能想要转向更高级的方法,而不是仅在每帧之间找到单应性。