-
Notifications
You must be signed in to change notification settings - Fork 3
/
plane_sweep_stereo.py
129 lines (100 loc) · 3.28 KB
/
plane_sweep_stereo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from scipy.misc import imsave
import cv2
import numpy as np
import sys
import time
from util import preprocess_ncc, pyrdown, get_depths, \
unproject_corners, compute_ncc, project
from dataset import load_dataset
from gifwriter import GifWriter
assert len(sys.argv) > 1
data = load_dataset(sys.argv[1])
K_right = data.K_right
K_left = data.K_left
Rt_right = data.Rt_right
Rt_left = data.Rt_left
ncc_size = data.ncc_size
width = data.width
height = data.height
ncc_gif_writer = GifWriter(data.ncc_temp, data.ncc_gif)
projected_gif_writer = GifWriter(data.projected_temp, data.projected_gif)
"""
Images are pretty large, so we're going to reduce their size
in each dimension.
"""
right = data.right[0]
left = data.left[0]
for i in xrange(data.stereo_downscale_factor):
right = pyrdown(right)
left = pyrdown(left)
height, width, _ = right.shape
K_left[:2, :] /= 2
K_right[:2, :] /= 2
"""
We'll give you the depth labels for this problem.
"""
depths = get_depths(data)
tic = time.time()
"""
The planes will be swept fronto-parallel to the right camera, so no
reprojection needs to be done for this image. Simply compute the normalized
patches across the entire image.
"""
right_normalized = preprocess_ncc(right[:, :, :3], ncc_size)
"""
We'll sweep a series of planes that are fronto-parallel to the right camera.
The image from the left camera is to be projected onto each of these planes,
normalized, and then compared to the normalized right image.
"""
volume = []
for pos, depth in enumerate(depths):
"""
Unproject the pixel coordinates from the right camera onto the virtual
plane.
"""
points = unproject_corners(K_right, width, height, depth, Rt_right)
"""
Project those points onto the two cameras to generate correspondences.
"""
points_left = project(K_left, Rt_left, points)
points_right = project(K_right, Rt_right, points)
points_left = np.float32(points_left.reshape(-1, 2))
points_right = np.float32(points_right.reshape(-1, 2))
H, mask = cv2.findHomography(points_left, points_right)
assert (mask == 1).all()
projected_left = cv2.warpPerspective(left, H, (width, height))
"""
Normalize this projected left image.
"""
left_normalized = preprocess_ncc(projected_left, ncc_size)
"""
Compute the NCC score between the right and left images.
"""
ncc = compute_ncc(right_normalized, left_normalized)
volume.append(ncc)
projected_gif_writer.append(np.uint8(projected_left))
ncc_gif_writer.append(np.uint8(255 * np.clip(ncc / 2 + 0.5, 0, 1)))
sys.stdout.write('Progress: {0}\r'.format(int(100 * pos / len(depths))))
sys.stdout.flush()
print ''
toc = time.time()
print 'Plane sweep took {0} seconds'.format(toc - tic)
ncc_gif_writer.close()
projected_gif_writer.close()
"""
All of these separate NCC layers get stacked together into a volume.
"""
volume = np.dstack(volume)
"""
We're going to use the simplest algorithm to select a depth layer per pixel --
the argmax across depth labels.
"""
solution = volume.argmax(axis=2)
print 'Saving NCC to {0}'.format(data.ncc_png)
imsave(data.ncc_png, solution * 2)
"""
Remap the label IDs back to their associated depth values.
"""
solution = depths[solution]
print 'Saving depth to {0}'.format(data.depth_npy)
np.save(data.depth_npy, solution)