不同于特征描述的方法,直接基于像素的图像追踪速度更快,而且如果选择逐像素匹配的话还能构建致密的三维场景。而且转向时匹配失败的机率也明显低于基于特征的方法。但其最大的缺点是对光照的稳定性依赖太高,然而实际上这很不现实。下面实际走一下这个过程。
首先对第一幅图像进行特征检测,根据源码,作者是采用的fast库进行特征检测,具体的检测过程这里先不讨论,总之大概能获得几百个角点(每层金字塔都检测,并且根据网格使得角点分布均匀)。于此同时,根据相机的内参计算角点的三维单位向量,以便于后续计算。角点里主要保存有其二维位置和三维单位向量等。如果角点数目大于100,设为第一帧,否则跳过这一帧。
然后进入下一帧,采用光流法计算图像的相对运动,这里采用的是cv::calcOpticalFlowPyrLK,当然也可以采用cv::calcOpticalFlowFarneback,cv::CalcOpticalFlowBM,cv::CalcOpticalFlowHS,cv::calcOpticalFlowSF等方法计算,具体参见opencv官方手册。同时计算当前帧的特征点对应的三维单位向量。如果成功跟踪的特征数大于50,则跟踪成功。同时根据两幅图像的偏差确定关键帧(太近不能作为关键帧)。然后使用cv::findHomography计算两幅图像的单应,获得单应矩阵(也可以自己写而不使用opencv)。然后将单应矩阵分解,从而求得SE3,这里比较抽象,还没完全弄明白,后续补上具体细节问题。根据单应矩阵,反向验证特征点的对应关系(根据单应矩阵从第二幅图像求第一幅图像的点,然后计算误差,当误差大于临界值时不是内点)。从8个分解里找出最好的分解(也不是很明白),通过最好的分解获得SE3。然后三角化所有特征点,得到特征点的世界坐标,然后计算投影误差和内点,最终确定SE3。
计算结果如图所示
可以看到在特征点只有几百个的时候追踪相当快。
首先对第一幅图像进行特征检测,根据源码,作者是采用的fast库进行特征检测,具体的检测过程这里先不讨论,总之大概能获得几百个角点(每层金字塔都检测,并且根据网格使得角点分布均匀)。于此同时,根据相机的内参计算角点的三维单位向量,以便于后续计算。角点里主要保存有其二维位置和三维单位向量等。如果角点数目大于100,设为第一帧,否则跳过这一帧。
然后进入下一帧,采用光流法计算图像的相对运动,这里采用的是cv::calcOpticalFlowPyrLK,当然也可以采用cv::calcOpticalFlowFarneback,cv::CalcOpticalFlowBM,cv::CalcOpticalFlowHS,cv::calcOpticalFlowSF等方法计算,具体参见opencv官方手册。同时计算当前帧的特征点对应的三维单位向量。如果成功跟踪的特征数大于50,则跟踪成功。同时根据两幅图像的偏差确定关键帧(太近不能作为关键帧)。然后使用cv::findHomography计算两幅图像的单应,获得单应矩阵(也可以自己写而不使用opencv)。然后将单应矩阵分解,从而求得SE3,这里比较抽象,还没完全弄明白,后续补上具体细节问题。根据单应矩阵,反向验证特征点的对应关系(根据单应矩阵从第二幅图像求第一幅图像的点,然后计算误差,当误差大于临界值时不是内点)。从8个分解里找出最好的分解(也不是很明白),通过最好的分解获得SE3。然后三角化所有特征点,得到特征点的世界坐标,然后计算投影误差和内点,最终确定SE3。
计算结果如图所示
可以看到在特征点只有几百个的时候追踪相当快。