双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法
一、 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); //计算SADprivate: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.csdn.net/wqvbjhc/article/details/6260844
[cpp] view plain copy
- <code class="language-cpp">void BM()
- {
- IplImage * img1 = cvLoadImage("left.png",0);
- IplImage * img2 = cvLoadImage("right.png",0);
- CvStereoBMState* BMState=cvCreateStereoBMState();
- assert(BMState);
- BMState->preFilterSize=9;
- BMState->preFilterCap=31;
- BMState->SADWindowSize=15;
- BMState->minDisparity=0;
- BMState->numberOfDisparities=64;
- BMState->textureThreshold=10;
- BMState->uniquenessRatio=15;
- BMState->speckleWindowSize=100;
- BMState->speckleRange=32;
- BMState->disp12MaxDiff=1;
- CvMat* disp=cvCreateMat(img1->height,img1->width,CV_16S);
- CvMat* vdisp=cvCreateMat(img1->height,img1->width,CV_8U);
- int64 t=getTickCount();
- cvFindStereoCorrespondenceBM(img1,img2,disp,BMState);
- t=getTickCount()-t;
- cout<<"Time elapsed:"<<t*1000/getTickFrequency()<<endl;
- cvSave("disp.xml",disp);
- cvNormalize(disp,vdisp,0,255,CV_MINMAX);
- cvNamedWindow("BM_disparity",0);
- cvShowImage("BM_disparity",vdisp);
- cvWaitKey(0);
- //cvSaveImage("cones\\BM_disparity.png",vdisp);
- cvReleaseMat(&disp);
- cvReleaseMat(&vdisp);
- cvDestroyWindow("BM_disparity");
- }</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);
}
双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法相关推荐
- 立体匹配成像算法BM,SGBM,GC,SAD一览
本文转自|新机器视觉 在深度相机的主流技术方案Structure Light,ToF,Stereo Dual)中,主动双目成像方案可以基于低成本的硬件,获得高分辨率.高精度的深度图像,但是立体匹配算法 ...
- 双目立体视觉之立体匹配算法
一.立体匹配简介: 双目立体视觉是指使用两个摄像机从不同的角度获取同一个场景的左右视图,然后使用双目立体匹配算法来寻找左右视图中的匹配像素点对,最后利用三角测量原理来还原三维空间物理点过程.其中双目立 ...
- 双目立体视觉:SAD算法
算法原理 SAD(Sum of absolute differences)是一种图像匹配算法.基本思想:差的绝对值之和.此算法常用于图像块匹配,将每个像素对应数值之差的绝对值求和,据此评估两个图像块的 ...
- 26 Java GC算法 垃圾收集器、标记 -清除算法、复制算法、标记-压缩算法、分代收集算法
26.Java GC算法 垃圾收集器 1.1.1标记 -清除算法 1.1.2复制算法 1.1.3标记-压缩算法 1.1.4分代收集算法 26.Java GC算法 垃圾收集器 概述 垃圾收集 Garba ...
- JVM之垃圾收集机制四种GC算法详解
JVM之四种GC算法详解 目录: 什么是GC? GC算法之引用计数法 GC算法之复制算法(Copying) GC算法之标记清除(Mark-Sweep) GC算法之标记压缩(Mark-Compact) ...
- 【JVM】四种GC算法(分代收集+三种标记算法)
目录 参考文章 四种GC算法 分代收集算法(理论) 标记清除算法 标记整理算法 标记复制算法 三种算法的优缺点 参考文章 JVM的4种垃圾回收算法.垃圾回收机制与总结_我是guyue,guyue就是我 ...
- (六)JVM成神路之GC基础篇:对象存活判定算法、GC算法、STW、GC种类详解
引言 经过前面五个章节的分析后,对于JVM的大部分子系统都已阐述完毕,在本文中则开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优.监控.面试都逃不开的JVM话题. 在前面分析J ...
- 几种常见GC算法介绍
本文主要是对常用的GC算法(引用计数法.标记-清除法.复制算法.标记-清除算法)作出相关的说明,并对相关知识做简单的介绍. 一.什么是堆? 堆指用于动态(即执行程序时)存放对象的内存空间 ...
- JVM(三)GC垃圾回收以及四种GC算法
JVM(三) 学习视频链接,以示尊重:https://www.bilibili.com/video/BV1iJ411d7jS?p=4 图片来源:https://blog.csdn.net/weixin ...
最新文章
- 一阵骚操作,我把SQL执行效率提高了10000000倍!
- 插入排序的基本原理及实现
- 定时发布任务,在global.asax中获取文件的物理路径的方法
- 错误C4996:'std :: _Copy_impl'
- 亚马逊云服务(AWS)中国与毕马威中国建立战略合作伙伴关系
- P1035 [NOIP2002 普及组] 级数求和(python3实现)
- Goalng小demo二:客户信息关系系统
- 实操教程|用不需要手工标注分割的训练数据来进行图像分割
- GnosisDAO社区正就如何分配GNO代币展开讨论
- 非NLB网段的客户端无法访问NLB
- 迅雷对非会员进行下载限速的解决方案
- rtsp、rtmp测试地址
- FME 坐标系使用(二)----关于Beijing54坐标系和Xian80坐标系说明的补充
- 体验极好的临时邮箱,10分钟邮箱,极美观,速度特别快
- 职业规划 软件开发职业规划的10个建议
- smipleChart 简单图表类 javascript
- 3.9 拆解小红书爆文,流量密码原来是这些【玩赚小红书】
- 函数模板案例—选择排序
- 2021年中国5G手机发展现状及市场竞争格局分析:华为持续领跑国内5G手机市场[图]
- 在大厂呆过多年的35岁“大龄”程序猿,聊聊35岁以上的程序猿们都干什么去了