cavargas10 commited on
Commit
69b99a0
·
verified ·
1 Parent(s): 9bd35bb

Update trellis/utils/render_utils.py

Browse files
Files changed (1) hide show
  1. trellis/utils/render_utils.py +120 -116
trellis/utils/render_utils.py CHANGED
@@ -1,116 +1,120 @@
1
- import torch
2
- import numpy as np
3
- from tqdm import tqdm
4
- import utils3d
5
- from PIL import Image
6
-
7
- from ..renderers import OctreeRenderer, GaussianRenderer, MeshRenderer
8
- from ..representations import Octree, Gaussian, MeshExtractResult
9
- from ..modules import sparse as sp
10
- from .random_utils import sphere_hammersley_sequence
11
-
12
-
13
- def yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, rs, fovs):
14
- is_list = isinstance(yaws, list)
15
- if not is_list:
16
- yaws = [yaws]
17
- pitchs = [pitchs]
18
- if not isinstance(rs, list):
19
- rs = [rs] * len(yaws)
20
- if not isinstance(fovs, list):
21
- fovs = [fovs] * len(yaws)
22
- extrinsics = []
23
- intrinsics = []
24
- for yaw, pitch, r, fov in zip(yaws, pitchs, rs, fovs):
25
- fov = torch.deg2rad(torch.tensor(float(fov))).cuda()
26
- yaw = torch.tensor(float(yaw)).cuda()
27
- pitch = torch.tensor(float(pitch)).cuda()
28
- orig = torch.tensor([
29
- torch.sin(yaw) * torch.cos(pitch),
30
- torch.cos(yaw) * torch.cos(pitch),
31
- torch.sin(pitch),
32
- ]).cuda() * r
33
- extr = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda())
34
- intr = utils3d.torch.intrinsics_from_fov_xy(fov, fov)
35
- extrinsics.append(extr)
36
- intrinsics.append(intr)
37
- if not is_list:
38
- extrinsics = extrinsics[0]
39
- intrinsics = intrinsics[0]
40
- return extrinsics, intrinsics
41
-
42
-
43
- def render_frames(sample, extrinsics, intrinsics, options={}, colors_overwrite=None, verbose=True, **kwargs):
44
- if isinstance(sample, Octree):
45
- renderer = OctreeRenderer()
46
- renderer.rendering_options.resolution = options.get('resolution', 512)
47
- renderer.rendering_options.near = options.get('near', 0.8)
48
- renderer.rendering_options.far = options.get('far', 1.6)
49
- renderer.rendering_options.bg_color = options.get('bg_color', (0, 0, 0))
50
- renderer.rendering_options.ssaa = options.get('ssaa', 4)
51
- renderer.pipe.primitive = sample.primitive
52
- elif isinstance(sample, Gaussian):
53
- renderer = GaussianRenderer()
54
- renderer.rendering_options.resolution = options.get('resolution', 512)
55
- renderer.rendering_options.near = options.get('near', 0.8)
56
- renderer.rendering_options.far = options.get('far', 1.6)
57
- renderer.rendering_options.bg_color = options.get('bg_color', (0, 0, 0))
58
- renderer.rendering_options.ssaa = options.get('ssaa', 1)
59
- renderer.pipe.kernel_size = kwargs.get('kernel_size', 0.1)
60
- renderer.pipe.use_mip_gaussian = True
61
- elif isinstance(sample, MeshExtractResult):
62
- renderer = MeshRenderer()
63
- renderer.rendering_options.resolution = options.get('resolution', 512)
64
- renderer.rendering_options.near = options.get('near', 1)
65
- renderer.rendering_options.far = options.get('far', 100)
66
- renderer.rendering_options.ssaa = options.get('ssaa', 4)
67
- else:
68
- raise ValueError(f'Unsupported sample type: {type(sample)}')
69
-
70
- rets = {}
71
- for j, (extr, intr) in tqdm(enumerate(zip(extrinsics, intrinsics)), desc='Rendering', disable=not verbose):
72
- if not isinstance(sample, MeshExtractResult):
73
- res = renderer.render(sample, extr, intr, colors_overwrite=colors_overwrite)
74
- if 'color' not in rets: rets['color'] = []
75
- if 'depth' not in rets: rets['depth'] = []
76
- rets['color'].append(np.clip(res['color'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8))
77
- if 'percent_depth' in res:
78
- rets['depth'].append(res['percent_depth'].detach().cpu().numpy())
79
- elif 'depth' in res:
80
- rets['depth'].append(res['depth'].detach().cpu().numpy())
81
- else:
82
- rets['depth'].append(None)
83
- else:
84
- res = renderer.render(sample, extr, intr)
85
- if 'normal' not in rets: rets['normal'] = []
86
- rets['normal'].append(np.clip(res['normal'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8))
87
- return rets
88
-
89
-
90
- def render_video(sample, resolution=512, bg_color=(0, 0, 0), num_frames=300, r=2, fov=40, **kwargs):
91
- yaws = torch.linspace(0, 2 * 3.1415, num_frames)
92
- pitch = 0.25 + 0.5 * torch.sin(torch.linspace(0, 2 * 3.1415, num_frames))
93
- yaws = yaws.tolist()
94
- pitch = pitch.tolist()
95
- extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitch, r, fov)
96
- return render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)
97
-
98
-
99
- def render_multiview(sample, resolution=512, nviews=30):
100
- r = 2
101
- fov = 40
102
- cams = [sphere_hammersley_sequence(i, nviews) for i in range(nviews)]
103
- yaws = [cam[0] for cam in cams]
104
- pitchs = [cam[1] for cam in cams]
105
- extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, r, fov)
106
- res = render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': (0, 0, 0)})
107
- return res['color'], extrinsics, intrinsics
108
-
109
-
110
- def render_snapshot(samples, resolution=512, bg_color=(0, 0, 0), offset=(-16 / 180 * np.pi, 20 / 180 * np.pi), r=10, fov=8, **kwargs):
111
- yaw = [0, np.pi/2, np.pi, 3*np.pi/2]
112
- yaw_offset = offset[0]
113
- yaw = [y + yaw_offset for y in yaw]
114
- pitch = [offset[1] for _ in range(4)]
115
- extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaw, pitch, r, fov)
116
- return render_frames(samples, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+ from tqdm import tqdm
4
+ import utils3d
5
+ from PIL import Image
6
+
7
+ from ..renderers import OctreeRenderer, GaussianRenderer, MeshRenderer
8
+ from ..representations import Octree, Gaussian, MeshExtractResult
9
+ from ..modules import sparse as sp
10
+ from .random_utils import sphere_hammersley_sequence
11
+
12
+
13
+ def yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, rs, fovs):
14
+ is_list = isinstance(yaws, list)
15
+ if not is_list:
16
+ yaws = [yaws]
17
+ pitchs = [pitchs]
18
+ if not isinstance(rs, list):
19
+ rs = [rs] * len(yaws)
20
+ if not isinstance(fovs, list):
21
+ fovs = [fovs] * len(yaws)
22
+ extrinsics = []
23
+ intrinsics = []
24
+ for yaw, pitch, r, fov in zip(yaws, pitchs, rs, fovs):
25
+ fov = torch.deg2rad(torch.tensor(float(fov))).cuda()
26
+ yaw = torch.tensor(float(yaw)).cuda()
27
+ pitch = torch.tensor(float(pitch)).cuda()
28
+ orig = torch.tensor([
29
+ torch.sin(yaw) * torch.cos(pitch),
30
+ torch.cos(yaw) * torch.cos(pitch),
31
+ torch.sin(pitch),
32
+ ]).cuda() * r
33
+ extr = utils3d.torch.extrinsics_look_at(orig, torch.tensor([0, 0, 0]).float().cuda(), torch.tensor([0, 0, 1]).float().cuda())
34
+ intr = utils3d.torch.intrinsics_from_fov_xy(fov, fov)
35
+ extrinsics.append(extr)
36
+ intrinsics.append(intr)
37
+ if not is_list:
38
+ extrinsics = extrinsics[0]
39
+ intrinsics = intrinsics[0]
40
+ return extrinsics, intrinsics
41
+
42
+
43
+ def get_renderer(sample, **kwargs):
44
+ if isinstance(sample, Octree):
45
+ renderer = OctreeRenderer()
46
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
47
+ renderer.rendering_options.near = kwargs.get('near', 0.8)
48
+ renderer.rendering_options.far = kwargs.get('far', 1.6)
49
+ renderer.rendering_options.bg_color = kwargs.get('bg_color', (0, 0, 0))
50
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 4)
51
+ renderer.pipe.primitive = sample.primitive
52
+ elif isinstance(sample, Gaussian):
53
+ renderer = GaussianRenderer()
54
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
55
+ renderer.rendering_options.near = kwargs.get('near', 0.8)
56
+ renderer.rendering_options.far = kwargs.get('far', 1.6)
57
+ renderer.rendering_options.bg_color = kwargs.get('bg_color', (0, 0, 0))
58
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 1)
59
+ renderer.pipe.kernel_size = kwargs.get('kernel_size', 0.1)
60
+ renderer.pipe.use_mip_gaussian = True
61
+ elif isinstance(sample, MeshExtractResult):
62
+ renderer = MeshRenderer()
63
+ renderer.rendering_options.resolution = kwargs.get('resolution', 512)
64
+ renderer.rendering_options.near = kwargs.get('near', 1)
65
+ renderer.rendering_options.far = kwargs.get('far', 100)
66
+ renderer.rendering_options.ssaa = kwargs.get('ssaa', 4)
67
+ else:
68
+ raise ValueError(f'Unsupported sample type: {type(sample)}')
69
+ return renderer
70
+
71
+
72
+ def render_frames(sample, extrinsics, intrinsics, options={}, colors_overwrite=None, verbose=True, **kwargs):
73
+ renderer = get_renderer(sample, **options)
74
+ rets = {}
75
+ for j, (extr, intr) in tqdm(enumerate(zip(extrinsics, intrinsics)), desc='Rendering', disable=not verbose):
76
+ if isinstance(sample, MeshExtractResult):
77
+ res = renderer.render(sample, extr, intr)
78
+ if 'normal' not in rets: rets['normal'] = []
79
+ rets['normal'].append(np.clip(res['normal'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8))
80
+ else:
81
+ res = renderer.render(sample, extr, intr, colors_overwrite=colors_overwrite)
82
+ if 'color' not in rets: rets['color'] = []
83
+ if 'depth' not in rets: rets['depth'] = []
84
+ rets['color'].append(np.clip(res['color'].detach().cpu().numpy().transpose(1, 2, 0) * 255, 0, 255).astype(np.uint8))
85
+ if 'percent_depth' in res:
86
+ rets['depth'].append(res['percent_depth'].detach().cpu().numpy())
87
+ elif 'depth' in res:
88
+ rets['depth'].append(res['depth'].detach().cpu().numpy())
89
+ else:
90
+ rets['depth'].append(None)
91
+ return rets
92
+
93
+
94
+ def render_video(sample, resolution=512, bg_color=(0, 0, 0), num_frames=300, r=2, fov=40, **kwargs):
95
+ yaws = torch.linspace(0, 2 * 3.1415, num_frames)
96
+ pitch = 0.25 + 0.5 * torch.sin(torch.linspace(0, 2 * 3.1415, num_frames))
97
+ yaws = yaws.tolist()
98
+ pitch = pitch.tolist()
99
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitch, r, fov)
100
+ return render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)
101
+
102
+
103
+ def render_multiview(sample, resolution=512, nviews=30):
104
+ r = 2
105
+ fov = 40
106
+ cams = [sphere_hammersley_sequence(i, nviews) for i in range(nviews)]
107
+ yaws = [cam[0] for cam in cams]
108
+ pitchs = [cam[1] for cam in cams]
109
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaws, pitchs, r, fov)
110
+ res = render_frames(sample, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': (0, 0, 0)})
111
+ return res['color'], extrinsics, intrinsics
112
+
113
+
114
+ def render_snapshot(samples, resolution=512, bg_color=(0, 0, 0), offset=(-16 / 180 * np.pi, 20 / 180 * np.pi), r=10, fov=8, **kwargs):
115
+ yaw = [0, np.pi/2, np.pi, 3*np.pi/2]
116
+ yaw_offset = offset[0]
117
+ yaw = [y + yaw_offset for y in yaw]
118
+ pitch = [offset[1] for _ in range(4)]
119
+ extrinsics, intrinsics = yaw_pitch_r_fov_to_extrinsics_intrinsics(yaw, pitch, r, fov)
120
+ return render_frames(samples, extrinsics, intrinsics, {'resolution': resolution, 'bg_color': bg_color}, **kwargs)