双目立体视觉一直是机器视觉研究领域的热点和难点。 “热”是因为双目立体视觉有着广阔的应用前景,而且随着光学、计算机科学等学科的不断发展,双目立体技术将会不断进步,直到应用到人类生活的各个方面。 “难”是由于相机、镜头等硬件设备以及一些相关算法的限制。
01 简介
双目立体视觉是机器视觉的一个重要分支。自20世纪60年代中期诞生以来,经过几十年的发展,现已广泛应用于机器人视觉、航空测绘、军事应用和医学成像、工业检测等领域。双目立体视觉是基于视差原理,利用成像设备从不同位置获得被测物体的左右图像。然后根据三角测量原理计算二维图像中空间点的位置偏差,最后利用位置偏差进行三维重建。获取被测物体的三维几何信息(本文不详细介绍双目立体视觉的数学原理)。
02
双目立体视觉的三种基本算法原理及其代码实现(基于opencv)
双目立体视觉中常用的基于区域的局部匹配准则主要包括图像序列中对应像素差值绝对值之和SAD(sum ofabsolute Difference)、对应像素差值平方和SSD(sum of squared差异)和半全局匹配算法SGM(半全局匹配)。
2.1 SAD(绝对差之和)原理
匹配算法SAD的基本思想是对对齐的左右视图图像的对应像素块的对应像素差值的绝对值求和。
其数学公式如下:
SAD匹配算法的基本流程如下:
输入两个经过校正的左视图(Left-Image)和右视图(Right-Image),以实现线对齐。
扫描左视图的Left-Image,选择一个锚点,构建一个类似于卷积核的小窗口。
用这个小窗口覆盖Left-Image,并选择小窗口覆盖区域内的所有像素。
同样用这个小窗口覆盖Right-Image,选择小窗口覆盖区域内的所有像素。
用Left-Image覆盖区域的像素减去Right-Image覆盖区域的像素,求所有像素点差值的绝对值之和。
移动右图小窗口,重复-操作。 (注意这里会设置一个搜索范围,超出这个范围就会跳出)
找到该范围内SAD值最小的小窗口,然后找到与Left-Image锚点最匹配的像素块。
2.1.1 基于Opencv的SAD(绝对差之和)的C++代码实现
首先定义一个SAD算法的头文件(SAD_Algorithm.h):
#include'iostream'#include'opencv2/opencv.hpp'#include'iomanip'using 命名空间std;using 命名空间cv;class SAD{public: SAD() :winSize(7), DSR(30) {} SAD(int _winSize, int _DSR) :winSize(_winSize), DSR(_DSR) {} Mat computerSAD(Mat L, Mat R); //计算SADprivate: int winSize; //卷积核的大小int DSR; //视差搜索范围};Mat SAD:computerSAD(Mat L, Mat R){ int Height=L.rows; int 宽度=L.cols; Mat Kernel_L(Size(winSize, winSize), CV_8U, Scalar:all(0)); Mat Kernel_R(大小(winSize, winSize), CV_8U, Scalar:all(0));垫子视差(高度,宽度,CV_8U,标量(0)); //视差图for (int i=0; i=0) { Kernel_R=R(Rect(x, j, winSize , winSize));马特迪夫; absdiff(Kernel_L, Kernel_R, Dif);//求差值绝对值之和Scalar ADD=sum(Dif);浮动a=ADD[0]; MM.at(k)=a ; } } 点minLoc; minMaxLoc(MM, NULL, NULL, minLoc, NULL); int loc=minLoc.x; //int loc=DSR-loc;视差.at(j, i)=loc * 16; } 双倍率=double(i)/(宽度); cout '完成' set precision(2) 率* 100 '%' endl; //显示处理进度} return Disparity;}调用示例:#include'SAD_Algorithm.h'int main(int argc, char* argv[]){ Mat Img_L=imread('Teddy_L.png', 0); //这里调用的图片已经放到项目文件夹下Mat Img_R=imread('Teddy_R.png', 0);垫子差异; //创建视差图SAD mySAD(7, 30); //给出SAD的参数Disparity=mySAD.computerSAD(Img_L, Img_R); imshow('Teddy_L', Img_L); imshow('Teddy_R', Img_R); imshow('视差', 视差); //显示视差图waitKey();系统('暂停'); //按任意键退出return 0;}
2.1.2 SAD算法的运行效果
可见,SAD算法虽然运行速度较快,但效果较差。
2.2 SSD原理(差平方和)
SSD(平方差之和)算法与SAD(绝对差之和)算法大致相似。
其数学公式如下:
由于SSD匹配算法的流程和代码实现与SAD匹配算法类似,考虑到文章篇幅,本文不再详细介绍SSD算法的基本流程和代码实现,读者可参考可以自己实现。
2.3 SGBM(半全局块匹配)原理
SGM(半全局匹配)是一种用于计算双目立体视觉视差的半全局匹配算法。它在opencv中的实现是SGBM(半全局块匹配)。
SGBM的原理:设置一个与视差图(由每个像素的视差组成)相关的全局能量函数,以最小化这个能量函数。
原始文件:Heiko Hirschmuller。通过半全局匹配和互信息进行立体处理。模式分析和机器智能,IEEE 汇刊,30(2):328341,2008 年。
其能量函数如下:
D--disparity map(视差图)
p、q——图像中的某个像素
Np——像素点Pd相邻像素点(一般认为是8连通)
C(P,Dp)--当当前像素的视差为Dp时,该像素的代价
P1、P2——惩罚系数,分别适用于像素P的相邻像素的视差值与P的视差值之间的视差差为1或大于1时
I[]——当[]中的参数为真时返回1,否则返回0
SGBM算法的基本流程如下:
预处理:使用sobel算子对源图像进行处理,将sobel算子处理后的图像映射为新图像,并获取图像的梯度信息,用于后续计算成本。
代价计算:对预处理得到的图像梯度信息采用采样方法计算梯度代价,对源图像采用采样方法计算SAD代价。
动态规划:默认4条路径,设置路径规划的参数P1、P2(包括P1、P2、cn(图像通道数)和SADWindowsize(SAD窗口大小)的设置)。
后处理:包括唯一性检测、亚像素插值、左右一致性检测、连通区域检测。
2.3.1 基于Opencv的SGBM(半全局块匹配)的C++代码实现
首先定义一个SGBM算法的头文件(SGBM_Algorithm.h):
具体参数请参见代码及其注释(如需优化读者可自行调整),不再赘述。
enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2, STEREO_VAR=3, STEREO_3WAY=4 };#include'iostream'#include'opencv2/opencv.hpp'using 命名空间std;using 命名空间cv;void calDispWithSGBM(Mat Img_L , Mat Img_R, Mat imgDisparity8U){ 大小imgSize=Img_L.size(); int numberOfDisparities=((imgSize.width/8) + 15) -16; Ptr sgbm=StereoSGBM:create(0, 16, 3); int cn=Img_L .channels(); //左图像的通道数int SADWindowSize=9; int sgbmWinSize=SADWindowSize 0 ? SAD窗口大小: 3; sgbm-setMinDisparity(0); //minDisparity的最小视差默认为0; sgbm-setNumDisparities(numberOfDisparities); //numDisparity视差搜索范围,其值必须是16的整数倍; sgbm-setP1(8 * cn*sgbmWinSize*sgbmWinSize); sgbm-setP2(32 * cn*sgbmWinSize*sgbmWinSize); //一般推荐惩罚系数P1、P2取这两个值,P1和P2控制视差图的平滑度//P2越大,视差图越平滑sgbm-setDisp12MaxDiff(1); //左右一致性检测最大允许误差阈值sgbm-setPreFilterCap(31); //预处理过滤器的截断值,预处理后的输出值只保留//[-preFilterCap, preFilterCap]范围内的值,参数范围:1 - 31 sgbm-setUniquenessRatio(10); //Disparity uniqueness百分比:disparity 当窗口范围内最低cost为(1 + uniquenessRatio/100)倍下一个最低cost时//最低cost对应的视差值为该像素的视差,否则为该像素的视差像素为0且不能为负值。一般去5——15 sgbm-setSpeckleWindowSize(100); //视差连通区域的像素数量大小:对于每个视差点,当连通区域的像素数量小于//speckleWindowSize 时,认为该视差值无效。这是噪音。 sgbm-setSpeckleRange(32); //视差连通性条件:计算某个视差点的连通面积时,当下一个像素点的视差变化绝对值大于//speckleRange时,认为下一个视差像素点与当前视差像素点是不相连的。 sgbm-setMode(0); //模式选择sgbm-setBlockSize(sgbmWinSize); //设置SAD代价计算窗口,通常在3*3到21*21之间//blockSize(SADWindowSize)越小,匹配代价计算窗口越小,视差图中的噪声越大; //blockSize越大,视差图越平滑; //尺寸过大很容易导致过度平滑,失配增加,体现在视差图空洞增加//三种模式选择(HH、SGBM、3WAY) int Algorithm=STEREO_SGBM; if (算法==STEREO_HH) sgbm-setMode(StereoSGBM:MODE_HH);否则if (算法==STEREO_SGBM) sgbm-setMode(StereoSGBM:MODE_SGBM);否则if (算法m==STEREO_3WAY ) sgbm-setMode(StereoSGBM:MODE_SGBM_3WAY); Mat imgDisparity16S=Mat(Img_L.rows, Img_L.cols, CV_16S); sgbm-计算(Img_L,Img_R,imgDisparity16S); //--显示为CV_8UC1图像:16位有符号转换为8位无符号imgDisparity16S.convertTo(imgDisparity8U, CV_8U, 255/(numberOfDisparities*16.));} 调用示例:#include'SGBM_Algorithm.h' int main(){ Mat Img_L=imread('Teddy_L.png', 0); Mat Img_R=imread('Teddy_R.png', 0); Mat Disparity8U=Mat(Img_L.rows, Img_R.cols, CV_8UC1);//创建视差图像calDispWithSGBM(Img_L, Img_R, Disparity8U); imshow('Teddy_L', Img_L); imshow('Teddy_R', Img_R); imshow('视差', Disparity8U);等待键();系统('暂停'); //按任意键退出return 0;}
2.3.2 SGBM算法的运行效果
我还调整了SADWindowsize 的大小,以讨论并向读者展示设置不同SADWindowsize 大小时对视差渲染的影响。结果如下(均为MODE_SGBM模式):
从上述不同SADWindowsize大小设置(其他参数不变)的效果图对比,我们可以得出以下结论:
如果SADWindowsize太小,视差图会有更多的噪声。随着SADWindowsize 的增加,视图将变得更加平滑。然而,当SADWindowsize太大时,视差图中的空洞会增加。因此,在选择SADWindowsize的大小时,应该选择合适的大小。大小(建议选择SADWindowsize=9)。
03 双目立体视觉发展现状
目前,双目立体视觉技术在国外已广泛应用于生产生活中。然而在我国,双目立体视觉技术还处于起步阶段,还需要在座大家努力拼搏,努力创新。
3.1 双目立体视觉的发展方向
就目前双眼立体视觉(实现类似于人眼的通用双眼立体视觉)的发展现状和发展目标而言,还有很长的路要走。我认为进一步的发展方向可以概括为以下几个方面:
探索新的、更通用的计算理论和匹配算法结构,解决当前的灰度失真、噪声干扰和几何失真问题。
提高算法性能,优化算法,尽可能提升实时效果。
建立更有效的双目立体模型可以更全面地反映立体不确定性的本质属性,为匹配提供更多的约束信息,降低立体匹配的难度。
强调场景和任务的约束,建立适合不同场景和任务的双目立体视觉系统的标准和方法。
3.2 国内外双目立体视觉发展趋势
双目立体视觉目前主要应用于机器人导航、微操作系统参数检测、三维测量和虚拟现实四个领域。
目前国外,日本大阪大学自适应机械系统研究所开发了自适应双目视觉伺服系统,该系统利用双目立体视觉的原理,如每幅图像中的三个相对静止的标记作为参考,计算出目标在即时的。图像的雅可比矩阵可以用来预测目标的下一步运动方向,实现对未知运动模式目标的自适应跟踪。该系统仅需要两个图像中的固定参考标记,不需要相机参数。
日本奈良工业大学信息学院提出了一种基于双目立体视觉的增强现实系统(AR)配准方法,通过动态校正特征点的位置来提高配准精度。
日本东京大学综合实时双目立体视觉和机器人整体姿态信息,开发了模拟机器人动态线长导航系统,该系统根据实时情况为机器人建立实时地图,实现障碍物检测。
日本冈山大学利用体视显微镜、两个CCD相机、显微操作器等,开发了视觉反馈系统,利用体视显微镜控制显微操作器,用于操作细胞、进行基因注射和钟的微组装等。
麻省理工学院计算机系统公司提出了一种新的智能交通传感器融合方法。雷达系统提供目标深度的大致范围,利用双目立体视觉提供粗略的目标深度信息,并将其与改进的图像分割算法相结合。从而实现高速环境下视频图像中目标位置的分割。
华盛顿大学和微软合作为火星卫星航海者号开发了宽基线立体视觉系统,使航海者号能够对即将穿越火星的数公里范围内的地形进行精确定位和导航。
国内,浙江大学的机械系统充分利用透视成像原理,采用双目立体方法,实现多自由度机械装置的动态精确位姿检测。只需要从两张对应的图像中提取必要的三维特征点。坐标,信息量小,处理速度快,特别适合动态情况。
基于双目立体视觉,INDEMIND开发了适用于商业和家庭服务机器人的视觉导航技术。在算法和硬件方面,提出了一套自主研发的VSLAM算法和集成多种视觉传感器的集成模块。可实现机器人视觉定位、语义识别、语义建图、避障、交互等多种功能。
东南大学电子工程系基于双目立体视觉,提出了一种新型灰度相关多峰视差绝对值最小化立体匹配方法,可对三坐标系的三维空间坐标进行非接触式精密测量。尺寸不规则物体(偏转线圈)。
哈尔滨工业大学采用异构双目主动视觉系统实现全自主足球机器人导航。机器人的顶部和中下部分别安装了固定摄像头和水平旋转摄像头,可以同时监视不同方向的视点,表现出相对于人类视觉的优越性。即使实际比赛中其他传感器出现故障,仅依靠双目协调仍然可以实现完全自主的足球机器人导航。
审稿人:刘庆