精华内容
下载资源
问答
  • 双目立体匹配原理及流程简介

    千次阅读 2019-07-27 01:22:41
    双目立体视觉(Binocular Stereo Vision)是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被测物体的两幅图像,通过计算图像对应点间的位置偏差,来获取物体三维几何信息的方法...

    立体视觉:

    立体视觉:立体视觉是计算机视觉领域的一个重要课题,它的目的在于重构场景的三维几何信息.其应用包括移动机器人的自主导航系统,航空及遥感测量,工业自动化系统等。

    双目立体视觉:

    双目立体视觉(Binocular Stereo Vision)是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被测物体的两幅图像,通过计算图像对应点间的位置偏差,来获取物体三维几何信息的方法。

    双目匹配其实求的是视差disparity, 视差和深度有一个计算公式:
    disp = focal_length * base_line / depth 
    其中disp为视差, focal_length是焦距, base_line是双目之间的距离, depth是深度	
    
    • 步骤:
      1)摄像机标定:内参、外参、畸变参数
      2)双目图像的矫正: 畸变校正和立体矫正
      3)双目立体匹配: 得到视差图,深度图

    双目相机标定及矫正: link

    一.立体匹配算法分类:

    • 按照算法运行时约束的作用范围,即采用的最优化理论方法:
      • 局部立体匹配
        • 区域匹配: 可获取稠密视差图。缺点:受图像的仿射畸变和辐射畸变影响较大;像素点约束窗口的大小与形状选择比较困难,选择过大,在深度不连续处,视差图中会出现过度平滑现象;选择过小,对像素点的约束比较少,图像信息没有得到充分利用,容易产生误匹配。
        • 特征匹配: 可获得稀疏的视差图,经差值估计可获得稠密视差图。可提取点、线、面等局部特征,也可提取多边形和图像结构等全局特征。缺点:特征提取易受遮挡、光线、重复纹理等影响较大;差值估计计算量大
        • 相位匹配: 假定在图像对应点中,其频率范围内,其局部相位是相等的,在频率范围内进行视差估计
      • 全局立体匹配:
        • 动态规划:
        • 图割法:
        • 置信传播:
    • 按照生成的视差图:
      • 稠密匹配: 对于所有像素都能生成确定视差值
      • 稀疏匹配: 只选择关键像素点[通常为角点或者边缘点]计算视差值的方法称为稀疏匹配,该算法计算速度较快,但后续还需要通过插值算法计算缺失像素点的视差值,因此应用场景上有很大限制。

    二、算法优缺点比较:

    立体匹配算法名称 算法特性
    基于动态规划的立体匹配算法 时间复杂度比较低,匹配精度不高,容易出现条纹现象
    基于图割法的立体匹配算法 能解决动态规划出现的条纹现象,边缘匹配处理比较好,时间复杂度比较高
    基于置信度传播的立体匹配算法 收敛性比较差,时间复杂度比较高,对于低纹理问题处理的比较好
    基于区域的立体匹配算法 时间复杂度比较低,算法受环境影响比较大,弱纹理问题不能有效解决
    基于特征的立体匹配算法 时间复杂度比较低,对于几何特征明显的图像匹配效果比较好

    三、立体视觉基本原理:

    1.从两个点或多个点观察同一物体,获取不同视角下的二维图像, 根据三角测量原理计算空间点在二维图像的位置偏差, 运用位置偏差进行三维重建。从本质上看,就是以最小的代价在两幅图像上精确的寻找相同的像素点,找到一条最优的线路。因此设计立体匹配算法就是构建一种优化模型,求解最优解的过程。
    2.从各具特色的双目立体匹配算法框架来看,算法有效性主要依赖3 个因素,选择准确的匹配基元(决策变量)、寻找相应的匹配准则(目标函数和约束条件)、构建能够准确匹配所选基元的稳定算法(求解过程)。
    3.构建一个完整的立体匹配算法应从4 个方面着手:
    1. 广义匹配基元与特征参数选择;
    2. 匹配方法及策略;
    3. 匹配代价优化标准;
    4. 视差提炼方式
    3.1匹配基元:

    在图像中有明显特征的点、线或者特定的区域,它是立体匹配算法的最小匹配单元;
    匹配基元的选择,要考虑基元的稳定性、敏感性、可行性和能否表示图像。

    • 点:利用图像的局部特征信息作为匹配基元,表示一个像素,如像素灰度值,角点,边缘,卷积等;
      最基本的特征基元,所含有效的信息量相对较少;
      优点是对特征点定位准确、检测和描述像素点的信息更容易;
      采用点状特征作为基元的算法需要采用比较有力的约束准则及匹配策略来约束像素点;
      通常选择图像中的角点作为点状特征匹配基元。
    • 块:局部区域内所有像素的灰度、亮度特征值,对区域内所有像素进行变化
      如卷积、梯度变换和Censes变换等;
      块具有较好的全局属性,所含的信息量较为丰富,能够简单描述出事物的大致结构,在合适的图像中可以采用点状特征基元对场景进行三维重建;
    • 线:一般是像素灰度信息发生急剧变化的像素点集,最能体现边缘特征;
      检测边缘的算子如Sobel算子、Canny算子、Log算子和Prewitt算子等;
      线基元的特征介于点和块之间。
    3.2立体匹配约束准则:

    约束准则具有缩小匹配搜索的范围,降低误匹配,同时提高匹配效率的功能。

    • 极线约束:
      如图所示,
      三维空间的一个映射点,其匹配点必定在另一图像的极线上,理想情况下,匹配点对位于同一水平线上即坐标y值相同。故只需在对应的水平线上搜素匹配点,大大提高了匹配效率。

    注:真正用来匹配的图一般都是矫正好的图,即极线会映射一条水平的直接,匹配点在一条水平线上,即坐标y相同

    • 唯一性约束:
      三维空间点至多只一个图像上的映射点(遮挡则没有映射点),匹配时左右图像上只有唯一一个匹配点。
      连续性约束:
      三维空间中物体表面是光滑的,匹配得到的视差图大部分情况下是连续且光滑变化的。一般使用较小的视差梯度降低匹配的搜索范围和待匹配点的数量以提高匹配速度。
    • 相似性约束:
      三维空间中的物体在不同视角下投影产生的匹配基元(点、块、线)必须要有相同或相似的属性。由于光照等因素的影响,相似性约束具有局限性。
    • 顺序一致性约束:
      三维空间中物体上的点的位置信息在映射到两幅图像上的位置顺序不会改变。
      这是不透明物体表面投影的几何学必然性。
    • 平滑性约束:
      假设三维空间中物体表面是平滑的,则视差图上除物体边界位置会有大的视差波动以外,其他位置上匹配视差的变化很小。
    • 左右一致性约束:
      左参考图像素点p点在右匹配图上的点是q,则右参考图上像素点q在左匹配图上是p。如果两次搜索的结果不对应,则该点不可靠。
      常用于遮挡区域的检测,然后再对遮挡点做一些其他处理。
    • 视差范围约束:
      两台摄像机之间具有一定的距离,在沿极线搜索时,搜索的范围应小于一定的阈值。视差范围约束限制了搜索的范围。

    四、数据集:

    • 1.SceneFlow(Synthetic):
      Synthetic data
      39, 000 training/ 2, 000 testing
      960*540 pixels
      在这里插入图片描述在这里插入图片描述

    • 2.KITTI 2012/2015:
      Autonomous driving data (LIDAR)
      200 training / 200 testing (2012)
      1260*370 pixels

    五、立体匹配步骤:

    • 1.匹配代价计算
    C(x, y, z) = L(x + d, y) − R(x, y) 
    L:双目立体视觉系统中的左视图, 
    R:双目立体视觉系统中的右视图, 
    x和 y 分别表示像素点的坐标值,
    d像素点的视差值。
    

    匹配代价计算的目的是计算参考图像上的每一个待匹配像素与目标图上每一个可能的视差范围内的候选像素之间的相关性,最后得到一个大小为W×H×D (D为视差搜索范围)的代价矩阵C(也叫视差空间图Disparity Space Image,DSI),代价计算算法是双目匹配的核心之一,不同的计算方式有不同的优势,有时候可以结合多种计算方法。

    比如Census保留周边像素空间信息,对光照变化有一定鲁棒性,具有灰度不变的特性,AD边缘明显清晰,纹理重复结构效果还可以,不适用于噪声多的情况,低纹理区域效果不好,对颜色值敏感,AD和Census结构可以取一个折中。

    常用的相关性计算方式有灰度绝对值差(AD,Absolute Differences)、灰度绝对值差之和(SAD,Sum of Absolute Differences)、归一化相关系数(NCC,Normalized Cross-correlation)、互信息(MI,Mutual Information)、Census变换(CT,Census Transform)法、Rank变换(RT, Rank Transform等方法来计算两个像素的匹配代价。

    • 2.代价聚合
      局部立体匹配算法匹配时的代价只考虑以匹配像素为中心一个小窗口之间的相关性,没有考虑全局信息,不适用于低纹理或者重复纹理,对噪声敏感,所以一般需要代价聚合让代价值能够准确的反映像素之间的相关性。
      每个像素在每个视差下的新代价值都会根据其相邻像素在同一视差值或者附近视差值下的代价值来重新计算,得到新的DSI,相当于更新了一下DSI。
      代价聚合其实是视差传播的步骤,因为相邻像素一般具有连续的视差值,考虑进来可以降低噪声的影响,也可以提升低纹理或重复纹理效果。
      常用的代价聚合方法有扫描线法、动态规划法、SGM算法中的路径聚合法等。
    • 3.视差计算
      通常采用‘赢者通吃’策略(WTA,Winner Take All),即在视差搜索范围内选择累积代价最优的点作为对应匹配点,与之对应的视差即为所求的视差。
    • 4.视差优化
      最后还需要对视差图做优化,包括左右一致性检查算法剔除因为遮挡和噪声而导致的错误视差;采用剔除小连通区域算法来剔除孤立异常点;采用中值滤波、双边滤波等平滑算法对视差图进行平滑,还有插值和亚像素增强等方法也常被使用。

    六、立体匹配相似性测度:

    匹配代价 公式 说明
    绝对差值和SAD 在这里插入图片描述
    截断绝对差值和STAD 在这里插入图片描述
    差值平方和SSD 在这里插入图片描述
    归一化互关系NCC 在这里插入图片描述 用于归一化待匹配目标之间的相关程度
    census 在这里插入图片描述 计算左右图的二进制序列的海明距离,也可以用异或操作计算。seq[I§]函数根据p点像素值和p的支持窗口内像素值生成一个二进制序列。即根据p点周围像素和p点关系是生成,如大于p点则为1,小于为0,左右图都生成这样的序列,然后计算两个序列的汉明距离作为代价,这种方法充分考虑了图像局部相关的特性,而不是直接使用灰度值做差,具有抗光影畸变的作用,效率高、稳定性强
    rank变换函数 在这里插入图片描述 对图像噪声和立体图像的亮度差异不那么敏感,且计算快,实时性好。

    常用的census: 计算每个待匹配像素和周围像素的大小关系,当左图某像素和右图对应像素与周围像素大小关系一致时(比如都大于周围某像素),则diff + 1, 否则diff不变, 其实diff记录的是汉明距离。
    AD也经常和census合用

    展开全文
  • 双目立体匹配算法SGBM

    万次阅读 多人点赞 2018-08-07 23:01:20
    semi-global matching(SGM)是一种用于计算双目视觉中视差(disparity)的半全局匹配算法,在OpenCV中的实现为semi-global block matching(SGBM)。 第一部分:SGBM算法原理: 一、预处理 Step1:SGBM采用水平...

    semi-global matching(SGM)是一种用于计算双目视觉中视差(disparity)的半全局匹配算法,在OpenCV中的实现为semi-global block matching(SGBM)。

    第一部分:SGBM算法原理:

    一、预处理

    Step1:SGBM采用水平Sobel算子,把图像做处理,公式为:

    Sobel(x,y)=2[P(x+1,y)-P(x-1,y)]+ P(x+1,y-1)-P(x-1,y-1)+ P(x+1,y+1)-P(x-1,y+1)

    Step2:用一个函数将经过水平Sobel算子处理后的图像上每个像素点(P表示其像素值)映射成一个新的图像:PNEW表示新图像上的像素值。

    映射函数:

    preFilterCap 为一个常数参数,opencv缺省情况下取15,例程中取63。

    预处理实际上是得到图像的梯度信息,将预处理的图像保存起来,将会用于计算代价。

    二、代价计算

    代价有两部分组成:

    1、经过预处理得到的图像的梯度信息经过基于采样的方法得到的梯度代价。

    2、原图像经过基于采样的方法得到的SAD代价。

    上述两个代价都会在SAD窗口内进行计算。

    三、动态规划

    动态规划算法本身存在拖尾效应,视差突变处易产生错误的匹配,利用态规划进行一维能量累积累,会将错误的视差信息传播给后面的路径上。半全局算法利用多个方向上的信息,试图消除错误信息的干扰,能明显减弱动态规划算法产生的拖尾效应。

    半全局算法试图通过影像上多个方向上一维路径 的约束,来建立一个全局的马尔科夫能量方程,每个像素最终的匹配代价是所有路径信息的叠加,每个像素的视差选择都只是简单通过 WTA(Winner Takes All)决定的。多方向能量聚集如下图所示:

    在每个方向上按照动态规划的思想进行能量累积,然后将各个方向上的匹配代价相加得到总的匹配代价,如下式所示:

    式中L为当前路径累积的代价函数,P1、P2为像素点与相邻点视差存在较小和较大差异情况下的平滑惩罚,P1<P2,第三项无意义,仅仅是为了消除各个方向路径长度不同造成的影响。将所有r方向的匹配代价相加得到总的匹配代价,如下:

    默认4条路径,其中动态规划很重要两个参数P1,P2是这样设定的:

    P1 =8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

    P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

    cn是图像的通道数, SADWindowSize是SAD窗口大小,数值为奇数。

    可以看出,当图像通道和SAD窗口确定下来,SGBM的规划参数P1和P2是常数

    四、后处理

    opencvSGBM的后处理包含以下几个步骤:

    Step1:唯一性检测:视差窗口范围内最低代价是次低代价的(1 + uniquenessRatio/100)倍时,最低代价对应的视差值才是该像素点的视差,否则该像素点的视差为0。其中uniquenessRatio是一个常数参数。

    Step2:亚像素插值:

           插值公式:

    Step3:左右一致性检测:误差阈值disp12MaxDiff默认为1,可以自己设置。

    OpencvSGBM计算右视差图的方式:

    通过得到的左视察图计算右视差图

     

     

    第二部分:opencv中SGBM算法的参数含义及数值选取

    一、 预处理参数

    1:preFilterCap:水平sobel预处理后,映射滤波器大小。默认为15

    int ftzero =max(params.preFilterCap, 15) | 1;

    opencv测试例程test_stereomatching.cpp中取63。

    二 、代价参数

    2:SADWindowSize:计算代价步骤中SAD窗口的大小。由源码得,此窗口默认大小为5。

    SADWindowSize.width= SADWindowSize.height = params.SADWindowSize > 0 ?params.SADWindowSize : 5;

    注:窗口大小应为奇数,一般应在3x3到21x21之间。

    3:minDisparity:最小视差,默认为0。此参数决定左图中的像素点在右图匹配搜索的起点。int 类型

    4:numberOfDisparities:视差搜索范围,其值必须为16的整数倍(CV_Assert( D % 16 == 0 );)。最大搜索边界= numberOfDisparities+ minDisparity。int 类型

    三 、动态规划参数

    动态规划有两个参数,分别是P1、P2,它们控制视差变化平滑性的参数。P1、P2的值越大,视差越平滑。P1是相邻像素点视差增/减 1 时的惩罚系数;P2是相邻像素点视差变化值大于1时的惩罚系数。P2必须大于P1。需要指出,在动态规划时,P1和P2都是常数。

    5:opencv测试例程test_stereomatching.cpp中,P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

    6:opencv测试例程test_stereomatching.cpp中,P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

    四、后处理参数

    7:uniquenessRatio:唯一性检测参数。对于左图匹配像素点来说,先定义在numberOfDisparities搜索区间内的最低代价为mincost,次低代价为secdmincost。如果满足

    即说明最低代价和次第代价相差太小,也就是匹配的区分度不够,就认为当前匹配像素点是误匹配的。

    opencv测试例程test_stereomatching.cpp中,uniquenessRatio=10。int 类型

    8:disp12MaxDiff:左右一致性检测最大容许误差阈值。int 类型

    opencv测试例程test_stereomatching.cpp中,disp12MaxDiff =1。

    9:speckleWindowSize:视差连通区域像素点个数的大小。对于每一个视差点,当其连通区域的像素点个数小于speckleWindowSize时,认为该视差值无效,是噪点。

    opencv测试例程test_stereomatching.cpp中,speckleWindowSize=100。

    10:speckleRange:视差连通条件,在计算一个视差点的连通区域时,当下一个像素点视差变化绝对值大于speckleRange就认为下一个视差像素点和当前视差像素点是不连通的。

    opencv测试例程test_stereomatching.cpp中,speckleWindowSize=10。

     

    第三部分:C++实现

    #include <opencv2/opencv.hpp>  
    #include <iostream>  
    
    using namespace std;
    using namespace cv;
    
    const int imageWidth = 672;  //摄像头的分辨率  
    const int imageHeight = 376;
    Size imageSize = Size(imageWidth, imageHeight);
    
    Mat grayImageL,grayImageR;
    Mat rectifyImageL, rectifyImageR;
    
    Rect validROIL;//图像校正之后,会对图像进行裁剪,这里的validROI就是指裁剪之后的区域, 其内部的所有像素都有效
    Rect validROIR;
    
    Mat mapLx, mapLy, mapRx, mapRy;     //映射表  
    Mat Rl, Rr, Pl, Pr, Q;              //校正旋转矩阵R,投影矩阵P 重投影矩阵Q
    Mat xyz;              //三维坐标
    
    Point origin;     //鼠标按下的起始点
    Rect selection;      //定义矩形选框
    bool selectObject = false;    //是否选择对象
    
    int numberOfDisparities = ((imageSize.width / 8) + 15) & -16;
    int numDisparities = 6;
    
    cv::Ptr<cv::StereoSGBM> sgbm = StereoSGBM::create(0, 16, 3);
    
    Mat cameraMatrixL = (Mat_<double>(3, 3) << 350.11095, 0, 339.81480,
    	0, 349.39869, 200.42205,
    	0, 0, 1);
    Mat distCoeffL = (Mat_<double>(5, 1) << -0.16028, 0.00600, -0.00009, -0.00047, 0.00000);
    
    Mat cameraMatrixR = (Mat_<double>(3, 3) << 351.08207, 0, 343.68828,
    	0, 350.19118, 210.18586,
    	0, 0, 1);
    Mat distCoeffR = (Mat_<double>(5, 1) << -0.17678, 0.02713, -0.00033, -0.00109, 0.00000);
    //左右目之间的R,t可通过stereoCalibrate()或matlab工具箱calib求得
    Mat T = (Mat_<double>(3, 1) << -119.61078, -0.06806, 0.08105);//T平移向量
    Mat rec = (Mat_<double>(3, 1) << 0.00468, 0.02159, 0.00015);//rec旋转向量
    Mat R;//R 旋转矩阵
    Mat frame, f1, f2;
    Mat disp, disp8;
    
    /*****立体匹配*****/
    void stereo_match(int, void*)
    {
    	sgbm->setPreFilterCap(32);
    	int SADWindowSize = 9;
    	int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
    	sgbm->setBlockSize(sgbmWinSize);
    	int cn = rectifyImageL.channels();
    	sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
    	sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
    	sgbm->setMinDisparity(0);
    	sgbm->setNumDisparities(numberOfDisparities);
    	sgbm->setUniquenessRatio(10);
    	sgbm->setSpeckleWindowSize(100);
    	sgbm->setSpeckleRange(32);
    	sgbm->setDisp12MaxDiff(1);
    	sgbm->setMode(cv::StereoSGBM::MODE_SGBM);
    	sgbm->compute(rectifyImageL, rectifyImageR, disp);//输入图像必须为灰度图
    
    	disp.convertTo(disp8, CV_8U, 255 / ((numDisparities * 16 + 16)*16.));//计算出的视差是CV_16S格式
    	reprojectImageTo3D(disp, xyz, Q, true); //在实际求距离时,ReprojectTo3D出来的X / W, Y / W, Z / W都要乘以16(也就是W除以16),才能得到正确的三维坐标信息。
    	xyz = xyz * 16;
    	imshow("disparity", disp8);
    }
    
    /*****描述:鼠标操作回调*****/
    static void onMouse(int event, int x, int y, int, void*)
    {
    	if (selectObject)
    	{
    		selection.x = MIN(x, origin.x);
    		selection.y = MIN(y, origin.y);
    		selection.width = std::abs(x - origin.x);
    		selection.height = std::abs(y - origin.y);
    	}
    
    	switch (event)
    	{
    	case EVENT_LBUTTONDOWN:   //鼠标左按钮按下的事件
    		origin = Point(x, y);
    		selection = Rect(x, y, 0, 0);
    		selectObject = true;
    		cout << origin << "in world coordinate is: " << xyz.at<Vec3f>(origin) << endl;
    		break;
    	case EVENT_LBUTTONUP:    //鼠标左按钮释放的事件
    		selectObject = false;
    		if (selection.width > 0 && selection.height > 0)
    			break;
    	}
    }
    
    
    /*****主函数*****/
    int main()
    {
    	Rodrigues(rec, R); //Rodrigues变换
    	//经过双目标定得到摄像头的各项参数后,采用OpenCV中的stereoRectify(立体校正)得到校正旋转矩阵R、投影矩阵P、重投影矩阵Q
    	//flags-可选的标志有两种零或者 CV_CALIB_ZERO_DISPARITY ,如果设置 CV_CALIB_ZERO_DISPARITY 的话,该函数会让两幅校正后的图像的主点有相同的像素坐标。否则该函数会水平或垂直的移动图像,以使得其有用的范围最大
    	//alpha-拉伸参数。如果设置为负或忽略,将不进行拉伸。如果设置为0,那么校正后图像只有有效的部分会被显示(没有黑色的部分),如果设置为1,那么就会显示整个图像。设置为0~1之间的某个值,其效果也居于两者之间。
    	stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR, imageSize, R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY,
    		0, imageSize, &validROIL, &validROIR);
    	//再采用映射变换计算函数initUndistortRectifyMap得出校准映射参数,该函数功能是计算畸变矫正和立体校正的映射变换
    	initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pr, imageSize, CV_32FC1, mapLx, mapLy);
    	initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr, imageSize, CV_32FC1, mapRx, mapRy);
    
    	VideoCapture cap(0);
    	cap.set(CAP_PROP_FRAME_HEIGHT, 376);
    	cap.set(CAP_PROP_FRAME_WIDTH, 1344);
    	namedWindow("disparity", CV_WINDOW_AUTOSIZE);
    	namedWindow("paramemnt", CV_WINDOW_NORMAL);
    	createTrackbar("numDisparities:\n", "paramemnt", &numDisparities, 20, stereo_match);
    	setMouseCallback("disparity", onMouse, 0);
    	
    	while (1)
    	{
    		cap >> frame;
    		imshow("video", frame);
    		f1 = frame.colRange(0, 672);
    		f2 = frame.colRange(672, 1344);
    
    		cvtColor(f1, grayImageL, CV_BGR2GRAY);
    		cvtColor(f2, grayImageR, CV_BGR2GRAY);
    		//然后用remap来校准输入的左右图像
    		//interpolation-插值方法,但是不支持最近邻插值
    		remap(grayImageL, rectifyImageL, mapLx, mapLy, INTER_LINEAR);
    		remap(grayImageR, rectifyImageR, mapRx, mapRy, INTER_LINEAR);
    
    		stereo_match(0, 0);
    		waitKey(1);
    	}
    	waitKey(0);
    	return 0;
    }
    

    运行效果:

     

    参考:

    Accurate and Efficient Stereo Processing by Semi-Global Matching and Mutual Information

    opencvSGBM半全局立体匹配算法的研究(1)

    semi-global matching 算法总结

    密集匹配之半全局匹配SGBM

    【OpenCV】双目测距(双目标定、双目校正和立体匹配)

    双摄像头立体成像(三)-畸变矫正与立体校正

    双目立体匹配经典算法之Semi-Global Matching(SGM)概述:匹配代价计算之Census变换(Census Transform,CT)(附计算C代码)

    展开全文
  • 立体匹配:在左右图像上寻找对应的匹配点,利用三角测量原理计算视差 传统立体匹配有四个步骤:匹配代价计算,代价聚合、代价最优化计算、视差调整 匹配代价计算:针对双目摄像机拍到的一对图像,针对图像上的某点,...

    记录下Binocular Stereo Matching 的点

    1. 双目立体视觉系统可以根据左右相机拍摄得到的场景图像,恢复图像中物体的位置、外部特征等信息,还可以恢复出场景里障碍物的位置,本质是从二维图像中恢复出三维信息的问题
    2. 双目立体视觉系统包含:离线相机标定、双目图像采集和矫正、立体匹配、计算深度信息
    3. 立体匹配:在左右图像上寻找对应的匹配点,利用三角测量原理计算视差
    4. 传统立体匹配有四个步骤:匹配代价计算,代价聚合、代价最优化计算、视差调整
    5. 匹配代价计算:针对双目摄像机拍到的一对图像,针对图像上的某点,在经过极线约束过后的右幅图像上的同水平方向上找到同源点,计算两个点的相似性。匹配代价计算分为两类,一个是根据原始图像的像素的相似性去比较,比如比较左右视图内对应的一个区域内的全部像素求差的绝对值再求和(SAD),另一个就是根据特征描述的角度上比较,比如SIFT、BRIEF,构建成功的匹配代价函数是立体匹配算法的关键,设计出抗干扰、抗噪声并且对光照保持不敏感的代价函数可以有效提升立体匹配的精度,所以匹配代价函数在基于全局优化的立体匹配算法和基于局部优化的立体匹配算法
    6. 匹配代价聚合:将待匹配的像素点周围一个匹配窗口,将这个窗口范围内的所有像素点计算匹配代价,,再对全部的匹配代价进行求和或者平均值,把这个值作为该待匹配下像素点的匹配代价。根据窗口内像素点到中心点像素的距离作为不同权重来对匹配代价进行加和的方法称为高斯滤波匹配法
    7. 代价最优化计算:选择匹配代价函数最小的那个像素点是真实对应的匹配点。但是对于弱纹理和重复纹理的区域,经常出现很多区域与待匹配区域相似,所以基于局部优化算法针对这种图像匹配效果较差。代价最优化计算的目的是让匹配代价函数能够更加真实反映出待匹配区域和真实区域的相似性,全局优化算法没有代价聚合步骤,全局优化的立体匹配算法选择构造全局能量函数的方法,在代价匹配中增加平滑项,目标像素的能量函数值与其领域范围的近点的像素的能量函数值差距较小,与领域内函数距离较远点的能量函数值差距大
    8. 视差图后处理:为了提升最后的匹配精度。大部分立体算法得到的视差图是离散的,经过例如采用中值滤波算法连续化最终的视差图,得到更加精确的预测视差图
    9. 传统立体匹配算法:体现在立体匹配过程中需要人工设计匹配代价函数,选择匹配特征。根据采用最优化理论方法的不同,分为基于局部优化的算法、全局优化和半全局优化算法
    10. 基于局部优化:基于窗口。根据待匹配视点的局部区域特征,建立区域特征相似性函数,再通过最优化这个函数的方法里寻找最佳匹配点,并且计算该匹配点的视差值。用中心像素点的灰度、梯度、颜色等信息构建匹配函数。对弱纹理、重复纹理、视差不连续效果差
    11. 基于全局优化:采用全局最优化理论构建一个全局能量函数,再最优化这个能量函数来寻找最佳匹配点
    12. 基于半全局优化:基于全局优化的动态规划算法中发展出,采用一维搜索路径的动态规划,在构建能量函数中加入平滑项。首先建立匹配基元,构建多个方向上的能量代价函数,得到能量代价函数的最优解,得到结果的视差图
    13. 基于深度学习的立体匹配算法:一种计算匹配代价:输入图像块,计算图像块的相似性,比如MC-CNN。另一种是输入左右场景图像,直接输出视差图,实现端到端的卷积神经网络,比如DispNet、GC-Net、PSMNet
    展开全文
  • 1.算法原理 SAD(Sum of absolute differences)是一种图像匹配算法。基本思想:差的绝对值之和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。该算法快速、但并不精确...

    1.算法原理
    SAD(Sum of absolute differences)是一种图像匹配算法。基本思想:差的绝对值之和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。该算法快速、但并不精确,通常用于多级处理的初步筛选。
    公式如下:
    在这里插入图片描述

    2.基本流程
    输入:两幅图像,一幅LeftImage,一幅RightImage且两幅图像已经校正实现行对准
    对左图,依次扫描,选定一个像素点:

    (1)以该像素点为中心构造一个公式小窗口,类似于卷积核;
    (2)用窗口覆盖左边的图像,选择出窗口覆盖区域内的所有像素点;
    (3)同样用窗口覆盖右边的图像并选择出覆盖区域的像素点;
    (4)左边覆盖区域减去右边覆盖区域,并求出所有像素点灰度差的绝对值之和;
    (5)移动右边图像的窗口,重复(3)-(4)的处理(这里有个搜索范围,超过这个范围跳出);
    (6)找到这个范围内SAD值最小的窗口,即找到了左图锚点的最佳匹配的像素块。

    3.matlab程序

    clear all
    clc
    
    left=double(rgb2gray(imread('C:\Users\Administrator\Desktop\scene1.row1.col1.ppm')));  %读取左图,并转换成灰度图
    right=double(rgb2gray(imread('C:\Users\Administrator\Desktop\scene1.row1.col2.ppm')));   %读取右图,并转换成灰度图
    [m n]=size(left);
    
    w=4;    %窗口半径
    dmax=16;    %最大偏移距离,同样也是最大深度距离
    shicha=ones(m,n);  
    shicha=shicha*3;  %给视差图所有位置赋一个较大的初始视差值,避免图像扫描的空缺
    for i=1+w:1:m-w  %图像的行
        for j=1+w:1:n-w   %图像的列
            min=5000; tmpd=0; tmp=0;diff=[];
            for d=0:1:dmax   %视差允许范围
               if(j+w+d<=n)   %窗口的列不能超出图片的范围
            lwin=left(i-w:i+w,j-w+d:j+w+d); %左图子窗口
                  rwin=right(i-w:i+w,j-w:j+w);  %右图子窗口
    
                     diff=abs(rwin-lwin);  %以右图为基准图
                     tmp=sum(sum(diff(:)));  %窗口内所有灰度值之差求和
                  end
                  if(tmp<min)   %计算出的代价之,与最初设定的一个最大代价值比较
                      min=tmp;
                      tmpd=d;
                  end
              end
                  shicha(i,j)=tmpd;   %将视差存入空间视差矩阵中
        end
    end
    imshow(shicha,[]);  %显示视差图
    

    在这里插入图片描述
    这是第一次发布博客,程序可能还有不完善的地方欢迎指导修正。后续还有SGM半全局算法等。

    展开全文
  • 双目立体视觉匹配(1.双目原理

    千次阅读 2018-09-27 15:45:59
    全局立体匹配大体思路 双目摄像机的物理机构 网上大部分人都写了这一点,也仿佛只有这一点有写的价值和物理意义。 这里本来想放个控件(可调节动画),一直弄不上来,就算了。需要的可以联系我要下,下面放两张...
  • 第一种称为块匹配(BM, Block matching)算法,是一种快速有效的算法,它的工作原理是使用小的“绝对差值之和”(SAD)窗口来找到左右立体校正图像之间的匹配点。该算法仅在两个图像之间找到强匹配...
  • 本质上, 基于光度测量学不变性原理的区域匹配算法, 常以邻域窗的灰度为匹配基元, 以相关程度作为判别依据, 可以得到较稠密的视差图.从灰度相关性和非参数变换思想两个方面进行分类. 灰度相关性算法的研究主要.
  • 双目立体视觉数学原理

    千次阅读 2019-01-21 11:13:38
    双目立体视觉技术的实现一般可分为:图像获取、摄像机标定、特征提取、图像匹配和三维重建几个步骤。双目立体视觉是基于视差原理,由三角法原理进行三维信息的获取,即由两个摄像机的图像平面和北侧物体之间构成一个...
  • 另外,这篇文章的作者估计也很讨厌黑盒子式的端到端,所以整篇文章都在强调网络结构设计的合理性与原理。 网络结构 上图展示了GC-Net的整个网络结构,不难发现,其虽然是一个端到端的网络;但是仍旧被显著的分成了...
  • 双目立体匹配算法--SAD(C++\FPGA)

    千次阅读 2017-08-28 11:07:44
    SAD(Sum of absolute differences)是一种图像局部匹配算法。 1、本文结构 首先介绍SAD算法的基本原理与流程,之后使用C++和Verilog实现算法,分析对比两者区别,与。。对比,分析原因。 2、算法流程 输入:左摄像...
  • 根据立体匹配原理,采用双目摄像头对图像进行采集,通过对摄像机的标定和图像立体校正、图像分割与立体匹配得到最后的视差图;根据最后的视差图以及算法的速度来评价算法的性能。实验结果表明,图像的视差图十分接近...
  • 双目立体视觉深度相机的工作流程双目立体视觉深度相机详细工作原理理想双目相机成像模型极线约束图像矫正技术基于滑动窗口的图像匹配基于能量优化的图像匹配双目立体视觉深度相机的优缺点--------------------------...
  • 双目立体视觉的原理

    千次阅读 2017-07-12 22:41:27
    基本原理 双目视觉的基本原理就是模拟人眼并利用空间几何模型推导出相应的算法来解决实际问题。...2.立体匹配 3.双目标定 举例说明 下面以机器人导航应用为例进行说明,在这个应用中需要做的事情就是告诉
  • 原理: 对于原始的图像内任意一个像素点(px,py)(p_x,p_y)(px​,py​)构建一个n×nn\times nn×n的邻域作为匹配窗口。然后对于目标相素位置(px+d,py)(p_x+d, p_y)(px​+d,py​)同样构建一个n×nn\times nn×n大小的...
  • SAD进行双目立体视觉匹配(Python语言)1 编译环境2 算法原理介绍3 基本流程3.1 步骤3.2 示意图4 代码(Python)5 运行结果6 结论 1 编译环境 编程语言:Python IDE:PyCharm 2017 2 算法原理介绍 SAD(Sum of ...
  • 随着机器视觉的飞速发展,基于视差原理双目立体视觉已逐渐成为科学研究的核心。 本文简要介绍了背景和研究意义,阐述了国内外双目视觉机器人的研究现状,研究了棋盘格校正方法,并利用Matlab完成了双目相机的校正...
  • OpenCV中StereoCalibrate标定的结果极其不稳定,甚至会得到很夸张的结果,所以决定Matlab标定工具箱立体标定,再将标定的结果读入OpenCV,来进行后续图像校准和匹配。 采集棋盘图的时候要注意,尽量让棋盘占据...
  • 双目立体视觉深度相机的工作流程双目立体视觉深度相机详细工作原理理想双目相机成像模型极线约束图像矫正技术基于滑动窗口的图像匹配基于能量优化的图像匹配双目立体视觉深度相机的优缺点--------------------------...
  • Evision双目视觉关于双目视觉的一些总结相机模型标定视差算法:立体匹配重投影:测量,三维重建,重投影约束三维重建示例程序 关于双目视觉的一些总结 笔者2013年进入吉林大学软件学院,2014年开始写自己的第一个完整的...
  • 1.算法原理 SAD(Sum of absolute differences)是一种图像匹配算法。基本思想:差的绝对值之和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。该算法快速、但并不精确...
  • 深度相机原理揭秘–双目立体视觉 为什么非得用双目相机才能得到深度? 双目立体视觉深度相机的工作流程 双目立体视觉深度相机详细工作原理 理想双目相机成像模型 极线约束 图像矫正技术 基于滑动窗口的图像匹配 基于...
  • 第五章:1. 双目立体视觉2. 窗口匹配方法3.NCC(归一化相关性)4....双目立体视觉(Binocular Stereo Vision是机器视觉的一种重要形式,它是基于视差原理并利用成像设备从不同的位置获取被测物体的两幅图像...
  • 双目散斑立体视觉系统原理解析

    千次阅读 2019-05-06 22:10:19
    概念 在目前的消费级3D传感器中,双目立体视觉是比较常见的结构。然而,本文所讲的双目散斑立体视觉系统与单纯的双目立体视觉有些...在传统的双目立体视觉中(如图1所示),核心问题是如何从匹配图像中找到对应于...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 156
精华内容 62
关键字:

双目立体匹配原理