OpenCV3.0.0dev中鱼眼摄像机模型的主要参考是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV3.0.0dev中鱼眼摄像机模型的主要参考是什么?相关的知识,希望对你有一定的参考价值。
我正在与OpenCV 3.0.0.dev中使用的鱼眼相机模型搏斗。我已经多次阅读了这个link中的文档,特别是“详细描述”部分和模拟鱼眼失真的公式。到现在为止,我有两个问题:
- 基于here列出的投影模型及其在“鱼眼镜头模型的准确性”中的概念解释,Hughes,我无法弄清楚在OpenCV实现中使用了哪种投影模型。
- 由于描述非常简洁,我需要了解OpenCV开发人员用于实现鱼眼命名空间的主要参考文件,以便我能够掌控并了解更多细节。附:我检查了OpenCV 3.0.0-dev文档,但没有找到任何有用的东西。
Short answer:
OpenCV 3.0.0 Fisheye相机型号不使用Brown型号,也不使用OP从Panotools引用的任何型号,它使用Juho Kannala和Sami S. Brandt的Generic Camera Model。
Detailed answer:
正如Cfr在他的回答中指出的那样,来自Ilya Krylov的this comment(他在OpenCV中实施了鱼眼模型)说他们为Jean-Yves Bouguet的Matlab移植了相机校准工具箱:
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)
经过几个小时的阅读,我发现OpenCV的鱼眼文献中的公式θ= atan(r)是与针孔投影有关的r = f *tanθ的归一化逆,因此,没有提到的鱼眼投影模型以上链接用于OpenCV。
另外,关于失真模型,我猜想使用Fitzgibbon的分部模型在2001年的论文“多视图几何和透镜畸变的同时线性估计”中。根据Hughes在2008年的论文“鱼眼相机几何失真补偿的回顾”中,其他选择包括“奇数多项式模型”和“多项式鱼眼变换”。在他的论文中,在第2页中,他写道:
“(1)(指奇数多项式模型)和(3)(指的是分裂模型,我猜是OpenCV使用的模型)可以用来描述标准非鱼眼镜头的失真。但是,它通常认为这些多项式模型不足以描述鱼眼镜头引入的失真程度.Shah和Aggarwal在[9]中已经证明了(具有失真模型的高失真鱼眼镜头相机的固有参数校准程序)准确度估计)即使使用(1)的7阶版本来模拟鱼眼径向畸变,仍然存在相当大的失真,只要它们必须使用具有更大自由度的模型。因此,使用两者的多项式奇数和偶数系数(而不是简单的一个或另一个)可用于模拟由鱼眼镜头引入的径向畸变“
毕竟,我得出结论,OpenCV中的鱼眼模型的适用性非常有限,并且在失真模型和投影模型方面可以更加强化。我想再次强调,我仍然需要知道OpenCV开发人员使用哪些文件来实现fisheye命名空间。
我非常感谢任何人对此的评论。
根据Bouguet的calib_tool代码“project_points_fisheye.m”
%Definitions:
%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
%The coordinate vector of P in the camera reference frame is: Xc = R*X + T
%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3);
%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z.
%call r^2 = a^2 + b^2,
%call theta = atan(r),
%Fisheye distortion -> theta_d = theta * (1 + k(1)*theta^2 + k(2)*theta^4 + k(3)*theta^6 + k(4)*theta^8)
%
%The distorted point coordinates are: xd = [xx;yy] where:
%
%xx = (theta_d / r) * x
%yy = (theta_d / r) * y
%
%Finally, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where:
%
%xxp = f(1)*(xx + alpha*yy) + c(1)
%yyp = f(2)*yy + c(2)
它是Brown-Conrady model,在Camera Calibration Toolbox for Matlab参考文献中提到。本文讨论:D. C. Brown "Close-Range Camera Calibration"。
此外,当前的OpenCV模型似乎忽略了切向失真(P(r)
)。
看到这个comment。
以上是关于OpenCV3.0.0dev中鱼眼摄像机模型的主要参考是什么?的主要内容,如果未能解决你的问题,请参考以下文章