【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图

OpenCV在计算机视觉中有三种常用的色彩空间:灰度、BGR以及HSV(Hue,Saturation,Value)

  • 深度图:灰度图像。该图像的每个像素值都是摄像头到物体表面之间距离的估计值。

  • 点云图:彩色图像,该图像的每种颜色都对应一个(x、y或z)维度空间。

  • 视差图:灰度图像,该图像的每个像素值代表物体表面的立体视差。

    • 假如将从同一场景的两张图叠放在一起,这可能感觉是两张不同的图像,在这个场景中,针对两张图像中两个孪生物体之间任一对相互对应的两个像素点,可以度量这些像素之间的距离。这个度量就是立体视差。
  • 有效深度掩膜:它是一个给定像素深度的深度信息是否有效(一个非零值表示有效,零值表示无效)

深度摄像头:将传统摄像头和一个红外传感器相结合来帮助摄像头区别相似物体并计算它们与摄像头之间的距离

极几何:跟踪从摄像头到图像上每个物体的实线,然后在第二张图做相同的操作,并根据同一物体对应的线的交叉来计算距离。

【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图_第1张图片

使用同一物体的两幅图像来计算视差图

代码

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 30 21:04:06 2020

@author: gkm0120
"""
import numpy as np
import cv2

#使用普通摄像头进行深度估计
def update(val=0):
    #为“aloe”图像对调整视差范围
    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('right',imgR)
    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('D:\Python\Test_code\pycv\images\1.jpg') 
    imgR = cv2.imread('D:\Python\Test_code\pycv\images\2.jpg')
    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)
    # 创建一个StereoSGBM实例
    stereo =cv2.StereoSGBM_create(
        minDisparity = min_disp,
        numDisparities=num_disp,
        blockSize = window_size,
        uniquenessRatio = uniquenessRatio,
        speckleRange = speckleRange,
        speckleWindowSize = speckleWindowSize,
        disp12MaxDiff = disp12MaxDiff,
        P1 = P1,
        P2 = P2
    )
    update()
    cv2.waitKey()

图例

输入

【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图_第2张图片1.jpg
【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图_第3张图片2.jpg

输出

【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图_第4张图片left
【OpenCV-Python】16 使用同一物体的两幅图像来计算视差图_第5张图片视差图

整体流程:导入numpy和cv2模块;加载两幅图像,创建一个StereoSGBM实例(semiglobal block matching,计算视差图的一种方法),并创建几个跟踪条来调整算法参数,然后调用update函数。update函数将跟踪条的值传给StereoSGBM实例,然后调用compute方法来得到一个视差图

注:距离摄像头近的点在视差图中会有更明亮的颜色。黑色区域代表两幅图的差异部分。

StereoSGBM用到的几个参数如下

参数 描述
minDisparity 这个参数表示可能的最小视差值。它通常为零,但有时校正算法会移动图像,所以参数值要相应调整
numDisparity 这个参数表示最大视差值与最小视差值的差。这个差值总是大于0 。在当前的实现中,这个值必须要能被16整除
windowSize 这个参数为一个匹配块的大小,他必须是大于等于1的奇数,通常在3~11之间
P1 这个参数是控制视差平滑度的第一个参数。P1是邻近像素间视差变化为1的惩罚值
P2 这个参数是控制视差平滑度的第二个参数。P1是邻近像素间视差变化大于1的惩罚值。这个值越大,视差越平滑。算法要求P2>P1
disp12MaxDiff 这个参数表示左右视差检查中最大允许的偏差(整数像素单位)。设非正值不做检查
preFilterCap 这个参数表示预过滤图像像素的截断值。
uniquenessRatio 这个参数表示由代价函数计算得到的最好(最小)结果值比第二好的值小多少(用百分比表示)
speckWindowSize 这个参数表示平滑视差区域的最大窗口尺寸,以考虑噪声斑点或无效性。将它设为0就不会进行斑点过滤
speckleRange 该参数是指每一个已连接部分的最大视察变化。如果进行斑点过滤,则该参数取正值,函数会自动乘以16

你可能感兴趣的:(OpenCV-Python,opencv,python)