Skip to content

Commit 039e026

Browse files
classnerfacebook-github-bot
authored andcommitted
examples and docs.
Summary: This diff updates the documentation and tutorials with information about the new pulsar backend. For more information about the pulsar backend, see the release notes and the paper (https://arxiv.org/abs/2004.07484). For information on how to use the backend, see the point cloud rendering notebook and the examples in the folder docs/examples. Reviewed By: nikhilaravi Differential Revision: D24498129 fbshipit-source-id: e312b0169a72b13590df6e4db36bfe6190d742f9
1 parent 960fd6d commit 039e026

21 files changed

+759
-60
lines changed

INSTALL.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@ The core library is written in PyTorch. Several components have underlying imple
1414
- gcc & g++ ≥ 4.9
1515
- [fvcore](https://github.com/facebookresearch/fvcore)
1616
- If CUDA is to be used, use at least version 9.2.
17+
- If CUDA is to be used, the CUB library must be available. Starting from CUDA 11, CUB is part of CUDA. If you're using an earlier CUDA version and are not using conda, download the CUB library from https://github.com/NVIDIA/cub/releases and unpack it to a folder of your choice. Define the environment variable CUB_HOME before building and point it to the directory that contains `CMakeLists.txt` for CUB.
1718

18-
These can be installed by running:
19+
The dependencies can be installed by running:
1920
```
2021
conda create -n pytorch3d python=3.8
2122
conda activate pytorch3d
2223
conda install -c pytorch pytorch=1.6.0 torchvision cudatoolkit=10.2
2324
conda install -c conda-forge -c fvcore fvcore
25+
conda install -c cub
2426
```
2527

2628
### Tests/Linting and Demos
2729

28-
For developing on top of PyTorch3D or contributing, you will need to run the linter and tests. If you want to run any of the notebook tutorials as `docs/tutorials` you will also need matplotlib.
30+
For developing on top of PyTorch3D or contributing, you will need to run the linter and tests. If you want to run any of the notebook tutorials as `docs/tutorials` or the examples in `docs/examples` you will also need matplotlib and OpenCV.
2931
- scikit-image
3032
- black
3133
- isort
@@ -35,12 +37,13 @@ For developing on top of PyTorch3D or contributing, you will need to run the lin
3537
- jupyter
3638
- imageio
3739
- plotly
40+
- opencv-python
3841

3942
These can be installed by running:
4043
```
41-
# Demos
44+
# Demos and examples
4245
conda install jupyter
43-
pip install scikit-image matplotlib imageio plotly
46+
pip install scikit-image matplotlib imageio plotly opencv-python
4447
4548
# Tests/Linting
4649
pip install black 'isort<5' flake8 flake8-bugbear flake8-comprehensions
@@ -81,6 +84,8 @@ To install using the code of the released version instead of from the main branc
8184
pip install 'git+https://github.com/facebookresearch/pytorch3d.git@stable'
8285
```
8386

87+
For CUDA builds with versions earlier than CUDA 11, set `CUB_HOME` before building as described above.
88+
8489
**Install from Github on macOS:**
8590
Some environment variables should be provided, like this.
8691
```
@@ -92,7 +97,7 @@ MACOSX_DEPLOYMENT_TARGET=10.14 CC=clang CXX=clang++ pip install 'git+https://git
9297
git clone https://github.com/facebookresearch/pytorch3d.git
9398
cd pytorch3d && pip install -e .
9499
```
95-
To rebuild after installing from a local clone run, `rm -rf build/ **/*.so` then `pip install -e .`. You often need to rebuild pytorch3d after reinstalling PyTorch.
100+
To rebuild after installing from a local clone run, `rm -rf build/ **/*.so` then `pip install -e .`. You often need to rebuild pytorch3d after reinstalling PyTorch. For CUDA builds with versions earlier than CUDA 11, set `CUB_HOME` before building as described above.
96101

97102
**Install from local clone on macOS:**
98103
```

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,23 @@ If you find PyTorch3D useful in your research, please cite our tech report:
106106
}
107107
```
108108

109+
If you are using the pulsar backend for sphere-rendering (the `PulsarPointRenderer` or `pytorch3d.renderer.points.pulsar.Renderer`), please cite the tech report:
110+
111+
```bibtex
112+
@article{lassner2020pulsar,
113+
author = {Christoph Lassner},
114+
title = {Fast Differentiable Raycasting for Neural Rendering using Sphere-based Representations},
115+
journal = {arXiv:2004.07484},
116+
year = {2020},
117+
}
118+
```
109119

110120
## News
111121

112122
Please see below for a timeline of the codebase updates in reverse chronological order. We are sharing updates on the releases as well as research projects which are built with PyTorch3D. The changelogs for the releases are available under [`Releases`](https://github.com/facebookresearch/pytorch3d/releases), and the builds can be installed using `conda` as per the instructions in [INSTALL.md](INSTALL.md).
113123

124+
**[November 2nd 2020]:** PyTorch3D v0.3 released, integrating the pulsar backend.
125+
114126
**[Aug 28th 2020]:** PyTorch3D v0.2.5 released
115127

116128
**[July 17th 2020]:** PyTorch3D tech report published on ArXiv: https://arxiv.org/abs/2007.08501

docs/examples/pulsar_basic.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@
55
sphere renderer. It renders and saves an image with 10 random spheres.
66
Output: basic.png.
77
"""
8+
import math
89
from os import path
910

1011
import imageio
1112
import torch
1213
from pytorch3d.renderer.points.pulsar import Renderer
1314

1415

16+
torch.manual_seed(1)
17+
1518
n_points = 10
1619
width = 1_000
1720
height = 1_000
1821
device = torch.device("cuda")
19-
renderer = Renderer(width, height, n_points).to(device)
22+
# The PyTorch3D system is right handed; in pulsar you can choose the handedness.
23+
# For easy reproducibility we use a right handed coordinate system here.
24+
renderer = Renderer(width, height, n_points, right_handed_system=True).to(device)
2025
# Generate sample data.
2126
vert_pos = torch.rand(n_points, 3, dtype=torch.float32, device=device) * 10.0
2227
vert_pos[:, 2] += 25.0
@@ -29,7 +34,7 @@
2934
0.0,
3035
0.0, # Position 0, 0, 0 (x, y, z).
3136
0.0,
32-
0.0,
37+
math.pi, # Because of the right handed system, the camera must look 'back'.
3338
0.0, # Rotation 0, 0, 0 (in axis-angle format).
3439
5.0, # Focal length in world size.
3540
2.0, # Sensor size in world size.

docs/examples/pulsar_basic_unified.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
3+
"""
4+
This example demonstrates the most trivial use of the pulsar PyTorch3D
5+
interface for sphere renderering. It renders and saves an image with
6+
10 random spheres.
7+
Output: basic-pt3d.png.
8+
"""
9+
from os import path
10+
11+
import imageio
12+
import torch
13+
from pytorch3d.renderer import PerspectiveCameras # , look_at_view_transform
14+
from pytorch3d.renderer import (
15+
PointsRasterizationSettings,
16+
PointsRasterizer,
17+
PulsarPointsRenderer,
18+
)
19+
from pytorch3d.structures import Pointclouds
20+
21+
22+
torch.manual_seed(1)
23+
24+
n_points = 10
25+
width = 1_000
26+
height = 1_000
27+
device = torch.device("cuda")
28+
29+
# Generate sample data.
30+
vert_pos = torch.rand(n_points, 3, dtype=torch.float32, device=device) * 10.0
31+
vert_pos[:, 2] += 25.0
32+
vert_pos[:, :2] -= 5.0
33+
vert_col = torch.rand(n_points, 3, dtype=torch.float32, device=device)
34+
pcl = Pointclouds(points=vert_pos[None, ...], features=vert_col[None, ...])
35+
# Alternatively, you can also use the look_at_view_transform to get R and T:
36+
# R, T = look_at_view_transform(
37+
# dist=30.0, elev=0.0, azim=180.0, at=((0.0, 0.0, 30.0),), up=((0, 1, 0),),
38+
# )
39+
cameras = PerspectiveCameras(
40+
# The focal length must be double the size for PyTorch3D because of the NDC
41+
# coordinates spanning a range of two - and they must be normalized by the
42+
# sensor width (see the pulsar example). This means we need here
43+
# 5.0 * 2.0 / 2.0 to get the equivalent results as in pulsar.
44+
focal_length=(5.0 * 2.0 / 2.0,),
45+
R=torch.eye(3, dtype=torch.float32, device=device)[None, ...],
46+
T=torch.zeros((1, 3), dtype=torch.float32, device=device),
47+
image_size=((width, height),),
48+
device=device,
49+
)
50+
vert_rad = torch.rand(n_points, dtype=torch.float32, device=device)
51+
raster_settings = PointsRasterizationSettings(
52+
image_size=(width, height),
53+
radius=vert_rad,
54+
)
55+
rasterizer = PointsRasterizer(cameras=cameras, raster_settings=raster_settings)
56+
renderer = PulsarPointsRenderer(rasterizer=rasterizer).to(device)
57+
# Render.
58+
image = renderer(
59+
pcl,
60+
gamma=(1.0e-1,), # Renderer blending parameter gamma, in [1., 1e-5].
61+
znear=(1.0,),
62+
zfar=(45.0,),
63+
radius_world=True,
64+
bg_col=torch.ones((3,), dtype=torch.float32, device=device),
65+
)[0]
66+
print("Writing image to `%s`." % (path.abspath("basic-pt3d.png")))
67+
imageio.imsave("basic-pt3d.png", (image.cpu().detach() * 255.0).to(torch.uint8).numpy())

docs/examples/pulsar_cam.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
The same scene parameterization is loaded and the camera parameters
88
distorted. Gradient-based optimization is used to converge towards the
99
original camera parameters.
10+
Output: cam.gif.
1011
"""
12+
import math
1113
from os import path
1214

1315
import cv2
1416
import imageio
1517
import numpy as np
1618
import torch
1719
from pytorch3d.renderer.points.pulsar import Renderer
20+
from pytorch3d.transforms import axis_angle_to_matrix, matrix_to_rotation_6d
1821
from torch import nn, optim
1922

2023

@@ -66,19 +69,18 @@ def __init__(self):
6669
)
6770
self.register_parameter(
6871
"cam_rot",
72+
# We're using the 6D rot. representation for better gradients.
6973
nn.Parameter(
70-
torch.tensor(
71-
[
72-
# We're using the 6D rot. representation for better gradients.
73-
0.9995,
74-
0.0300445,
75-
-0.0098482,
76-
-0.0299445,
77-
0.9995,
78-
0.0101482,
79-
],
80-
dtype=torch.float32,
81-
),
74+
matrix_to_rotation_6d(
75+
axis_angle_to_matrix(
76+
torch.tensor(
77+
[
78+
[0.02, math.pi + 0.02, 0.01],
79+
],
80+
dtype=torch.float32,
81+
)
82+
)
83+
)[0],
8284
requires_grad=True,
8385
),
8486
)
@@ -88,7 +90,7 @@ def __init__(self):
8890
torch.tensor([4.8, 1.8], dtype=torch.float32), requires_grad=True
8991
),
9092
)
91-
self.renderer = Renderer(width, height, n_points)
93+
self.renderer = Renderer(width, height, n_points, right_handed_system=True)
9294

9395
def forward(self):
9496
return self.renderer.forward(
@@ -106,7 +108,7 @@ def forward(self):
106108
torch.from_numpy(
107109
imageio.imread(
108110
"../../tests/pulsar/reference/examples_TestRenderer_test_cam.png"
109-
)
111+
)[:, ::-1, :].copy()
110112
).to(torch.float32)
111113
/ 255.0
112114
).to(device)

0 commit comments

Comments
 (0)