前言
代码在aslam_cameras中的cameras里,主要是PinholeProjection.hpp、OmniProjection.hpp、ExtendedUnifiedProjection.hpp、DoubleSphereProjection.hpp这四个头文件和对应的OmniCameraGeometry.cpp、PinholeCameraGeometry.cpp、
PinholeRSCameraGeometry.cpp
在代码中使用了模板类,所以可呢会比较不好找
一、小孔成像模型
首先,我们先看一些简单的PinholeCameraGeometry.cpp
这段没什么,就是普普通通的构造函数,主要就是把对应的参数写里面,重载了构造函数,第一个第二个是没有考虑畸变参数,第三个的是考虑了畸变,里面的参数也没什么可说的:
_fu(focalLengthU),相机焦距(U方向)–这里我认为是内参左上角的那个数
_fv(focalLengthV),相机焦距(U方向)–这里我认为是内参中间的那个数
_cu(imageCenterU),相机光心(U方向,第三列第一个数)
_cv(imageCenterV),相机光心(V方向,第三列第二个数)
_ru(resolutionU),图像像素,长方向
_rv(resolutionV),图像像素,高方向
_enableDistortion(0),
_recip_fu(1.0 / _fu),
_recip_fv(1.0 / _fv),
_fu_over_fv(_fu / _fv)
_k1(k1),径向畸变参数K1
_k2(k2),径向畸变参数K2
_p1(p1),切向畸变参数p1
_p2(p2),切向畸变参数p2
这里面第一个构造函数调了个函数createTestGeometry(),
其实就是初始化了个参数
中间这一大坨也没太大用,updateIntrinsicsOplus这个是应该本来是要做优化的时候留的接口,maxKeypoint()返回图像坐标最大的点,即右下角的点,通过这个我们也能看出来前面构造的那个ru、rv其实就是图像像素
这个cpp中有点用的函数之一,这个函数的意思是将投影到归一化平面的点加上畸变影响,变为畸变后的情况,其中返回的参数dx和dy是差值,要用mx_u和my_u分别去加上这个差值才是正确的畸变后的值
具体可以参考这个文章
但在这些文章中,对归一化平面的说法很少,其实按照小孔成像模型来说,Xworld/Xpixel=Zworld/fx (不考虑图像坐标系到像素坐标系的缩放),那么Xpixel=Xworldfx/Z
那么Xworld/Z=Xpixel/fx ,我理解的归一化坐标系就算Xworld/Z的坐标系。即输入参数应该为(Xpixel-cu)/fx,(Ypixel-cv)/fy,等做完畸变后要再搞回到像素坐标系,即Xpixel=Xdisfx+u0,Ypixel=Ydis*fy+v0
归一化坐标系
这一块依然是写把正常的归一化理想坐标给加上畸变,但输出了额外的几个参数,用于生成雅各比矩阵,这块主要是供去畸变那里去非线性优化求解去畸变之后的效果。
这里就是去畸变的地方,其实跟opencv的迭代思想一样,换汤不换药,无非就算用非线性优化列写残差方程,然后直到迭代结束或者残差小于一个很小的值,这里后面会更新一下详细说说,目前大致了解到这里
最后就是这两部分,主要内容就算设置和读取内参和畸变。
最后的最后,可能有些小伙伴会去找这个PinholeCameraGeometry类的定义,然后发现找不到,其实我们可以看一下它包含的头文件,
它就包含了这三个头文件,然后这三个里面就cameras.hpp这个有点靠相机模型这块,那我们可以看一下这个头文件
这里我们可以看到我们的这个类,是CameraGeometry模板类的PinholeProjection, GlobalShutter, NoMask 特化,那么后面我们就可以接着去看一下CameraGeometry类和PinholeProjection类