OpenCV中的立体图像创建深度图

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中的立体图像创建深度图相关的知识,希望对你有一定的参考价值。

OpenCV中的立体图像创建深度图

这篇博客将介绍如何从立体图像创建深度图。

1. 效果图

原图 VS 视差图效果如下:
可以看到结果受到高度噪音的污染。通过调整 numDisparities 和 blockSize 的值,可以获得更好的结果。

2. 源码

# 立体图像匹配和点云生成的简单示例。

from __future__ import print_function

import numpy as np
import cv2 as cv

ply_header = '''ply
format ascii 1.0
element vertex %(vert_num)d
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
end_header
'''


def write_ply(fn, verts, colors):
    verts = verts.reshape(-1, 3)
    colors = colors.reshape(-1, 3)
    verts = np.hstack([verts, colors])
    with open(fn, 'wb') as f:
        f.write((ply_header % dict(vert_num=len(verts))).encode('utf-8'))
        np.savetxt(f, verts, fmt='%f %f %f %d %d %d ')


def main():
    print('loading images...')
    imgL = cv.pyrDown(cv.imread('images/aloeL.jpg'))  # 下采样图片以加快处理速度
    imgR = cv.pyrDown(cv.imread('images/aloeR.jpg'))

    # 针对“芦荟”图像对,调整视差范围
    # disparity range is tuned for 'aloe' image pair
    window_size = 3
    min_disp = 16
    num_disp = 40
    stereo = cv.StereoSGBM_create(minDisparity=min_disp,
                                  numDisparities=num_disp,
                                  blockSize=16,
                                  P1=8 * 3 * window_size ** 2,
                                  P2=32 * 3 * window_size ** 2,
                                  disp12MaxDiff=1,
                                  uniquenessRatio=10,
                                  speckleWindowSize=100,
                                  speckleRange=32
                                  )

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

    print('generating 3d point cloud...', )
    h, w = imgL.shape[:2]
    f = 0.8 * w  # guess for focal length
    Q = np.float32([[1, 0, 0, -0.5 * w],
                    [0, -1, 0, 0.5 * h],  # turn points 180 deg around x-axis,
                    [0, 0, 0, -f],  # so that y-axis looks up
                    [0, 0, 1, 0]])
    points = cv.reprojectImageTo3D(disp, Q)
    colors = cv.cvtColor(imgL, cv.COLOR_BGR2RGB)
    mask = disp > disp.min()
    out_points = points[mask]
    out_colors = colors[mask]
    out_fn = 'out.ply'
    write_ply(out_fn, out_points, out_colors)
    print('%s saved' % out_fn)

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

    print('Done')


if __name__ == '__main__':
    print(__doc__)
    main()
    cv.destroyAllWindows()

参考

以上是关于OpenCV中的立体图像创建深度图的主要内容,如果未能解决你的问题,请参考以下文章

使用立体相机从视差图进行深度重建

来自形成立体系统的两个校准相机的 openCV 深度图

视差图的 OpenCv 深度估计

opencv三维重建深度怎么不随视场变化

深度相机-介绍

使用 opencv 进行立体图像校正不起作用