简体   繁体   English

OpenCV、Python:在拼接图像时消除最终变窄

[英]OpenCV, Python: Eliminating eventual narrowing when stitching images

Thanks in large part to some great answers on stackoverflow ( here , here , and here ) I've been having some pretty good success in aligning images.很大程度上要感谢有关 stackoverflow 的一些出色答案( 此处此处此处),我在对齐图像方面取得了一些不错的成功。 There is one issue, though, as you can see below.但是,有一个问题,如下所示。 As I stitch many images together, they get smaller and smaller.当我将许多图像拼接在一起时,它们变得越来越小。

My theory on why this is going on is that the camera wasn't exactly perpendicular to the ground, so as I added more and more images the natural perspective in having a camera not perpendicular to the ground caused the far images to become smaller.我关于为什么会这样的理论是相机并不完全垂直于地面,所以随着我添加越来越多的图像,相机不垂直于地面的自然视角导致远图像变得更小。 This could very well be completely incorrect, though.不过,这很可能是完全不正确的。

However, even when I transform the first image so that it's "as if" it was taken perpendicular to the ground (I think) the distortion still occurs.然而,即使当我转换第一张图像使其“好像”垂直于地面拍摄时(我认为),失真仍然发生。

Does the brilliant stackoverflow community have any ideas on how I can remedy the situation?出色的 stackoverflow 社区是否对我如何补救这种情况有任何想法?

This is the process I use to stitch the images:这是我用来拼接图像的过程:

  1. Using knowledge of the corner lat/long points of images, warp such that the first image is perpendicular to ground.使用图像的角纬度/经度点的知识,扭曲使第一幅图像垂直于地面。 The homography I use to do this is the "base" homography我用来做这个的单应性是“基础”单应性
  2. Find common features between each image and the last one using goodFeaturesToTrack() and calcOpticalFlowPyrLK()使用goodFeaturesToTrack()calcOpticalFlowPyrLK()查找每张图像和最后一张图像之间的共同特征
  3. Use findHomography() to find the homography between the two images.使用findHomography()查找两个图像之间的单应性。 Then, compose that homography with all the previous homographies to to get the "net" homography然后,将该单应性与所有先前的单应性组合以得到“净”单应性
  4. Apply the transformation and overlay the image with the net result of what I've done so far.应用转换并用我到目前为止所做的最终结果覆盖图像。

There is one major constraint有一个主要限制

The mosaic must be constructed one image at a time, as the camera moves.随着相机的移动,马赛克必须一次构建一张图像。 I am trying to create a real-time map as a drone is flying, fitting each image with the last, one by one.我正在尝试在无人机飞行时创建实时地图,将每张图像与最后一张一张一张地拟合。

在此处输入图片说明

My theory on why this is going on is that the camera wasn't exactly perpendicular to the ground.我关于为什么会发生这种情况的理论是相机并不完全垂直于地面。

This is a good intuition.这是一个很好的直觉。 If the camera is angled, then as it moves towards an object, that object becomes larger in the frame.如果相机是有角度的,那么当它移向一个物体时,该物体在画面中会变大。 So if you're stitching that to the previous frame, the current frame needs to shrink to fit to the object in the previous frame.因此,如果您将其拼接到前一帧,则当前帧需要缩小以适应前一帧中的对象。

Full 3x3 homographies include distortions in the x and y directions, but 2x3 affine transformations do not.完整的3x3单应性包括xy方向的失真,但2x3仿射变换不包括。 To stick with your current pipeline, you can try finding an affine or Euclidean (rigid) transformation instead.为了坚持您当前的管道,您可以尝试找到仿射或欧几里得(刚性)变换。 The difference between them is an affine warp allows for shearing and stretching separately in the x and y directions, Euclidean transforms only do translation, rotation, and uniform scaling.它们之间的区别在于仿射扭曲允许在xy方向分别进行剪切和拉伸,欧几里德变换仅进行平移、旋转和均匀缩放。 Both preserve parallel lines, whereas a full homography does not, so you could end up with a square image becoming more trapezoidal, and repeating that will shrink your image.两者都保留平行线,而完整的单应性则不保留,因此您最终可能会得到一个方形图像变得更加梯形,并且重复这样做会缩小您的图像。 An affine warp can still shrink in just one direction, turning a square into a rectangle so it still might shrink.仿射扭曲仍然可以仅在一个方向上收缩,将正方形变成矩形,因此它仍然可能会收缩。 Euclidean transformations can only scale the whole square, so it still might shrink.欧几里得变换只能缩放整个正方形,所以它仍然可能缩小。

Of course, they won't be as perfect matches as findHomography either, but they should be able to get you to close matches without distorting the size as much.当然,它们也不会像findHomography那样完美匹配,但它们应该能够让您关闭匹配而不会过多地扭曲大小。 There are two options to find Euclidean or affine transformations with OpenCV:有两个选项可以使用 OpenCV 找到欧几里得或仿射变换:

  1. estimateRigidTransform() instead of warpPerspective() to get either a rigid warp with the parameter fullAffine=False or an affine warp with fullAffine=True . estimateRigidTransform()而不是warpPerspective()来获得参数fullAffine=False的刚性扭曲或fullAffine=True的仿射扭曲。

  2. findTransformECC() with optional parameter motionType=cv2.MOTION_EUCLIDEAN or motionType=cv2.MOTION_AFFINE (but affine is the default so it's not necessary to specify). findTransformECC()与可选参数motionType=cv2.MOTION_EUCLIDEANmotionType=cv2.MOTION_AFFINE (但仿射是默认值,因此无需指定)。

You can check out the difference between the algorithms on their documentation pages, or try both to see what works best for you.您可以在他们的文档页面上查看算法之间的差异,或者尝试两者以查看最适合您的算法。

If this doesn't work out as well, you can try estimating the homography which warps a frame to be completely perpendicular to the ground.如果这也不起作用,您可以尝试估计使框架完全垂直于地面的单应性。 If you do that, you can try applying it to all frames first , and then matching the images.如果你这样做,你可以试试它适用于所有的帧,然后匹配的图像。 Otherwise, you'll probably want to move to more advanced methods than finding just an homography between each frame.否则,您可能想要转向更高级的方法,而不仅仅是在每帧之间找到单应性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM