OpenCV3.0.0dev中鱼眼摄像机模型的主要参考是什么?

时间:2015-06-27 13:20:54

标签: c++ opencv camera-calibration opencv3.0 fisheye

我正在与 OpenCV 3.0.0.dev 中使用的鱼眼相机模型进行斗争。我已经多次阅读了link中的文档,特别是“详细说明”部分以及模拟鱼眼失真的公式。到现在为止,我有两个问题:

  1. 基于列出here的投影模型及其在“鱼眼镜头模型的准确性”中的概念解释,Hughes,我无法弄清楚哪个投影模型已在OpenCV实施中使用。
  2. 由于描述非常简洁,我需要知道OpenCV开发人员用于实现鱼眼名称空间的主要参考文件,这样我才能掌握并了解更多细节。 附:我检查了OpenCV 3.0.0-dev文档,但没有找到任何有用的东西 感谢大家的帮助,
  3. 亲切的问候,

    马希赫

3 个答案:

答案 0 :(得分:17)

简答:

OpenCV 3.0.0鱼眼摄像机模型不使用Brown模型,也不使用OP从Panotools引用的任何模型,它使用Juho Kannala和Sami S. Brandt的通用相机模型。

详细答案:

正如 Cfr 指出,来自Ilya Krylov(在OpenCV中实施了鱼眼模型)的this comment说他们移植了相机校准工具箱for Matlab Jean-Yves Bouguet:

Snapshot of the comment

Jean-Yves Bouguet网站(link)反过来提到了论文A Generic Camera Model and Calibration Method for Conventional, Wide-Angle, and Fish-Eye Lenses,并说:

  

校准工具箱中包含的“未记录的”鱼眼模型遵循这篇非常好的论文中等式(3)所描述的等距投影模型。失真模型遵循等式(6),除了k1 = 1(否则与f无法区分)。

在我看来,这是一种误导性陈述或明显的误解,因为等式(3)和等式(6)对应于不同的模型:等式(6)是本文介绍的实际模型,作者称之为通用相机型号(因此是纸张的名称)。 更确切地说,等式(6)用作相机模型,等式(8)和(9)用作“失真”或偏离该模型。

但是奥德赛还没有结束。 OpenCV的实现(根据其documentation)首先计算针孔投影以找到视场角(3D点,投影中心和光轴之间的角度)。 这意味着您无法使用鱼眼模型将光线投射到90º(或者您将除以0)或接近90º(数值稳定性问题,如溢出可能发生如果z足够小)。 此外,我不确定它是否适用于超过90º的光线。 所有这些让我真的很想知道他们的鱼眼镜头模型对于鱼眼镜头或广角镜头的“实用性”。

如果您对此持怀疑态度,可以查看OpenCV的源代码,具体在sources\modules\calib3d\src\fisheye.cpp(我添加了一些评论)

void cv::fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray _rvec,
InputArray _tvec, InputArray _K, InputArray _D, double alpha, OutputArray jacobian)
{
    ...
    Rodrigues(om, R, dRdom);
    Affine3d aff(om, T);
    ...
    Vec3d Xi = objectPoints.depth() == CV_32F ? (Vec3d)Xf[i] : Xd[i];
    Vec3d Y = aff*Xi; /* To transform to camera reference frame*/

    Vec2d x(Y[0]/Y[2], Y[1]/Y[2]); /* <- The root of all evil (division by z) */

    double r2 = x.dot(x);
    double r = std::sqrt(r2);

    // Angle of the incoming ray:
    double theta = atan(r);

    double theta2 = theta*theta, theta3 = theta2*theta, theta4 = theta2*theta2, theta5 = theta4*theta,
            theta6 = theta3*theta3, theta7 = theta6*theta, theta8 = theta4*theta4, theta9 = theta8*theta;

    double theta_d = theta + k[0]*theta3 + k[1]*theta5 + k[2]*theta7 + k[3]*theta9;

    double inv_r = r > 1e-8 ? 1.0/r : 1;
    double cdist = r > 1e-8 ? theta_d * inv_r : 1;

    Vec2d xd1 = x * cdist;
    Vec2d xd3(xd1[0] + alpha*xd1[1], xd1[1]);
    Vec2d final_point(xd3[0] * f[0] + c[0], xd3[1] * f[1] + c[1]);
    ...
}

更新This拉取请求修复角度≥90º的光线问题。截至2018年4月,它还没有被合并为主人,但正在考虑使用OpenCV 4.x Calibration Module(同时检查calibration module discussion

答案 1 :(得分:2)

经过几个小时的阅读,我发现OpenCV的鱼眼文献中的公式θ= atan(r)是与针孔投影有关的r = f *tanθ的归一化逆,因此,没有任何鱼眼投影上述链接中提到的模型用于OpenCV。

另外,关于失真模型,我猜测的是Fitzgibbon的分部模型在其2001年的论文“多视图几何和透镜畸变的同时线性估计”中被使用。根据Hughes在2008年的论文“鱼眼相机几何失真补偿的回顾”中,其他选择包括“奇数多项式模型”和“多项式鱼眼变换”。在他的论文中,在第2页中,他写道:

(1)(指奇数多项式模型)和(3)(指除法模型< / strong>,我猜这是OpenCV使用的那个)可用于描述标准非鱼眼镜头的失真。但是,一般认为这些多项式模型不足以描述鱼类引入的失真水平 - Shah和Aggarwal在[9]中展示了(具有失真模型和精度估计的高失真鱼眼镜头相机的固有参数校准程序)即使使用第7个订单版本(1)模拟鱼眼径向畸变,相当大的扭曲仍然,只要他们必须使用具有更大自由度的模型。因此,使用奇数和偶数系数(而不是简单的一个或另一个)的多项式可用于模拟引入的径向失真通过鱼眼镜头“

毕竟,我得出结论,OpenCV中的鱼眼模型的适用性非常有限,并且在失真模型和投影模型方面可以更加强化。我想再次强调,我仍然需要知道OpenCV开发人员使用哪些文件来实现鱼眼命名空间。

我非常感谢任何人对此的评论。

答案 2 :(得分:0)

Brown-Conrady model引用中提到Camera Calibration Toolbox for Matlab。本文讨论:D. C. Brown "Close-Range Camera Calibration"

此外,当前的OpenCV模型似乎忽略了切向失真(P(r))。

请参阅此comment