算法原理

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

常见立体匹配算法流程

常见的立体匹配算法主要包括以下四步

  1. 匹配代价计算

  1. 代价聚合

  1. 视差计算或优化

  1. 视差改良

匹配代价计算常采用sad等方法,根据左右两幅图像上匹配点的像素之差的绝对值。

代价聚合常采用一个固定窗口,计算窗口内部的所有视差之和。

视差的计算最直观的方式是采用WTA(Winner Takes All)的方式,直接选取使得聚合代价最小的视差值。

BM算法概括

简单的理解立体匹配,在行对准的两幅图像中找到同一个点,或Reference图像中给定一点,在Target图像中搜索对应的点,如下图所示。

根据极线规则,上图左边图中红色像素点(x, y)到右边图中搜索匹配点。实际上,直接对一点来进行匹配,百分百会出现各种各样的问题,这个时候我们选择用一个固定窗口来替代一点,如下图所示。

这样做就隐含了一个假设,认为窗口内部视差值相同,但是,显然的,这种假设太过想当然,也使得算法实际效果不好。

BM算法,也常称为SAD(Sum of Absolute Differences)算法,是双目立体匹配中最基本的算法。

SAD基本理论

SAD算法由3步构成。

  1. 匹配代价计算

  1. 代价聚合

  1. 视差计算

Matching Cost Computation

SAD的匹配代价计算比较简单,Reference图像和Target图像像素直接相减加绝对值,即|IR(x,y)−IT(x+d,y)||IR(x,y)−IT(x+d,y)|。

视差空间(DSI)是一个三维矩阵,定义

[c(x,y,d)=

I_R(x,y)-I_T(x+d,y)

]

可以理解为Reference图像(x,y)(x,y)点,在搜索视差为dd时的代价。

Cost Aggeration

SAD的代价聚合就是将固定窗口FW(Fixed Window)内代价求和,直观理解如下图所示。

计算FW内视差视差为d时的聚合代价

[C(x,y,d)=\sum_{x\in S}|I_R(x,y)-I_T(x+d,y)|]

Disparity Computation

SAD的视差计算非常简单,采用WTA原则,对于给定的(x,y)(x,y),找使得C(x,y,d)C(x,y,d)最小的d,此d即可认为时该点的视差。

基本流程

输入:两幅图像,一幅Left-Image,一幅Right-Image且两幅图像已经校正实现行对准

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

(1)设定SAD窗口的大小(下图灰色区域),left_image为开始匹配的位置,(p,q)以及在right_image中SAD窗口移动的范围D。

(2)在left_image图像中,确定待匹配的像素点的位置(x,y),并以此位置作为SAD窗口的锚点,用SAD窗口覆盖left_image中以(x,y)为锚点的区域regionl。

(3)在right_image图像中,选取匹配的开始点,位置为(m,n),并以该点作为SAD窗口的锚点,用SAD窗口去覆盖,在right_iamge中形成以(m,n)为锚点的图像区域regionr.

(4)定义differernce=regionr-regionl。计算difference中的和。

(5)在right_image图像中沿行方向移动SAD(移动次数为匹配的范围大小),重复步骤(3),(4),并将每次得到的difference记录在mat矩阵中。

(6)找到mat矩阵中difference最小的值,则其所在位置就是right_image和left_image的视差。

代码实现


