鱼眼相机模型 (fisheye camera model)

  • 模型介绍
    • 等距投影
    • 等立体角投影
    • 正交投影
    • 体视投影
    • 线性投影
  • Kannala-Brandt 模型
    • 去畸变过程
    • 投影过程
    • 反投影过程
  • 雅可比计算

之前总结了一下针孔相机的模型,然后得到了比较积极的回复(其实是我到处求人关注的,虽然截至到目前才三个人),所以就再接再励,乘胜追击(也没得办法,夸下的海口,跪着也要做完),继续总结其他相机模型。

模型介绍

鱼眼相机相较于针孔相机来说,视野更广,但畸变也更加严重,因此普通的针孔模型已不适用。鱼眼镜头的基本构造如图所示,经过多个镜头的折射,最终到达成像单元上。文章中所有图片均来自于网络,非本人所绘。

一般情况下,可以通过控制光线的路径来设计各种各样的镜头类型,根据投影方式的不同,可以将这些镜头分为等距投影、等立体角投影、正交投影、体视投影以及线性投影。

等距投影

r=fθr=f \theta r=fθ

等立体角投影

r=2fsin(θ2)r=2fsin({{\theta} \over {2}})r=2fsin(2θ​)

正交投影

r=fsin(θ)r=fsin(\theta )r=fsin(θ)

体视投影

r=2ftan(θ2)r=2ftan({{\theta} \over {2}})r=2ftan(2θ​)

线性投影

r=ftan(θ)r=ftan(\theta)r=ftan(θ)

Kannala-Brandt 模型

同针孔模型一样,鱼眼模型也有畸变,那么怎么来用数学鱼眼描述这种畸变呢?观察各种投影方式,发现他们都是一个关于入射角 θ\thetaθ 的奇函数,因此鱼眼镜头的畸变也是对 θ\thetaθ 的畸变,KB模型用只包含奇次项的多项式来描述畸变过程,其具体形式如下所示
θd=θ+k1θ3+k2θ5+k3θ7+k4θ9\theta_d=\theta+k_1\theta^3+k_2\theta^5+k_3\theta^7+k_4\theta^9θd​=θ+k1​θ3+k2​θ5+k3​θ7+k4​θ9
opencv中使用的鱼眼相机畸变模型就是这个模型,该模型适用于大多数鱼眼相机。另外,也可以用这种模型来对普通的针孔相机模型进行标定,仔细观察,上述的线性投影实际就是普通的针孔投影模型。最后鱼眼相机的投影模型可以表示为
r=fθdr = f \theta_dr=fθd​
其中rrr表示图像中像素点到主点的距离。

去畸变过程

对于鱼眼相机的去畸变过程可以采用解析的方式,因为从上述畸变公式中可以看到,畸变模型是一个多项式,理论上是存在解析解的。但本人使用的方法和针孔模型中类似,通过优化的方法进行去即便,代码如下

      template<typename DERIVED_P>void undistort(const Eigen::MatrixBase <DERIVED_P> &p_d,const Eigen::MatrixBase <DERIVED_P> &p_ud) const{EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE_OR_DYNAMIC(Eigen::MatrixBase<DERIVED_P>, 2)Eigen::MatrixBase<DERIVED_P> &y_ud = const_cast<Eigen::MatrixBase<DERIVED_P> &>(p_ud);Eigen::MatrixBase<DERIVED_P> &y_d = const_cast<Eigen::MatrixBase<DERIVED_P> &>(p_d);y_ud.derived().resize(2);y_d.derived().resize(2);struct MLFunctor{MLFunctor( const Eigen::Vector2d &imagePoint, double k1, double k2, double k3, double k4 ): imagePoint_(imagePoint), _k1(k1), _k2(k2), _k3(k3), _k4(k4){}int operator( )( const Eigen::VectorXd &x, Eigen::VectorXd &fvec ) const{double theta = x[0];double phi = x[1];double theta2 = theta * theta;double theta4 = theta2 * theta2;double theta6 = theta4 * theta2;double theta8 = theta4 * theta4;double thetad = theta * ( 1 + _k1 * theta2 + _k2 * theta4 + _k3 * theta6 + _k4 * theta8);fvec[0] = thetad;fvec[1] = phi;fvec = fvec - imagePoint_;return 0;}int df( const Eigen::VectorXd &x, Eigen::MatrixXd &fjac ) const{double theta = x[0];double theta2 = theta * theta;double theta4 = theta2 * theta2;double theta6 = theta4 * theta2;double theta8 = theta4 * theta4;fjac(0, 0) = 9 * _k4 * theta8 + 7 * _k3 * theta6 + 5 * _k2 * theta4 + 3 * _k1 * theta2 + 1;fjac(0, 1) = 0;fjac(1, 0) = 0;fjac(1, 1) = 1;return 0;}int values() const { return 2; }int inputs() const { return 2; }Eigen::Vector2d imagePoint_;double _k1;double _k2;double _k3;double _k4;};Eigen::Vector2d target = y_d;MLFunctor func( target, m_k1, m_k2, m_k3, m_k4 );Eigen::LevenbergMarquardt< MLFunctor > lm(func);double theta = y_d[0];double phi = y_d[1];Eigen::VectorXd res = Eigen::Vector2d(theta, phi);lm.minimize(res);y_ud = res;}

