opencv/samples/python/stereo_match.py

79 lines
2.2 KiB
Python
Raw Normal View History

2013-03-06 14:41:02 +08:00
#!/usr/bin/env python
2012-10-17 07:18:30 +08:00
'''
Simple example of stereo image matching and point cloud generation.
Resulting .ply file cam be easily viewed using MeshLab ( http://meshlab.sourceforge.net/ )
'''
# Python 2/3 compatibility
from __future__ import print_function
2012-10-17 07:18:30 +08:00
import numpy as np
import cv2
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 ')
2012-10-17 07:18:30 +08:00
if __name__ == '__main__':
print('loading images...')
2014-09-13 22:28:41 +08:00
imgL = cv2.pyrDown( cv2.imread('../data/aloeL.jpg') ) # downscale images for faster processing
imgR = cv2.pyrDown( cv2.imread('../data/aloeR.jpg') )
2012-10-17 07:18:30 +08:00
# disparity range is tuned for 'aloe' image pair
window_size = 3
min_disp = 16
num_disp = 112-min_disp
stereo = cv2.StereoSGBM_create(minDisparity = min_disp,
2012-10-17 07:18:30 +08:00
numDisparities = num_disp,
blockSize = 16,
2012-10-17 07:18:30 +08:00
P1 = 8*3*window_size**2,
P2 = 32*3*window_size**2,
disp12MaxDiff = 1,
uniquenessRatio = 10,
speckleWindowSize = 100,
speckleRange = 32
2012-10-17 07:18:30 +08:00
)
print('computing disparity...')
2012-10-17 07:18:30 +08:00
disp = stereo.compute(imgL, imgR).astype(np.float32) / 16.0
print('generating 3d point cloud...',)
2012-10-17 07:18:30 +08:00
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 = cv2.reprojectImageTo3D(disp, Q)
colors = cv2.cvtColor(imgL, cv2.COLOR_BGR2RGB)
mask = disp > disp.min()
out_points = points[mask]
out_colors = colors[mask]
out_fn = 'out.ply'
write_ply('out.ply', out_points, out_colors)
print('%s saved' % 'out.ply')
2012-10-17 07:18:30 +08:00
cv2.imshow('left', imgL)
cv2.imshow('disparity', (disp-min_disp)/num_disp)
cv2.waitKey()
cv2.destroyAllWindows()