用Python实现双目立体匹配SAD算法

SAD(Sum of absolute differences)是一种图像匹配算法。

SAD算法的基本流程:
1.构造一个小窗口,类似与卷积核。
2.用窗口覆盖左边的图像,选择出窗口覆盖区域内的所有像素点。
3.同样用窗口覆盖右边的图像并选择出覆盖区域的像素点。
4.左边覆盖区域减去右边覆盖区域,并求出所有像素点差的绝对值的和。
5.移动右边图像的窗口,重复3,4的动作。(这里有个搜索范围,超过这个范围跳出)
6.找到这个范围内SAD值最小的窗口,即找到了左边图像的最佳匹配的像素块。

SAD算法具体实现

import os
import time
import cv2 as cv
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
max_D = 25       #最大视差
win_size = 5     #滑动窗口大小
os.chdir(r'../ohta')                                         #图片所在文件夹路径
limg = np.asanyarray(Image.open(r"scene1.row3.col1.ppm"))    #左相机图片
rimg = np.asanyarray(Image.open(r"scene1.row3.col3.ppm"))    #右相机图片
limg = cv.cvtColor(limg, cv.COLOR_BGR2GRAY)     #将左图像转化为灰度图
rimg = cv.cvtColor(rimg, cv.COLOR_BGR2GRAY)
limg = np.asanyarray(limg, dtype=np.double)     #将左图像转化为double类型
rimg = np.asanyarray(rimg, dtype=np.double)
img_size = np.shape(limg)[0:2]                  #定义一个和图片大小相等尺寸的数组
plt.figure("左图灰度图")
plt.imshow(limg)
plt.show()
plt.figure("右图灰度图")
plt.imshow(rimg)
plt.show()
t1 = time.time()      #记录开始时间
imgDiff = np.zeros((img_size[0], img_size[1], max_D))   #记录视差为max_D的e2
e = np.zeros(img_size)                                 #记录视差为i时,左右图片的整体差距
for i in range(0, max_D):
    e = np.abs(rimg[:, 0:(img_size[1]-i)]-limg[:, i:img_size[1]])
    e2 = np.zeros(img_size)       #记录win_size之和
    for x in range(0, img_size[0]):
        for y in range(0, img_size[1]):
            e2[x, y] = np.sum(e[(x-win_size):(x+win_size), (y-win_size):(y+win_size)])
    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]/max_D*255   #恢复彩色图像
print("所用时间:", time.time()-t1)
plt.figure("视差图")
plt.imshow(dispMap)
plt.show()

具体的运行效果

 所用时间为: 11.613516569137573

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值