双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法

【算法】OpenCV-SGBM算法及源码的简明分析 OpenCV-SGBM的源码在/modules/calib3d/src/stereosgbm.cpp中, 博主用的opencv版本为4.5.2 BT代价就是计算两个像素之间的相似度(或者,代价cost) 阅读详情

一、 SAD算法

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

输入:两幅图像,一幅Left-Image,一幅Right-Image

对左图,依次扫描,选定一个锚点:

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

参考代码:SAD.h

 

#include"iostream"
#include"opencv2/opencv.hpp"
#include"iomanip"
using namespace std;
using namespace cv;

class SAD
{
	public:
		SAD():winSize(7),DSR(30){}
		SAD(int _winSize,int _DSR):winSize(_winSize),DSR(_DSR){}
		Mat computerSAD(Mat &L,Mat &R); //计算SAD
	private:
		int winSize; //卷积核的尺寸
		int DSR;     //视差搜索范围
	
};

 Mat SAD::computerSAD(Mat &L,Mat &R)
	{
		int Height=L.rows;
	    int Width=L.cols;
		Mat Kernel_L(Size(winSize,winSize),CV_8U,Scalar::all(0));
	    Mat Kernel_R(Size(winSize,winSize),CV_8U,Scalar::all(0));
	    Mat Disparity(Height,Width,CV_8U,Scalar(0)); //视差图

		for(int i=0;i<Width-winSize;i++)  //左图从DSR开始遍历
		{
			for(int j=0;j<Height-winSize;j++)
			{
				Kernel_L=L(Rect(i,j,winSize,winSize));
			    Mat MM(1,DSR,CV_32F,Scalar(0)); //

				for(int k=0;k<DSR;k++)
				{
					int x=i-k;
					if(x>=0)
					{
					Kernel_R=R(Rect(x,j,winSize,winSize));
					Mat Dif;
			        absdiff(Kernel_L, Kernel_R, Dif);//
					Scalar ADD=sum(Dif);
					float a=ADD[0];
					MM.at<float>(k)=a;
					}
					
				}
				Point minLoc;
                minMaxLoc(MM, NULL, NULL,&minLoc,NULL);
			    
				int loc=minLoc.x;
				//int loc=DSR-loc;
				Disparity.at<char>(j,i)=loc*16;
				
			}
			double rate=double(i)/(Width);
			cout<<"已完成"<<setprecision(2)<<rate*100<<"%"<<endl; //处理进度
		}
		return Disparity;
	}
// MySAD.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"SAD.h"
int _tmain(int argc, _TCHAR* argv[])
{
	Mat Img_L=imread("imL.png",0);
	Mat Img_R=imread("imR.png",0);
    Mat Disparity;    //视差图
    
	//SAD mySAD;
	SAD mySAD(7,30);
	Disparity=mySAD.computerSAD(Img_L,Img_R);

	imshow("Img_L",Img_L);
	imshow("Img_R",Img_R);
	imshow("Disparity",Disparity);
	waitKey();
	return 0;
}
 

二、BM算法:速度很快,效果一般

 

 

SGBM算法 Stereo Processing by Semiglobal Matching and Mutual Information

GC算法 算法文献:Realistic CG Stereo Image Dataset with Ground Truth Disparity Maps

参考:http://blog.youkuaiyun.com/wqvbjhc/article/details/6260844

 

[cpp] view plain copy

 

  1. <code class="language-cpp">void BM()  
  2. {  
  3.   IplImage * img1 = cvLoadImage("left.png",0);  
  4.     IplImage * img2 = cvLoadImage("right.png",0);  
  5.     CvStereoBMState* BMState=cvCreateStereoBMState();  
  6.     assert(BMState);  
  7.     BMState->preFilterSize=9;  
  8.     BMState->preFilterCap=31;  
  9.     BMState->SADWindowSize=15;  
  10.     BMState->minDisparity=0;  
  11.     BMState->numberOfDisparities=64;  
  12.     BMState->textureThreshold=10;  
  13.     BMState->uniquenessRatio=15;  
  14.     BMState->speckleWindowSize=100;  
  15.     BMState->speckleRange=32;  
  16.     BMState->disp12MaxDiff=1;  
  17.   
  18.     CvMat* disp=cvCreateMat(img1->height,img1->width,CV_16S);  
  19.     CvMat* vdisp=cvCreateMat(img1->height,img1->width,CV_8U);  
  20.     int64 t=getTickCount();  
  21.     cvFindStereoCorrespondenceBM(img1,img2,disp,BMState);  
  22.     t=getTickCount()-t;  
  23.     cout<<"Time elapsed:"<<t*1000/getTickFrequency()<<endl;  
  24.     cvSave("disp.xml",disp);  
  25.     cvNormalize(disp,vdisp,0,255,CV_MINMAX);  
  26.     cvNamedWindow("BM_disparity",0);  
  27.     cvShowImage("BM_disparity",vdisp);  
  28.     cvWaitKey(0);  
  29.     //cvSaveImage("cones\\BM_disparity.png",vdisp);  
  30.     cvReleaseMat(&disp);  
  31.     cvReleaseMat(&vdisp);  
  32.     cvDestroyWindow("BM_disparity");  
  33. }</code>  

 

 

 