投影过程

  1. 给定相机坐标系下一点Pc=(x,y,z)P_c=(x, y, z)Pc​=(x,y,z)
  2. 归一化到球平面上Ps=Pc∣∣Pc∣∣=(xs,ys,zs)P_s = {{P_c} \over {||P_c||}}=(x_s, y_s,z_s)Ps​=∣∣Pc​∣∣Pc​​=(xs​,ys​,zs​)
  3. 求经纬度 θ=acos(zs)=atan2(x2+y2),z)\theta=acos(z_s)=atan2(\sqrt{x^2+y^2)}, z)θ=acos(zs​)=atan2(x2+y2)​,z), ϕ=atan2(ys,xs)\phi=atan2(y_s, x_s)ϕ=atan2(ys​,xs​)
  4. 利用畸变模型对 θ\thetaθ进行加畸变处理,得到θd\theta_dθd​。
  5. 最后得到该点在图像中的像素坐标u=fxθdxcr+cxu={{f_x\theta_d x_c}\over r } +cxu=rfx​θd​xc​​+cx, v=fyθdycr+cyv={{f_y\theta_d y_c}\over r } +cyv=rfy​θd​yc​​+cy, r=xc2+yc2r=\sqrt{x_c^2 + y_c^2}r=xc2​+yc2​​

反投影过程

  1. 给定图像上一点p=(u,v)p=(u, v)p=(u,v).
  2. 可以得到归一化坐标pd=(x,y)=(u−cxfx,v−cyfy)p_{d} = (x, y) = ({{u - cx} \over f_x}, {{v - cy} \over f_y})pd​=(x,y)=(fx​u−cx​,fy​v−cy​)
  3. 可以得到带畸变的入射角 θd=x2+y2,ϕ=atan2(y,x)\theta_d=\sqrt{x^2+y^2}, \phi=atan2(y, x)θd​=x2+y2​,ϕ=atan2(y,x).
  4. 去畸变后得到θ\thetaθ.
  5. 最后得到单位球面坐标x=sin(θ)cos(ϕ),y=sin(θ)sin(ϕ),z=cos(θ)x = sin(\theta)cos(\phi), y=sin(\theta)sin(\phi), z = cos(\theta)x=sin(θ)cos(ϕ),y=sin(θ)sin(ϕ),z=cos(θ)

雅可比计算

多数情况下,都用BA算法来计算相机的内外参,这就需要知道雅可比矩阵,即投影误差对各待优化变量的偏导数组成的矩阵。所谓的投影误差,实际检测到点与投影到图像上的点之间的误差
err=pm−perr=p_m - perr=pm​−p
其中 pmp_mpm​表示检测到的角点。为了避免手撕公式,我使用了matlab直接来推导出结果,并且在推导公式时,没有考虑畸变项,因为公式太长了,懒得敲。
代码:

syms fx fy x y z cx cy k1 k2 k3 k4R = sqrt(x^2 + y^2 + z^2);
xc = x / R;
yc = y / R;
zc = z / R;
theta = acos(z);
%thetad = theta + k1 * theta^3 + k2 * theta^5 + k3 * theta^7 + k4 * theta^9;
thetad = theta;
r = sqrt(xc^2 + yc^2);
u = fx * (thetad * xc) / r + cx;
v = fy * (thetad * yc) / r + cy;alphaE_alphaK = - [diff(u, fx), diff(u, fy), diff(u, cx), diff(u, cy);diff(v, fx), diff(v, fy), diff(v, cx), diff(v, cy)]alphaE_alphaP = -[diff(u, x), diff(u, y), diff(u, z);diff(v, x), diff(v, y), diff(v, z)]
alphaP_alphaR = [1, 0, 0, 0, z, -y; 0, 1, 0, -z, 0, x; 0, 0, 1, y, -x, 0]alphaE_alphaP * alphaP_alphaR

假设相机坐标系下归一化到球面的3D点坐标坐标为Ps=(xs,ys,zs)P_s=(x_s, y_s, z_s)Ps​=(xs​,ys​,zs​)

  1. 误差项关于内参的偏导数

    其中r=xs2+ys2r=\sqrt{x_s^2 + y_s^2}r=xs2​+ys2​​, θ=acos(zs)\theta=acos(z_s)θ=acos(zs​)。

  2. 误差项关于相机坐标系下点PsP_sPs​的偏导

    其中r=xs2+ys2r=\sqrt{x_s^2 + y_s^2}r=xs2​+ys2​​, θ=acos(zs)\theta=acos(z_s)θ=acos(zs​)。

  3. 误差项在李代数上的扰动模型
    根据链式法则可得

∂err∂δξ=∂err∂Ps∂Ps∂δξ{{\partial err} \over {\partial \delta \xi }} = {{\partial err} \over {\partial {P_s}}}{{\partial {P_{\rm{s}}}} \over {\partial \delta \xi }}∂δξ∂err​=∂Ps​∂err​∂δξ∂Ps​​

