【问题标题】:What is the best camera calibration method?最好的相机校准方法是什么?
【发布时间】:2015-01-31 03:31:17
【问题描述】:

我知道上述问题是广泛而模糊的。 但要放在上下文中: 我正在尝试确定相机的姿势和位置估计的准确性。我花了数周时间校准和尝试不同的方法和不同尺寸的电路板、照明、距离等。

我尝试过的方法:

说明:

  • 每张照片使用大约 20 张不同方向和位置的图像,在相机前拍摄
  • 适用于尺寸为 25mm、32mm 和 50mm 的 9x6 棋盘
  • 在 1280x720 和 1920x1080 两种分辨率下
  • 小板的距离在 500 毫米到大板的 2000 毫米之间

在所有情况下,我都遵循此链接How to verify the correctness of calibration of a webcam?的严格准则

在上述因素的所有组合中,我得到的结果相差几毫米(+- 15 毫米) 对于上述方法,我对 1280x720 的 25mm 块的内在函数范围如下:

  • OpenCV 的内置校准方法 > fx = 1269.4 fy = 1269.49 cx = 639.5 cy = 359.5
  • Matlab 校准工具箱 > fx = 1259.53 fy = 1260.76 cx = 661.3 cy = 306.5
  • Matlab标定App > fx = 1255.1 fy = 1254.8 cx = 652.6 cy = 340.7
  • 手动调整值。 > 各种结果,除 cx = 639.5 cy = 359.5 外均不稳定

情况不应该如此。在处理 1 米以下的距离时,相机相对于电路板原点的位置应该精确到平均一毫米或两毫米,如果不是亚毫米精度的话。除非我弄错了?

我的问题是,对于高清网络摄像头,什么是理想、简单且失真小的校准方法?

【问题讨论】:

  • openCVs和Matlabs的标定方法是一样的,据我所知...
  • 我不确定如何解释您的声明 "In all cases I have followed strict guidelines as per ..." - 因为如果我点击链接,在 #4 下我会读到:“进行大量测量和图片。你想要数百个每张图像的测量值(角)和数十张图像。就数据而言,越多越好。10x10 棋盘格是我会考虑的绝对最小值。我通常以 20x20 工作。" - 但你使用的是9x6 板?
  • 这是真的。我的项目是确定距离约为 3 米的精度。使用较小的块变得更难检测,并且使用 10x10 在检测 180 度旋转时会出现错误。我还阅读了一些资源(其中一个在 stackoverflow 中并且找不到),说明没有必要拥有这么多图像。我发现我的重投影误差随着图像的增加而增加。拒绝高错误图像后,我剩下 20 张图像。

标签: matlab opencv computer-vision camera-calibration matlab-cvst


【解决方案1】:

参加这个聚会有点晚了,但如果能帮上忙……

考虑到这三个应用程序虽然主要依赖于相同的算法(对于 OpenCV 和 Matlab 工具包,甚至共享一位作者),但这些差异并不那么令人惊讶,但它们具有不同的实现,具有不同的性能。如果您有兴趣进行公平比较,您至少应该使用相同的测量集(即检测到的角点的位置,使用亚像素细化)来驱动它们,以便输出的任何差异纯粹是由于实现。已经正确指出,通过使用不同的图像格式,您实际上是在使用不同的测量集。

您在主点上观察到的变化也不足为奇:很难准确估计它,因为

  • 重投影误差对其位置不是很敏感,即您尝试优化的成本函数在 (cx, cy) 子空间中大部分是“平坦”的(请参阅this paper 中的深入讨论) , 和
  • 它本质上与非线性失真的中心以及平行于世界到相机转换的图像平面的分量混淆。

后一点意味着主点中难以检测的小变化将导致显着的 3D 位置误差除非添加额外的约束,这会使受约束的误差函数在数量上不平坦感兴趣的,即相机相对于校准装置的绝对位置和方向。

方便添加的约束是:

  • 校准目标和相机的相对运动的先验模型。例如,如果您的棋盘目标连接到转盘,您可以针对其运动的中心和轴(3 + 2 个参数)进行优化,而不是针对各个目标位置的姿势使用 6 x num_images 参数。
  • 相对于非平面固定装备(或与装备相关的点和方向,如上所述)的多个摄像机位置。

【讨论】:

    【解决方案2】:

    有许多可能的错误来源。

    首先,虽然您尝试过的所有三种校准实现都使用基本相同的算法,但存在足够的差异来解释结果的差异。

    主要区别在于棋盘角检测。 Caltech Calibration Toolbox 没有自动棋盘检测,并使用第二次优化通道来细化角落。 OpenCV 和 Camera Calibrator App 都会自动检测棋盘格,但 Camera Calibrator App 中使用的算法要好得多。它更健壮,这意味着它很可能在 OpenCV 没有检测到电路板的情况下检测到电路板,并且它的亚像素定位更精确。我的观点是,在这三种方法中,您使用不同的数据点进行校准。因此,您的结果不同也就不足为奇了。

    校准后,您会遇到什么样的重投影错误? Camera Calibrator App 向您显示重投影误差的条形图。您应该查看它,并排除给您带来高错误的图像。理想情况下,您希望平均重投影误差小于半像素。越低越好。

    现在我要问你如何测量从相机到棋盘的距离?您从校准中获得的外部参数表示从棋盘坐标系到相机坐标系的转换,其原点位于相机外壳内部的光学中心。这很难准确测量。更好的方法是place a flat object of a known size on the checkerboard and measure it using the camera。事实上,您可以测量检测到的棋盘角之间的距离。请注意,检测精度是另一个误差来源。

    另外,请务必不要将校准图像保存为 jpeg。压缩伪影会影响棋盘角检测的准确性。使用无损格式,如 tiff 或 png。

    【讨论】:

    • 感谢您的回答。我知道结果会有所不同,只是希望它们更相似。对于 matlab App 和 Caltec 的工具箱,我得到低于 0.199 的重投影误差。两者都是在拒绝高错误图像之后。
    • 您的 jpeg 信息很有趣。我将 jpeg 用于 caltec 的工具箱,但将 png 用于 OpenCV 和 Matlab 的应用程序。我会尝试 tiff 并得到结果。
    • 0.199 听起来不错...您的 +/- 15 毫米误差呢?你是怎么衡量的?
    • 绝对不要在采集过程中的任何时候使用 jpeg。显然,如果您将 jpeg 图像转换为 png,您仍然会有伪像。
    • 我可以确认以下几点:在 Matlab 工具箱中使用 PNG 或 TIFF 而不是 JPG,精度降低了约 3mm。正如你所说,“......相机的坐标系,其原点在相机外壳内......”这给了我正确的结果。 300mm 和 1500mm 之间的各种测试给了我不超过约 3mm 的精度(用卷尺)。此外,最重要的是,棋盘格尺寸是用卡尺测量的,卡尺也起飞了大约 5 毫米,即使认为它只是从 25 毫米到 25.3 毫米,这是有道理的。非常感谢您对迪玛的帮助。
    猜你喜欢
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2021-03-09
    • 2015-09-24
    • 2013-01-28
    • 2014-10-23
    • 2013-11-02
    相关资源
    最近更新 更多