#include "opencv2/opencv.hpp"class SAD
{
public:SAD() :winSize(7), DSR(30) {}SAD(int _winSize, int _DSR) :winSize(_winSize), DSR(_DSR) {}cv::Mat computerSAD(cv::Mat& L, cv::Mat& R); //计算SAD
private:int winSize; //卷积核的尺寸int DSR;     //视差搜索范围};cv::Mat SAD::computerSAD(cv::Mat& L, cv::Mat& R)
{int Height = L.rows;int Width = L.cols;cv::Mat Kernel_L(cv::Size(winSize, winSize), CV_8U, cv::Scalar::all(0));cv::Mat Kernel_R(cv::Size(winSize, winSize), CV_8U, cv::Scalar::all(0));cv::Mat Disparity(Height, Width, CV_8U, cv::Scalar(0)); //视差图for (int i = 0; i < Width - winSize; i++){for (int j = 0; j < Height - winSize; j++){Kernel_L = L(cv::Rect(i, j, winSize, winSize));cv::Mat MM(1, DSR, CV_32F, cv::Scalar(0)); //MM是一个1行DSR列的图像(矩阵)for (int k = 0; k < DSR; k++){int x = i - k; //为什么是i-k参见我上面的叙述if (x >= 0){Kernel_R = R(cv::Rect(x, j, winSize, winSize));cv::Mat Dif;cv::absdiff(Kernel_L, Kernel_R, Dif);//cv::Scalar ADD = sum(Dif);float a = ADD[0];//a为视差为k是相应窗口的像素差值的绝对值之和MM.at<float>(k) = a;//将a赋给MM的第k列,因为从0开始搜索,遍历结束后MM每一列为视差为列序号时对应的SAD值,我们取其最小即可std::cout << "i,j: " << i << ", " << j << "; MM " << MM << std::endl;}}cv::Point minLoc; //point数据类型为二维点对象,有横纵xy两个坐标double min = 0.0;cv::minMaxLoc(MM, &min, NULL, &minLoc, NULL);//返回MM最小值的坐标int loc = minLoc.x;//取最小值坐标的横坐标x值,即为对应的列序号,也就是相应的视差值//int loc=DSR-loc;Disparity.at<char>(j, i) = loc * 16;//*16只是为了方便显示}double rate = double(i) / (Width);//cout << "已完成" << setprecision(2) << rate * 100 << "%" << endl; //处理进度}return Disparity;
}int main()
{cv::Mat Img_L = cv::imread("SAD\\left_0.jpg", 0);cv::Mat Img_R = cv::imread("SAD\\right_0.jpg", 0);cv::Mat Disparity;    //视差图//SAD mySAD;SAD mySAD(7, 30);Disparity = mySAD.computerSAD(Img_L, Img_R);cv::imshow("Img_L", Img_L);cv::imshow("Img_R", Img_R);cv::imshow("Disparity", Disparity);cv::waitKey();return -1;
}

备注:

用SAD算法可以得出左右图像的视差,进一步处理就可以得到深度图,深度与视差成反比的关系。我们做个实验:将手指头放在离眼睛不同距离的位置,并轮换睁、闭左右眼,可以发现手指在不同距离的位置,视觉差也不同,且距离越近,视差越大,其中距离的远近就是深度了。并且可以观察到,用左眼看手指时,手指在你眼中的靠右位置,而用右眼看时,手指在你眼中靠左的位置。假设两只眼分别看到的视野一样大。若用(x,y)表示左眼视图中某个位置的坐标,那么相应的该位置右眼视图的坐标应该为(x-d,y),其中d就是视差。这时(x,y)和(x-d,y)就是最佳匹配点。但是实际情况我们并不知道d是多少。SAD算法就给出了如何求视差d.

SAD算法:我们按视差搜索范围从0开始搜索,找到左右图像最匹配的点,对应的视差值就确定了。如何确定最佳匹配点呢?试想一下,如果视差为0,也就是左右图像一样,那么这个点上下左右区域对应的点都应该相同,所以像素相减后都为0,由于视差的存在(简单理解为从不同的角度看物体,由于光照的影响像素值也会发生改变),该点上下左右区域的像素值不会完全相等,但是我们依然可以利用这个思想,设定一个小窗口,在左右两幅图中计算其像素值差的绝对值之和。根据极线约束覆盖右图像像素点,假如视差搜索范围为0-50,那么就会得到51个结果。若在某个视差值d下该绝对值之和最小,那么d就为该中心点对应的视差。再由视差与深度的关系就可以得到深度图。

https://jiweibo.github.io/StereoBM/

双目立体视觉:SAD算法相关推荐

  1. 关于双目立体视觉的三大基本算法SAD、SSD、SGBM及发展现状的总结

    双目立体视觉一直是机器视觉研究领域的发展热点和难点,"热"是因为双目立体视觉有着及其广阔的应用前景,且随着光学.计算机科学等学科的不断发展,双目立体技术将不断进步直到应用到人类生活 ...

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

    一. SAD算法 1.算法原理         SAD(Sum of absolute differences)是一种图像匹配算法.基本思想:差的绝对值之和.此算法常用于图像块匹配,将每个像素对应数值 ...

  3. 关于双目立体视觉的三大基本算法及发展现状的总结

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 双目立体视觉一直是机器视觉研究领域的发展热点和难点,"热 ...

  4. 基于深度学习算法和传统立体匹配算法的双目立体视觉

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 01 立体视觉是什么? 在开始之前,我相信很多站友都会有这个疑问, ...

  5. sgbm算法_关于双目立体视觉的三大基本算法及发展现状的总结

    作者:何文博 来源:公众号 @3D视觉工坊 链接:关于双目立体视觉的三大基本算法及发展现状的总结 双目立体视觉一直是机器视觉研究领域的发展热点和难点,"热"是因为双目立体视觉有着及 ...

  6. 双目立体视觉建立深度图_从单幅图像到双目立体视觉的3D目标检测算法

    原创声明:本文为 SIGAI 原创文章,仅供个人学习使用,未经允许,不能用于商业目的. 其它机器学习.深度学习算法的全面系统讲解可以阅读<机器学习-原理.算法与应用>,清华大学出版社,雷明 ...

  7. 双目立体视觉Bouguet矫正算法详解

    版权声明:本文为博主原创文章,欢迎转载,请注明出处 https://blog.csdn.net/u011574296/article/details/73826420 </div>< ...

  8. 检测三维物体?一篇文章认识《双目立体视觉》

    来源:https://blog.csdn.net/qq_41204464/article/details/115387812 作者:一颗小树X@CSDN(已授权) 编辑:3D视觉开发者社区 前言 双目 ...

  9. 双目立体视觉系统”机器之眼“之扬帆起航篇

    双目立体视觉系统"机器之眼"之扬帆起航篇 好久不见,你还好吗?!!! 久违了,不能等太久,一休哥与大家再次相见,相约双目立体视觉系统! 双目立体视觉(Binocular Stere ...

最新文章

  1. 动态参数与静态参数的判断、修改
  2. 基于xilinx异构平台上视频采集分析
  3. 《Linux设备驱动程序》学习2—高级字符设备驱动ioctl
  4. 一家美资企业的java servlet面试题
  5. 魅族用鸿蒙系统吗,魅族宣布接入鸿蒙是怎么回事?魅族手机可以刷鸿蒙系统吗?...
  6. linux中send函数MSG_NOSIGNAL异常消息
  7. 计算机启动到安全模式,计算机启动每次都进入安全模式怎么办
  8. 查看手机是否安装微信客户端
  9. Linux基础入门(一)
  10. error: Pulling is not possible because you have unmerged files
  11. 创建应用 django
  12. anaconda安装tensorflow后,matplotlib无法调用的解决方法
  13. 推荐学习网页标准的20个好去处
  14. 初学者易上手的SSH-hibernate01环境搭建
  15. Java简单语法与访问权限修饰符
  16. 圈圈教你玩usb第一版硬件实物图
  17. url传值的长度限制解决方法
  18. Eclipse 启动时提示loading workbench错误并提示查看.log
  19. 俺压箱底的导航网站推荐
  20. 计算机怎么没有word文档,电脑新建没有word文档怎么办 没有Word解决方法

热门文章

  1. sql查询语句-平均分、最高最低分、判断、排序
  2. 了解ThinkPad指纹识别系统设置
  3. 你可能是盗版软件的受害者
  4. The ACM Publishing System (TAPS) ACM出版系统上传文章 操作流程
  5. 计算机基础之CPU架构
  6. 根据经纬度在地图上定位
  7. 智慧养老数据可视化(数据大屏)
  8. 利用Python中的fealpy包求解泊松方程
  9. 深度学习中图像标注工具整理
  10. java基础知识 整理