立体匹配算法-SAD

目录

前言

SAD 是一种简单高效的立体匹配算法,虽然由于精度等原因很少被实际应用,但可以帮助我们理解立体匹配过程

一、SAD算法原理

Sum of Absolute Differences 即”绝对差之和”简称SAD。该算法通过比较立体图像对(一般为左右图)中的光照亮度差异来寻找匹配点对,进而计算视差。

SAD计算过程主要包括以下步骤:

  1. 选取窗口,窗口大小通常为3×3、5×5、7×7或者更大;
  2. 确定最大视差Dmax;
  3. 在左(右)图上以(x,y)为中心构建窗口,在右(左)图分别以(x,y-d)((x,y+d))
    ,d=0-Dmax构建窗口,并计算视差0-Dmax范围内的左右图窗口内像素亮度差异;
  4. 对窗口内的亮度差异求和,选取使绝对亮度差值之和最小的d作为(x,y)处的视差值。

二、代码示例

1.引入库

代码如下(示例):

import os
import time
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

2.设置窗口和最大视差

代码如下(示例):

window_size=5
Dmax=64

3.读入左右图

本文使用的图片来源于Middlebury数据集
代码如下:

#Read rectified stereo image pairs
os.chdir(r'此处为图片路径')
LeftRawImage = cv.imread("左图文件名")
RightRawImage = cv.imread("右图文件名")
#Convert to gray image
LeftRawImage = cv.cvtColor(LeftRawImage,cv.COLOR_BGR2GRAY)
RightRawImage = cv.cvtColor(RightRawImage,cv.COLOR_BGR2GRAY)

立体匹配算法-SAD
立体匹配算法-SAD

4.定义SAD类

代码如下,此代码对图片做了padding,保证输出视差图和原图具有相同分辨率:

class SAD():
    def __init__(self, Lraw, Rraw, window_size, Dmax):
        self.Lraw = Lraw
        self.Rraw = Rraw
        self.window_size = window_size
        self.Dmax = Dmax
        self.ROWS = Lraw.shape[0]
        self.COLS = Lraw.shape[1]
        self.PADDING_SIZE = int((window_size-1)/2)

    #Calculate Absolute Differences
    def AD(self):
        AD_PADDING=np.zeros((self.ROWS,self.COLS,self.Dmax))
        AD_PADDING=np.pad(AD_PADDING,(self.PADDING_SIZE,self.PADDING_SIZE))
        Cost_SAD=np.zeros((self.ROWS,self.COLS,Dmax))
        for d in range(0,self.Dmax):
            for i in range(0,self.ROWS):
                for j in range(0,self.COLS):
                    if(j - d >= 0):
                        AD_PADDING[i+self.PADDING_SIZE,j+self.PADDING_SIZE,d]=np.abs(int(self.Lraw[i,j])-int(self.Rraw[i,j-d]))
                        Cost_SAD[i,j,d] = np.sum(AD_PADDING[i:i+window_size,j:j+window_size,d])
                    else:
                        Cost_SAD[i,j,d]=0
        return Cost_SAD

    #Calculate the minimum index
    def argmin(self,Cost_volume):
        Disparity = np.zeros((self.ROWS,self.COLS),dtype=np.int8)
        for i in range(0,self.ROWS):
            for j in range(0,self.COLS):
                Cost_sad = Cost_volume[i,j,:]
                index_sort= np.argsort(Cost_sad)
                Disparity[i,j]=index_sort[0]
        return Disparity

5.计算视差图

代码如下:

#Calculate disparity
time_start = time.time()
SAD_Middleburry = SAD(LeftRawImage,RightRawImage,window_size, Dmax)
Cost_sad = SAD_Middleburry.AD()
Disparity_image = SAD_Middleburry.argmin(Cost_sad)
print("用时:",time.time() - time_start,"s")
plt.imshow(Disparity_image,cmap='plasma')
plt.show()
plt.imsave('./Disparity.png',  Disparity_image, cmap='plasma')

立体匹配算法-SAD

总结

SAD算法虽然简单高效,但是容易受光照、曝光等噪声影响,视差图的效果往往不是特别鲁棒。

注:以上代码运行较慢,在作者的电脑上运行时间为325s左右,运行后请耐心等待。以后作者将不定时更新立体匹配算法的python代码,包括Census,AD-Census等,同时作者将学习相关加速方法,并对所写代码做出改进,以便高效运行。
作者并不精通python编程,如有错误,欢迎各位大佬不吝赐教!如有疑问,欢迎大家一起讨论!谢谢!

Original: https://blog.csdn.net/weixin_45155861/article/details/123777105
Author: 可与人言不过二三
Title: 立体匹配算法-SAD

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/533419/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球