FAST特征检测
./test_feature_detection
圈的大小代表了尺度的大小,也就是在不同金字塔下检测的特征。
基础成员数据结构:
/svo/include/frame.h
对于帧按照面向对象的思想,其应该包含自己固有的属性,比如帧的编号,帧对应的相机模型,对应的特征等等。
目前定义的帧成员变量主要有:帧的计数器用于设置帧的唯一id,帧创建的时间戳(后期用于同步,多传感器融合),相机模型(用于对图像进行畸变矫正),图像金字塔(主要用于提取不同尺度下的特征,具体尺度的讲解可以参考:sift)以及帧对应的特征。
/Vikit/include/abstract_camera.h
对于相机模型,定义了相机抽象类,提供了相机分辨率,定义摄像机坐标与图像像素坐标转换的相关抽象方法.
定义了抽象的相机类,目前实现了小孔相机模型,后期进一步考虑实现ATAN相机模型(/Vikit/include/atan_camera.h atan_camera.cpp)。
/Vikit/include/pinhole_camera.h pinhole_camera.cpp
小孔相机模型 :width, height, fx, fy, cx, cy,
d0=0.0, d1=0.0, d2=0.0, d3=0.0, d4=0.0
//考虑畸变参数k1,k2,p1,p2,k3主要考虑了5个畸变参数.
小孔相机模型主要公式可以参考:http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
这样,基础的相机模型已经设计与实现完毕,那下面我们就考虑帧对应的图像金字塔,对于图像金字塔,直接采用了OpenCV的数据结构cv::Mat,定义为typedef std::vector<cv::Mat> ImgPyr;以及对于特征feature的定义:/svo/include/feature.h
具体帧初始化时,也就是对帧对应的图像进行构造图像金字塔。/svo/src/frame.cpp
特征检测:上面基本的类型已经定义好了,下面进行特征提取。对于特征提取,为了特征跟踪的时候,不容易出现突变,通过将图像进行划分为单元格(将图像分成grid_n_cols_*grid_n_rows_个格子),使得检测到的特征尽可能的分散,尽量保证每个单元格有一个特征。对特征检测也进行抽象,为了后期可以方便的切换到其它特征检测算法,/svo/src/feature_detection.cpp /svo/inculde/feature_detection.h
定义好特征检测的抽象类,我们主要使用的特征检测算法为FAST特征检测,由抽象类定义FAST特征检测类,[并且使用了shiTomasiScore方法,我们对通过FAST检测出的角点进行了进一步的筛选(Shi-Tomasi角点提取的方法),确保提取出的角点的稳定性。我们采用了第三方库fast,主要作者通过SSE2指令进行了实现,效率高。---后续对这一块进一步学习。]
初始位置确定
前面我们已经进行了特征提取,接下来不是通过特征匹配的方式来寻找对应特征点,而是采用跟踪的方式。
初始位置的确定很重要,要确保初始位置的尽可能的准确。
Sophus库的添加:对于sophus,目前我理解的范围就是对旋转和平移做了一个封装,可以更好的进行刚性变换。
基本思路:根据光流确定对应特征点,根据对应特征点计算两帧之间的单应矩阵,根据单应矩阵进行分解,计算出两帧之间的旋转和平移。
考虑到帧的旋转和平移,则在帧上添加属性,添加从世界坐标系(w)orld转到摄像机坐标系(f)rame的刚性变换Rt
Sophus::SE3 Tf_w;
而对于特征添加特征对应的3D点,以及特征的单位方向向量(用于后期的三角定位)
Vector3d f; //!< 特征的单位方向向量 Point3D* point; //!< 指针指向跟特征对应的3D点
选择第一帧/svo/src/initalization.cpp /svo/inculde/initalization.h