【问题标题】:camera calibration and Bird's Eye Projection in OpenCVOpenCV中的相机校准和鸟瞰投影
【发布时间】:2026-01-09 13:35:01
【问题描述】:

我已经完成了相机校准。现在我想获得棋盘图片的鸟瞰图。如下所示。但结果很奇怪,它看起来不是一个正方形。你可以看到 pic3。每个正方形都是 7.95x7.95。 smoebody 知道为什么吗?

gpsPoints[0] = Point2f(..., ...);
gpsPoints[1] = Point2f(..., ...);
gpsPoints[2] = Point2f(..., ...);
gpsPoints[3] = Point2f(..., ...);

dst[0] = Point2f(..., ...);
dst[1] = Point2f(..., ...);
dst[2] = Point2f(..., ...);
dst[3] = Point2f(..., ...);
Mat transmtx = getPerspectiveTransform(gpsPoints, dst);
warpPerspective(img, frame, transmtx, img.size());

【问题讨论】:

  • 可能是您的图像中的镜头失真或不完美的平面度。
  • 在您的输入图像中,不同的正方形上没有直线?
  • @Micka 将其作为答案:)

标签: c++ opencv camera


【解决方案1】:

一般来说,单应性会将直线转换为直线。

由于您只提供了 4 个角,因此透视变换是唯一定义的。因此,如果您确实选择了正确的 4 个角,但在图案中的某个位置存在错误的结构,那么这些结构在输入图像中一定是错误的。

在您的场景中,这可能是由于镜头畸变导致的,因此现实中的直线在(输入)图像中不会作为直线可见。或者输入图像中的线条在现实世界中不是直的,例如,您的图案基础不是完全平面的,或者您的图案没有很好地粘在平面上。

在 GIMP 中,我为您的图像添加了一些标记。

轮廓(绿点)是从一个角到下一个角的单条直线。如您所见,它们很好地位于图案基底的边界上,这表明您的图像中没有太多的镜头失真。

另一方面,顶部的红线由单条线段组成,始终连接两个相邻的角。如您所见,第 2 条和第 3 条线段有明显的“弯曲”,因此整个图案上没有直线。 底部的红线(细线)是从图案一侧到另一侧的直线,正如您所看到的,有些地方白色像素位于线条的两侧。所以你的图案在图像中看起来并不直。

我猜你的图案制作得不好,但这只是一个猜测,最后也可能是一些奇怪的镜头行为。您可以从不同的视图(如果可能的话,使用相同的相机焦点等)捕获相同模式的图像,以进一步分析。

如 user3896254 (thx) 所述,不同的错误可能会被透视扭曲放大。测量(或手动标记)错误(即使是亚像素精度)可能是另一个问题。

【讨论】:

  • 我可以补充一点,由不完美(非平坦)图案和由镜头引起的轻微(或不)失真引起的轻微缺陷在通过单应性翘曲后被强烈放大。在校准过程中,您应该始终牢记这一点。此外,点配准过程中的透视失真越大(例如从锐角捕获标记),相对测量误差就会越大,这会降低您的传输估计