三、SGBM算法

作为一种全局匹配算法,立体匹配的效果明显好于局部匹配算法,但是同时复杂度上也要远远大于局部匹配算法。算法主要是参考Stereo Processing by Semiglobal Matching and Mutual Information。

opencv中实现的SGBM算法计算匹配代价没有按照原始论文的互信息作为代价,而是按照块匹配的代价。

参考:http://www.opencv.org.cn/forum.php?mod=viewthread&tid=23854

#include <highgui.h>
#include <cv.h>
#include <cxcore.h>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{

    IplImage * img1 = cvLoadImage("left.png",0);
    IplImage * img2 = cvLoadImage("right.png",0);
    cv::StereoSGBM sgbm;
    int SADWindowSize = 9;
    sgbm.preFilterCap = 63;
    sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
    int cn = img1->nChannels;
    int numberOfDisparities=64;
    sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
    sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
    sgbm.minDisparity = 0;
    sgbm.numberOfDisparities = numberOfDisparities;
    sgbm.uniquenessRatio = 10;
    sgbm.speckleWindowSize = 100;
    sgbm.speckleRange = 32;
    sgbm.disp12MaxDiff = 1;
    Mat disp, disp8;
    int64 t = getTickCount();
    sgbm((Mat)img1, (Mat)img2, disp);
    t = getTickCount() - t;
    cout<<"Time elapsed:"<<t*1000/getTickFrequency()<<endl;
    disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));

    namedWindow("left", 1);
    cvShowImage("left", img1);
    namedWindow("right", 1);
    cvShowImage("right", img2);
    namedWindow("disparity", 1);
    imshow("disparity", disp8);
    waitKey();
    imwrite("sgbm_disparity.png", disp8);   
    cvDestroyAllWindows();
    return 0;
}


 

四、GC算法 效果最好,速度最慢

 

void GC()
{
    IplImage * img1 = cvLoadImage("left.png",0);
    IplImage * img2 = cvLoadImage("right.png",0);
    CvStereoGCState* GCState=cvCreateStereoGCState(64,3);
    assert(GCState);
    cout<<"start matching using GC"<<endl;
    CvMat* gcdispleft=cvCreateMat(img1->height,img1->width,CV_16S);
    CvMat* gcdispright=cvCreateMat(img2->height,img2->width,CV_16S);
    CvMat* gcvdisp=cvCreateMat(img1->height,img1->width,CV_8U);
    int64 t=getTickCount();
    cvFindStereoCorrespondenceGC(img1,img2,gcdispleft,gcdispright,GCState);
    t=getTickCount()-t;
    cout<<"Time elapsed:"<<t*1000/getTickFrequency()<<endl;
    //cvNormalize(gcdispleft,gcvdisp,0,255,CV_MINMAX);
    //cvSaveImage("GC_left_disparity.png",gcvdisp);
    cvNormalize(gcdispright,gcvdisp,0,255,CV_MINMAX);
    cvSaveImage("GC_right_disparity.png",gcvdisp);


    cvNamedWindow("GC_disparity",0);
    cvShowImage("GC_disparity",gcvdisp);
    cvWaitKey(0);
    cvReleaseMat(&gcdispleft);
    cvReleaseMat(&gcdispright);
    cvReleaseMat(&gcvdisp);
}


双目立体匹配算法:SGBM SGBM(Semi-Global Block Matching)是一种用于计算双目视觉中视差(disparity)的半全局匹配算法,在OpenCV中的实现为semi-global block matching(SGBM)。它是基于全局匹配算法和局部匹配算法的优缺点,提出了一种折中的方法,既能保证视差图的质量,又能降低计算复杂度。 阅读详情

相关推荐

双目立体视觉:SAD算法

SAD(Sum of absolute differences)图像立体匹配中常用的初级块匹配算法

苦逼的程序猿 4851

双目立体匹配算法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...

A_L_A_N 6万+

双目立体视觉建立深度图_【3D视觉】立体匹配成像算法BM,SGBM,GC,SAD一览

