python - Python校准相机

标签 python opencv camera camera-calibration camera-matrix

我有以下图像I1。我没有捕获它。我是从Google下载的

enter image description here

我将已知的单应性H应用于I1,以获得以下图像I2。

enter image description here

我想假设照相机已经拍摄了以上I2的照片。我不知道这台相机的相机矩阵,所以我想找到它。要找到此相机矩阵mtx,我使用了OpenCV相机校准方法:ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None,flags=cv2.CALIB_FIX_ASPECT_RATIO|cv2.CALIB_FIX_K1|cv2.CALIB_FIX_K2|cv2.CALIB_FIX_K3|cv2.CALIB_FIX_K4|cv2.CALIB_FIX_K5)
这是使用正方形完成的,它是真实世界和图像坐标。我选择图像I1中的一个正方形,并使用单应性H来获取I2中该正方形的对应角点。由于我知道I2中的这些对应点形成一个正方形,因此我应该能够从这些点获取相机矩阵。但是,当我在图像的不同位置拍摄相同的正方形时,会得到不同的相机矩阵。为什么是这样?我在做什么错,我该如何解决?如何计算正确的相机矩阵?

一个例子如下所示。对于这两个选定的正方形,我从mtx函数获得了不同的calibrateCamera值。

enter image description here
enter image description here

注意:上图中的红色点不是I1中完美正方形的角点。我刚刚对它们进行了粗略标记,以表达我的观点,即当我拍摄两个相同大小但在不同位置的正方形时,相机矩阵的值将不同。

最佳答案

这是一个好问题,涉及校准和计算几何的几个重要问题。我将提供一个深入的答案,希望我能弄清楚这些事情。

执行相机校准时,如果使用不同的对应关系重复校准,则可能会有三个固有矩阵的三个原因。

  • 的通信很吵。
  • 相机校准问题未确定。这意味着没有足够的对应信息来唯一地解析所有相机参数。
  • 相机校准使用不精确或过于严格的相机模型。

  • 原因1 应该很明显。如果对应关系因测量噪声而损坏,那么使用不同的对应关系集通常会获得不同的校准。这是因为在校准过程中,相机是一个优化过程,其相机参数被优化为最适合对应关系。当有噪音时,最佳配合可能会因测得的噪音而异。

    原因2如果尝试使用不足的信息进行校准,则会发生。例如,如果每个图像只有三个对应关系,则校准问题正在确定中。您可以通过计算参数来考虑这一点。三种对应关系在校准方程式上提供了6个约束(通过x和y位置,每个对应关系对应两个)。现在,当我们进行校准时,我们必须共同估算校准对象的姿态(每个图像具有6个自由度),再加上内在函数的未知数(焦距,主点,失真等)。因此,未知数多于约束,因此许多校准可以无限!因此,如果您选择了三种不同的对应关系集,则返回校准(如果一个返回了)将永远是不正确的,并且通常也不会是相同的。

    原因3 比较细微。为了解释这一点,请记住,可以通过指定具有不同数量的未知固有参数的摄像机来完成校准。在校准信息非常有限的情况下,最好减少未知数。例如,如果使用单个图像进行校准,则平面校准对象将为您在校准时为每个图像最多提供8个约束(因为单应性具有8个自由度)。要获得飞机的姿势需要6个约束,因此每个图像剩下2个约束。如果只有一张图像,则当未知数超过2个(例如焦距和镜头失真)时,您将无法进行校准。因此,如果我们想使用单个图像进行校准,则必须减少未知数。

    您的情况如何
    在您的情况下,您已将未知数减小为单焦距(f = fx = fy)和相机的主要点。那是3个未知数,但要记住,对单个图像进行校准意味着您最多只能有2个固有未知数。因此,您有一个约束不足的问题(请参见上面的原因2)。

    现在,您可能决定通过将主点固定到图像中心来克服此问题,这是很常见的事情,因为它通常是真实主点的良好近似值。现在,您有一个校准问题,其中有1个未知的固有(f)。重要的问题是,如果我们尝试使用单个图像和4个无噪音的对应关系来校准f,我们是否可以期望使用不同的对应关系集获得相同的值?您可能会认为是,但答案是否定的。

    原因是因为校准过程将解决一个过度约束的问题(8个约束和7个未知数)。通常,它将使用函数最小化过程来解决此问题(如OpenCV的calibrateCamera方法所做的那样)。在OpenCV中,这是通过最小化重新投影误差来完成的。解决方案将根据您提供的信件而有所不同。很难想象,因此请考虑一个不同的问题,在该问题中,您试图使一条直线与一条略微弯曲的线上的点拟合。直线是数据的过度简化模型。如果我们尝试通过对曲线上的两个点进行采样来拟合直线,则最佳拟合解决方案将根据采样的点而变化。

    在您的特定情况下,您可以通过使用恰好有2个未知数的内在矩阵,删除标记以固定宽高比以及将主点固定在图像中心来消除问题2和3。

    关于python - Python校准相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48240239/

    相关文章:

    python - 使用 numpy/scipy 的快速 b 样条算法

    c++ - 如何提供从一个图像构建的前景和背景模型到其他图像以执行 Grabcut?

    android - 具有接受 ='image/*;capture=camera' 选项的 android phonegap 应用程序不支持输入类型文件

    java - 在 Canvas 上绘制 LinearLayout View 消失

    javascript - 如何制作目标宽度和高度大于 640px 的高质量 PhoneGap 相机图像?

    Python OpenCV : How to convert YCbCr back to RGB?

    python - python 的 if 字符串中的子字符串的运行时

    python - TweetSentiments.com API Python 脚本

    xml - 如何在 XML 文件中的同一元素名称中写入多个 Mats?

    C#人脸识别