opencv——StereoSGBM计算视差图算法 使用普通摄像头进行深度估计

本文介绍了一种使用极几何原理计算视差图的方法,通过处理同一物体在不同视角下的两幅图像,以提取前景并计算深度信息。文章详细阐述了StereoSGBM算法的参数设置及其实现过程,展示了如何利用OpenCV库进行视差图的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该算法使用极几何来计算所谓的视差图,它是对图像中检测到的不同深度的基本表示。这样就能提取出一张图片中的前景部分而抛弃其余部分。
首先需要同一物体在不同视角下拍摄的两幅图像,注意是在距物体相同距离拍摄的!否则计算会失败,计算得到的视差图就没有意义了。
极几何计算视差概念图
以下程序使用同一物体的两幅图像来计算视差图,距离摄像头近的点在视差图中会有更明亮的颜色。黑色区域代表两幅图像的差异部分。

import numpy as np
import cv2

def update(val = 0):
    stereo.setBlockSize(cv2.getTrackbarPos('window_size', 'disparity'))
    stereo.setUniquenessRatio(cv2.getTrackbarPos('uniquenessRatio', 'disparity'))
    stereo.setSpeckleWindowSize(cv2.getTrackbarPos('speckleWindowSize', 'disparity'))
    stereo.setSpeckleRange(cv2.getTrackbarPos('speckleRange', 'disparity'))
    stereo.setDisp12MaxDiff(cv2.getTrackbarPos('disp12MaxDiff', 'disparity'))

    print('computing disparity...')
    disp = stereo.compute(imgL, imgR).astype(np.float32) / 16.0

    cv2.imshow('left', imgL)
    cv2.imshow('disparity', (disp-min_disp)/num_disp)
    

if __name__ == "__main__":
    window_size = 5
    min_disp = 16
    num_disp = 192-min_disp
    blockSize = window_size
    uniquenessRatio = 1
    speckleRange = 3
    speckleWindowSize = 3
    disp12MaxDiff = 200
    P1 = 600
    P2 = 2400
    imgL = cv2.imread(r'C:\Users\Owen\Pictures\dis2.jpg')
    imgR = cv2.imread(r'C:\Users\Owen\Pictures\dis1.jpg')
    imgL = cv2.resize(imgL,dsize=None,fx=0.2,fy=0.2)
    imgR = cv2.resize(imgR,dsize=None,fx=0.2,fy=0.2)


    cv2.namedWindow('disparity')
    cv2.createTrackbar('speckleRange', 'disparity', speckleRange, 50, update)    
    cv2.createTrackbar('window_size', 'disparity', window_size, 21, update)
    cv2.createTrackbar('speckleWindowSize', 'disparity', speckleWindowSize, 200, update)
    cv2.createTrackbar('uniquenessRatio', 'disparity', uniquenessRatio, 50, update)
    cv2.createTrackbar('disp12MaxDiff', 'disparity', disp12MaxDiff, 250, update)
    stereo = cv2.StereoSGBM_create(
        minDisparity = min_disp,  #表示可能的最小视差值。通常为0,但有时校正算法会移动图像,所以参数值也要相应调整
        numDisparities = num_disp, #表示最大的视差值与最小的视差值之差,这个差值总是大于0。在当前的实现中,这个值必须要能被16整除
        blockSize = window_size,   
        uniquenessRatio = uniquenessRatio,#表示由代价函数计算得到的最好(最小)结果值比第二好的值小多少(用百分比表示)才被认为是正确的。通常在5-15之间。
        speckleRange = speckleRange,   #指每个已连接部分的最大视差变化,如果进行斑点过滤,则该参数取正值,函数会自动乘以16、一般情况下取1或2就足够了。
        speckleWindowSize = speckleWindowSize,  #表示平滑视差区域的最大窗口尺寸,以考虑噪声斑点或无效性。将它设为0就不会进行斑点过滤,否则应取50-200之间的某个值。
        disp12MaxDiff = disp12MaxDiff,  #表示在左右视图检查中最大允许的偏差(整数像素单位)。设为非正值将不做检查。
        P1 = P1,  #控制视差图平滑度的第一个参数
        P2 = P2   #控制视差图平滑度的第二个参数,值越大,视差图越平滑。P1是邻近像素间视差值变化为1时的惩罚值,
                  #p2是邻近像素间视差值变化大于1时的惩罚值。算法要求P2>P1,stereo_match.cpp样例中给出一些p1和p2的合理取值。
    )
    update()
    cv2.waitKey()

**

StereoSGBM用到的参数:

**

		minDisparity  #表示可能的最小视差值。通常为0,但有时校正算法会移动图像,所以参数值也要相应调整
        numDisparities  #表示最大的视差值与最小的视差值之差,这个差值总是大于0。在当前的实现中,这个值必须要能被16整除
        uniquenessRatio#表示由代价函数计算得到的最好(最小)结果值比第二好的值小多少(用百分比表示)才被认为是正确的。通常在5-15之间。
        speckleRange  #指每个已连接部分的最大视差变化,如果进行斑点过滤,则该参数取正值,函数会自动乘以16、一般情况下取1或2就足够了。
        speckleWindowSize  #表示平滑视差区域的最大窗口尺寸,以考虑噪声斑点或无效性。将它设为0就不会进行斑点过滤,否则应取50-200之间的某个值。
        disp12MaxDiff   #表示在左右视图检查中最大允许的偏差(整数像素单位)。设为非正值将不做检查。
        P1 = P1,  #控制视差图平滑度的第一个参数
        P2 = P2   #控制视差图平滑度的第二个参数,值越大,视差图越平滑。P1是邻近像素间视差值变化为1时的惩罚值,
                  #p2是邻近像素间视差值变化大于1时的惩罚值。算法要求P2>P1,stereo_match.cpp样例中给出一些p1和p2的合理取值。

运行截图:
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值