Skip to content

Commit dcc7773

Browse files
authored
Merge pull request andyzeng#13 from kevinzakka/cpu-optim
added numba optimisation to cpu code. ~2x FPS speedup.
2 parents 9075919 + 497c431 commit dcc7773

File tree

4 files changed

+426
-365
lines changed

4 files changed

+426
-365
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
__pycache__
2+
*.ply

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ An older CUDA/C++ version can be found [here](https://github.com/andyzeng/tsdf-f
88

99
## Requirements
1010

11-
* Python 2.7+ with [NumPy](http://www.numpy.org/), [PyCUDA](https://developer.nvidia.com/pycuda), [OpenCV](https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_tutorials.html), [Scikit-image](https://scikit-image.org/). These can be quickly installed/updated by running the following:
11+
* Python 2.7+ with [NumPy](http://www.numpy.org/), [PyCUDA](https://developer.nvidia.com/pycuda), [OpenCV](https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_tutorials.html), [Scikit-image](https://scikit-image.org/) and [Numba](https://numba.pydata.org/). These can be quickly installed/updated by running the following:
1212
```shell
13-
pip install --user numpy opencv-python scikit-image
13+
pip install --user numpy opencv-python scikit-image numba
1414
```
1515
* [Optional] GPU acceleration requires an NVIDA GPU with [CUDA](https://developer.nvidia.com/cuda-downloads) and [PyCUDA](https://developer.nvidia.com/pycuda):
1616
```shell
@@ -42,10 +42,10 @@ python demo.py
4242
This repository is a part of [3DMatch Toolbox](https://github.com/andyzeng/3dmatch-toolbox). If you find this code useful in your work, please consider citing:
4343

4444
```
45-
@inproceedings{zeng20163dmatch,
46-
title={3DMatch: Learning Local Geometric Descriptors from RGB-D Reconstructions},
47-
author={Zeng, Andy and Song, Shuran and Nie{\ss}ner, Matthias and Fisher, Matthew and Xiao, Jianxiong and Funkhouser, Thomas},
48-
booktitle={CVPR},
49-
year={2017}
45+
@inproceedings{zeng20163dmatch,
46+
title={3DMatch: Learning Local Geometric Descriptors from RGB-D Reconstructions},
47+
author={Zeng, Andy and Song, Shuran and Nie{\ss}ner, Matthias and Fisher, Matthew and Xiao, Jianxiong and Funkhouser, Thomas},
48+
booktitle={CVPR},
49+
year={2017}
5050
}
5151
```

demo.py

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,63 @@
1-
#!/usr/bin/env python
1+
"""Fuse 1000 RGB-D images from the 7-scenes dataset into a TSDF voxel volume with 2cm resolution.
2+
"""
23

3-
import numpy as np
4-
import cv2
54
import time
6-
import fusion
75

6+
import cv2
7+
import numpy as np
8+
9+
import fusion
810

9-
# (Optional) sample code to compute 3D bounds (in world coordinates) around convex hull of all camera view frustums in dataset
10-
print("Estimating voxel volume bounds...")
11-
n_imgs = 1000
12-
cam_intr = np.loadtxt("data/camera-intrinsics.txt",delimiter=' ')
13-
vol_bnds = np.zeros((3,2))
14-
for i in range(n_imgs):
1511

12+
if __name__ == "__main__":
13+
# ======================================================================================================== #
14+
# (Optional) This is an example of how to compute the 3D bounds
15+
# in world coordinates of the convex hull of all camera view
16+
# frustums in the dataset
17+
# ======================================================================================================== #
18+
print("Estimating voxel volume bounds...")
19+
n_imgs = 1000
20+
cam_intr = np.loadtxt("data/camera-intrinsics.txt", delimiter=' ')
21+
vol_bnds = np.zeros((3,2))
22+
for i in range(n_imgs):
1623
# Read depth image and camera pose
17-
depth_im = cv2.imread("data/frame-%06d.depth.png"%(i),-1).astype(float)/1000. # depth is saved in 16-bit PNG in millimeters
18-
depth_im[depth_im == 65.535] = 0 # set invalid depth to 0 (specific to 7-scenes dataset)
19-
cam_pose = np.loadtxt("data/frame-%06d.pose.txt"%(i)) # 4x4 rigid transformation matrix
24+
depth_im = cv2.imread("data/frame-%06d.depth.png"%(i),-1).astype(float)
25+
depth_im /= 1000. # depth is saved in 16-bit PNG in millimeters
26+
depth_im[depth_im == 65.535] = 0 # set invalid depth to 0 (specific to 7-scenes dataset)
27+
cam_pose = np.loadtxt("data/frame-%06d.pose.txt"%(i)) # 4x4 rigid transformation matrix
2028

2129
# Compute camera view frustum and extend convex hull
22-
view_frust_pts = fusion.get_view_frustum(depth_im,cam_intr,cam_pose)
23-
vol_bnds[:,0] = np.minimum(vol_bnds[:,0],np.amin(view_frust_pts,axis=1))
24-
vol_bnds[:,1] = np.maximum(vol_bnds[:,1],np.amax(view_frust_pts,axis=1))
25-
26-
# ---------------------------------------------------------------------
27-
28-
# Initialize voxel volume
29-
print("Initializing voxel volume...")
30-
tsdf_vol = fusion.TSDFVolume(vol_bnds,voxel_size=0.02)
31-
32-
# Loop through RGB-D images and fuse them together
33-
t0_elapse = time.time()
34-
for i in range(n_imgs):
35-
print("Fusing frame %d/%d"%(i+1,n_imgs))
30+
view_frust_pts = fusion.get_view_frustum(depth_im, cam_intr, cam_pose)
31+
vol_bnds[:,0] = np.minimum(vol_bnds[:,0], np.amin(view_frust_pts, axis=1))
32+
vol_bnds[:,1] = np.maximum(vol_bnds[:,1], np.amax(view_frust_pts, axis=1))
33+
# ======================================================================================================== #
34+
35+
# ======================================================================================================== #
36+
# Integrate
37+
# ======================================================================================================== #
38+
# Initialize voxel volume
39+
print("Initializing voxel volume...")
40+
tsdf_vol = fusion.TSDFVolume(vol_bnds, voxel_size=0.02)
41+
42+
# Loop through RGB-D images and fuse them together
43+
t0_elapse = time.time()
44+
for i in range(n_imgs):
45+
print("Fusing frame %d/%d"%(i+1, n_imgs))
3646

3747
# Read RGB-D image and camera pose
38-
color_image = cv2.cvtColor(cv2.imread("data/frame-%06d.color.jpg"%(i)),cv2.COLOR_BGR2RGB)
39-
depth_im = cv2.imread("data/frame-%06d.depth.png"%(i),-1).astype(float)/1000. # depth is saved in 16-bit PNG in millimeters
40-
depth_im[depth_im == 65.535] = 0 # set invalid depth to 0 (specific to 7-scenes dataset)
41-
cam_pose = np.loadtxt("data/frame-%06d.pose.txt"%(i)) # 4x4 rigid transformation matrix
48+
color_image = cv2.cvtColor(cv2.imread("data/frame-%06d.color.jpg"%(i)), cv2.COLOR_BGR2RGB)
49+
depth_im = cv2.imread("data/frame-%06d.depth.png"%(i),-1).astype(float)
50+
depth_im /= 1000.
51+
depth_im[depth_im == 65.535] = 0
52+
cam_pose = np.loadtxt("data/frame-%06d.pose.txt"%(i))
4253

4354
# Integrate observation into voxel volume (assume color aligned with depth)
44-
tsdf_vol.integrate(color_image,depth_im,cam_intr,cam_pose,obs_weight=1.)
55+
tsdf_vol.integrate(color_image, depth_im, cam_intr, cam_pose, obs_weight=1.)
4556

46-
fps = n_imgs/(time.time()-t0_elapse)
47-
print("Average FPS: %.2f"%(fps))
57+
fps = n_imgs / (time.time() - t0_elapse)
58+
print("Average FPS: {:.2f}".format(fps))
4859

49-
# Get mesh from voxel volume and save to disk (can be viewed with Meshlab)
50-
print("Saving to mesh.ply...")
51-
verts,faces,norms,colors = tsdf_vol.get_mesh()
52-
fusion.meshwrite("mesh.ply",verts,faces,norms,colors)
60+
# Get mesh from voxel volume and save to disk (can be viewed with Meshlab)
61+
print("Saving to mesh.ply...")
62+
verts, faces, norms, colors = tsdf_vol.get_mesh()
63+
fusion.meshwrite("mesh.ply", verts, faces, norms, colors)

0 commit comments

Comments
 (0)