我正在与 OpenCV 3.0.0.dev 中使用的鱼眼相机模型进行斗争。我已经多次阅读了link中的文档,特别是“详细说明”部分以及模拟鱼眼失真的公式。到现在为止,我有两个问题:
亲切的问候,
马希赫
答案 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:
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。