其中,∂Pc∂δξ{{\partial {P_{\rm{c}}}} \over {\partial \delta \xi }}∂δξ∂Pc​​的推导后续会有专门篇幅进行总结,在这个先用起来再说。

其中r=xs2+ys2r=\sqrt{x_s^2 + y_s^2}r=xs2​+ys2​​, θ=acos(zs)\theta=acos(z_s)θ=acos(zs​)。

相机模型-鱼眼模型(fisheye camera model)相关推荐

  1. OpenCV 3.0.0处理鱼眼镜头信息 - Fisheye camera model

    此篇随笔主要参考OpenCV 3.0.0的官方文档翻译而来,主要用作理解OpenCV对鱼眼相机的标定.图像校正.3D重建功能的理解. 版权所有,转载请注明出处~ xzrch@2018.09.29 参考 ...

  2. 相机模型-鱼眼模型/鱼眼镜头标定基本原理及实现(2)

    问题: 1 广角/超广角与鱼眼摄像机,角度界限 2 畸变模型中radtan畸变模型与鱼眼畸变模型在小于150范围是否都时能适用.   (同数据,拟合模型不同,,参数结果不同,不欠拟合和过拟合就可) 3 ...

  3. 【CV】鱼眼相机模型与畸变矫正(Fisheye Camera Model Calibration)

    文章目录 鱼眼镜头 鱼眼名称的由来 鱼眼镜头的实现 鱼眼相机的成像模型 鱼眼图像的矫正 Ref 鱼眼镜头 鱼眼镜头长这样 #鱼眼镜头成像样张 拍出来的照片长这样 鱼眼名称的由来 之所以叫鱼眼,是因为仿 ...

  4. 在OpenCV中,将鱼眼模型(Fisheye camera model)改写为普通相机模型

    笔者经验不足,把cv::fisheye::calibrate直接改为cv::calibrateCamera后,遇到的几个问题,当时走了很多弯路,为了减少同行们在查阅相关资料时浪费的时间,笔者做了如下整 ...

  5. opencv Fisheye camera model

    https://docs.opencv.org/master/db/d58/group__calib3d__fisheye.html

  6. 相机模型-Unified Camera Model

    相机模型-Unified Camera Model 模型介绍 投影过程 反投影过程 雅可比计算 开篇不知道说啥了,直接开始吧. 模型介绍 这个相机模型在其它地方又被叫做 Omnidirectional ...

  7. 3. 全向相机模型Omnidirectional Camera Model

    目录 1. 定义: 2. scaramuzza多项式模型 2.1 模型推导 3. 标定原理 3.1 求外参 3.2 求内参 3.3 非线性优化 4. 感谢您的阅读! 1. 定义: 全向相机(Omnid ...

  8. 相机模型-Extended Unified Camera Model

    相机模型-Extended Unified Camera Model 模型介绍 投影过程 反投影过程 雅可比计算 之前讲到了Unified Camera Model模型,该模型是借助于一个虚拟的单位球 ...

  9. 1. pinhole camera model 小孔相机模型【cs231a课程笔记】

    文章目录 同系列链接 1.1. pinhole camera model 1.2. lens-based model (paraxial refraction model) distortion 1. ...

最新文章

  1. 一阶微分算子锐化图像_【动手学计算机视觉】第三讲:图像预处理之图像分割...
  2. 处理问题的方法--抽象和特例化
  3. ARC在Release与Debug模式中内存释放的坑
  4. C++ explicit constructor/copy constructor note
  5. dommel mysql_.Net Core AA.FrameWork应用框架介绍
  6. 线程的核心应用(DoubleCat)
  7. clion修改选中行的背景颜色
  8. Eclipse常用快捷键常用技巧
  9. linux-centos连网
  10. python有什么优秀功能_Python都有什么强大的功能
  11. java 通过 socket 实现 服务器和客户端的通信 TCP
  12. 适配器模式之桥梁模式
  13. 如意淘商品推荐技术介绍之一:基础推荐
  14. python开发cms_基于Django的Python CMS---wagtail介绍
  15. mysql查询表升序降序_创建一个按钮,对MYSQL查询进行升序和降序排序
  16. 如何使用jquery插件
  17. 涂师傅手机数据恢复官方版
  18. Git错误!:403错误
  19. php validate,jQuery Validate | 菜鸟教程
  20. Python+PEP8 | VSCode自动格式化代码

热门文章

  1. Q3亏损超11亿,B站、拼多多、蔚来这些亏损新贵如何盈利破圈?
  2. SpringCloud和SpringBoot版本冲突问题
  3. POJ 3233 Matrix Power Serie
  4. 最短路算法 算法 python实现
  5. 黑马前端h5团队开发代码规范
  6. 2019河北省大学生程序设计竞赛(重现赛)部分题解
  7. YOLOv2训练DOTA数据集
  8. 树莓派c语言 智能车,人工智能-树莓派小车(4)——通过语音玩转智能小车
  9. 手机防抖的三大类-OIS-EIS-微云台
  10. 给定一个十进制整数,如何转成二进制形式?如何转成十六进制形式?