上一节的程序实现了立体视觉实现过程的所有步骤,现在对整体框架进行分析学习
书中框架结构介绍
书:Learning OpenCV3
第一步:读取左右图像对
目的:寻找亚像素精度的circles
方法:调用stereoCalibrate()标定
需求:相机矩阵_M以及畸变矢量_D
输出:_R,_T,_E,_F
第二步:评估精度
方式:图像上的点距离另一张图像上的极线到底有多远。
调用函数 undistortPoints()以及computeCorrespondEpilines()
第三步:计算校正图像
方式
Hartley-> cv::stereoRectifyUncalibrated()
如果使用这一步,代码还需要计算基础矩阵或者直接调用立体标定得到的基础矩阵
然后调用cv::remap()计算校正图像。
本实例中通过划线,表明了校正图像之间的联系。
Bouguet->stereoRectify()
第四步:计算视差图
这一部分通过StereoSGBM()寻找标定/非标定的校正立体图像对的视差图。
例子中给了水平放置以及垂直放置相机的校正实例。
但是垂直放置只能通过非标定校正算法,除非你通过代码对图像进行了转换
StereoCalib开放接口
接口参数表
static void StereoCalib(const char *imageList, int nx, int ny,
bool useUncalibrated)
在主程序中,使用了StereoCalib函数,使用形式为
StereoCalib(board_list, board_w, board_h, true);
其中board_list为包含了标定板名称的txt文件;board_w,board_h为棋盘格的方格数目,最后一个参数为校正的形式(使用标定校正(Bouguet's algorithm)还是非标定校正(Hartely's algorithm))
StereoCalib内部分析
工作流程
程序的流程为双目立体视觉成像的流程:
单目标定(获取内外参)->双目标定(相机之间的转换矩阵)->校正(输出行对准图像)->立体匹配(输出深度图)
立体校正的两种方法
前面几篇文章只是泛泛的提了一下立体校正,本文由于是进一步深入的应用,将对涉及的两种校正方法:Bouguet算法以及Hartely算法进行原理上的梳理。
资料来源:
Learning OpenCV3
Hartely算法(Hartley's algorithm)
本文研究的主程序对useUncalibrate赋值为true,进入程序中则自动选择非标定校正算法;这里采用的非标定校正算法就是Hartley算法。
Hartley算法通过将极点匹配到无穷远的方法寻找单应性,可以减少两立体图像之间的视差。这种方法绕过了计算相机的内参,从而不用进行点的匹配,因此算法复杂度较低。基础矩阵可由stereoCalibrate()获得。
优点:通过简单的观察场景中的点,可以实现在线立体标定(online stereo calibrate)
缺点:由于避开了图像的内参调用;我们无法了解图像的尺度因子,比如棋盘格到底是距离我们100cm还是100m。
函数
Bouguet算法(Bouguet's algorithm)
Bouguet算法就是标定算法,其输入参数为两相机之间的R/T矩阵。立体矫正在Bouguet算法的实现原理是:在最大化公共视场区域的同时,最小化重投影畸变。
由于目前我的数学基础还不扎实,以及目前这部分是为了用;这两种算法的原理在后续继续深入研究时将进行补充。
函数
本文调用函数汇总
stereoCalibrate
本函数实现立体标定,输出R、T、E、F矩阵