点击上方“新机器视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达在深度相机的主流技术方案Structure Light,ToF,Stereo Dual)中,主动双目成像方案可以基于低成本的硬件,获得高分辨率、高精度的深度图像,但是立体匹配算法(stereo matching)复杂,对计算资源消耗很大。那我们介绍下几种经典的双目匹配的算法。【双目匹配】双目立体视觉理论建立在对人类视觉...

weixin_29113371的博客 2145

双目立体视觉匹配算法之视差图算法从理论到实践专题1

1、资源搜索 双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法 半全局块匹配(Semi-Global Block Matching)算法 基于BM算法的双目测距 opencvSGBM半全局立体匹配算法的研究(1) 2、本人总结 在讲具体实现之前,我们还是先想想为什么会此概念。我们要实现的是相机能够可以知道这个场景的深度信息,但是从计算成像角度使...

CSS360的博客 3110

双目立体视觉建立深度图_立体匹配成像算法BM,SGBM,GC,SAD一览

在深度相机的主流技术方案Structure Light,ToF,Stereo Dual)中,主动双目成像方案可以基于低成本的硬件,获得高分辨率、高精度的深度图像,但是立体匹配算法(stereo matching)复杂,对计算资源消耗很大。那我们介绍下几种经典的双目匹配的算法。【双目匹配】双目立体视觉理论建立在对人类视觉系统研究的基础上,通过双目立体图象的处理,获取场景的三维信息,其结果表现为深度图...

weixin_42202605的博客 1528

【双目视觉探索路2】获取视差图(未完待续)

本篇文章的目的是获取视差图,基本原理涉及立体矫正与立体匹配。

JDeng的编程应用入门 1万+

双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法 2016年11月23日 11:11:54 阅读数:19959 一、 SAD算法 1.算法原理 SAD(

转载自:https://blog.youkuaiyun.com/liulina603/article/details/53302168一、 SAD算法1.算法原理        SAD(Sum of absolute differences)是一种图像匹配算法。基本思想:差的绝对值之和。此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的相似度。该算法快速、但并不精确,通常用于多级...

航天爱好者|雷达电子战 |分享可复现的踩坑笔记 1769

双目视觉立体匹配算法

1.双目立体匹配算法 左右视差 以后再细写。 1.1 立体匹配的流程 摄像机标定(包括内参和外参):直接用matlab标定工具箱即可 双目图像的校正(包括畸变校正和立体校正):立体校正opencv samples里给了案 立体匹配算法获取视差图,以及深度图 SAD/SGBM/BM/GC/ 利用视差图,或者深度图进行虚拟视点的合成 利用分水岭算法或者Grabcut算法进行分割 1.2 最新的...

wbzhang233的博客 3964

立体匹配成像算法BM,SGBM,GC,SAD一览

本文转自|新机器视觉在深度相机的主流技术方案Structure Light,ToF,Stereo Dual)中,主动双目成像方案可以基于低成本的硬件,获得高分辨率、高精度的深度图像,但是立...

3D视觉工坊 5243

3D感知技术(4)双目立体视觉测距

双目立体视觉测距

zfjBIT的专栏 1252

双目立体视觉匹配算法

1.SAD匹配算法、BM算法、SGBM算法、GC算法 https://blog.youkuaiyun.com/liulina603/article/details/53302168 2.双目视觉——立体匹配基本理论 https://blog.youkuaiyun.com/cyem1/article/details/80736878...

qq_32951799的博客 1221

计算机视觉视差图(SGBM算法)

该算法代码主要用于计算机视觉方面,双目相机左右图像通过运行该算法代码可得到视差图。

OpenCV stereo matching 代码 matlab实现视差显示

标签: opencvstereo matching 2014-11-16 22:47 10217人阅读 评论(23) 收藏 举报 本文章已收录于:   OpenCV知识库  分类: OpenCV(61)  图形图像(59)  立体匹配(3)  matlab(2)  计算机视觉(43)  立体视觉(9)  版权声明:本文为博主原创文章,未经博主

wu_wenhuan的专栏 1942

立体匹配算法,立体匹配算法sgbm原理介绍,C,C++

6SSD算法,SAD算法,NCC算法,DP算法,DP_5算法,census算法

变色龙哈希函数 Chameleon Hash 可变型区块链

哈希函数 Hash: 众所周知,区块链有着极其优秀的安全性就是因为其充分使用了哈希函数。 哈希简单用一句话来讲,就是:将任意长度输入的字串可转换成一个固定长度的字串,通过原始字串可以很容易地算出转换后的字串,通过转换后的字串很难还原出原始字串。 哈希函数特征: 1. 对于任意m作为输入,得到输出的结果,很难找到另一个输入m'  (m'不等于m),使得m'的Hash结果也为同样的输出

新手村 1万+
上一篇: RTP协议解析和H264码流提取
下一篇: 算法图解 总结
zero_china
博客等级 码龄16年 10粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值