SAD立体匹配算法的PYTHON实现
这是第一次发CSDN博客,因为在机器视觉的学习中CSDN帮助了我很多,那么我也应该为CSDN社区做一些贡献,所以本文将介绍我用python实现的SAD匹配算法。
1.SAD算法的原理
SAD算法是立体匹配算法中,隶属于局部区域匹配算法中的一个算法,原理是从 左图中找出一个小窗口,利用极线约束,在 ** 右图 中同一行中 间隔D为D_1处找到同样大小的一个小窗口,比方说都是 9*9 大小, 然后比较这个小窗口中每一个像素灰度差是多少,比如说灰度差为x_1,接着 更换间隔D为D_2**,再次计算灰度差x_2,比较灰度差最小的即为右图中的用一位置。
比如左图有一本书,算法可以找到这本书在右图的哪个位置,然后计算这本书在左图和右图中的位置差了多少,就可以计算出距离了
原理我就不多说了,已经有很多算法解释类的博文了,本文专注于算法实现
2.SAD算法的实现
import os
import time
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from numba import jit
from PIL import Image
maxDisparity=25 #最大视差
window_size=5#滑动窗口大小
#-------------------------------
'''这一部分是读取图片,请输入已经极线校准过的左图和右图,本算法不支持未校准图像的匹配'''
#------------------------------
os.chdir(r'C:\Users\86198\Desktop\learn\AAAAAAAAAAAA相机程序\下载的双目图像')
lraw=np.asanyarray(Image.open(r"scene1.row3.col1.ppm"))
rraw=np.asanyarray(Image.open(r"scene1.row3.col3.ppm"))
# os.chdir(r'C:\Users\86198\Desktop\L')
# lraw=cv.imread('ZED_image0L.png')
# os.chdir(r'C:\Users\86198\Desktop\R')
# rraw=cv.imread('ZED_image0R.png')
#-------------------------------
'''这一部分是转换彩色图像为灰度图像,并且转为double格式'''
#------------------------------
limg= cv.cvtColor(lraw,cv.COLOR_BGR2GRAY)
rimg= cv.cvtColor(rraw,cv.COLOR_BGR2GRAY)
limg=np.asanyarray(limg,dtype=np.double)
rimg=np.asanyarray(rimg,dtype=np.double)
img_size=np.shape(limg)[0:2]
plt.imshow(limg)
plt.show()
plt.imshow(rimg)
plt.show()
#-------------------------------
'''这一部分是加速后的SAD算法,具体做法是先计算右图按照视差由0到maxDisparity减去左图所得的矩阵'''
#------------------------------
tic1=time.time()
imgDiff=np.zeros((img_size[0],img_size[1],maxDisparity))
e = np.zeros(img_size)
for i in range(0,maxDisparity):
e=np.abs(rimg[:,0:(img_size[1]-i)]- limg[:,i:img_size[1]]) #视差为多少,那么生成的图像就会少多少像素列,e负责计算视差为i时,两张图整体的差距
e2=np.zeros(img_size) #计算窗口内的和
for x in range((window_size),(img_size[0]-window_size)):
for y in range((window_size),(img_size[1]-window_size)):
e2[x,y]=np.sum(e[(x-window_size):(x+window_size),(y-window_size):(y+window_size)])#其实相当于用111 111 111的卷积核去卷积,如果用tensorflow会不会更快一些,其实就是先做差再加和以及先加和再做差的关系
imgDiff[:,:,i]=e2
dispMap=np.zeros(img_size)
#-------------------------------
'''这一部分整找到使灰度差最小的视差,并绘图'''
#------------------------------
for x in range(0,img_size[0]):
for y in range(0,img_size[1]):
val=np.sort(imgDiff[x,y,:])
if np.abs(val[0]-val[1])>10:
val_id=np.argsort(imgDiff[x,y,:])
dispMap[x,y]=val_id[0]/maxDisparity*255#其实dispmap计算的是视差的大小,如果视差大,那么就相当于两张图片中同样物品的位移大,就是距离近
print('用时:',time.time()-tic1)
plt.imshow(dispMap)
plt.show()
3.SAD算法成果展示
左相机图片
右相机图片
深度图(视差图)
4.下一步工作
1.阅读更多相关文献,找到比SAD效果更好的局部匹配算法
目前已经完成了SAD的进化版本,SAD滑动窗口版本
匹配率更高,生成深度图更平滑,以及鲁棒性和SAD互补的Census代价函数
2.做更多有意义的代码实现