Download render_util.py from galmetzer/z2p: direct link, hf CLI and curl.
- Browser
- Download file 3.94 kB
-
https://huggingface.co/spaces/galmetzer/z2p/resolve/main/render_util.py
- Command line
-
hf download hf://spaces/galmetzer/z2p/render_util.py
-
curl -L -o render_util.py https://huggingface.co/spaces/galmetzer/z2p/resolve/main/render_util.py
3.94 kB
| import torch | |
| import numpy as np | |
| import math | |
| import cv2 | |
| world_mat_object = torch.tensor([ | |
| [0.5085, 0.3226, 0.7984, 0.0000], | |
| [-0.3479, 0.9251, -0.1522, 0.0000], | |
| [-0.7877, -0.2003, 0.5826, 0.3384], | |
| [0.0000, 0.0000, 0.0000, 1.0000] | |
| ]) | |
| world_mat_inv = torch.tensor([ | |
| [0.4019, 0.9157, 0.0000, 0.3359], | |
| [-0.1932, 0.0848, 0.9775, -1.0227], | |
| [0.8951, -0.3928, 0.2110, -7.0748], | |
| [-0.0000, 0.0000, -0.0000, 1.0000] | |
| ]) | |
| proj = torch.tensor([ | |
| [2.1875, 0.0000, 0.0000, 0.0000], | |
| [0.0000, 3.8889, 0.0000, 0.0000], | |
| [0.0000, 0.0000, -1.0020, -0.2002], | |
| [0.0000, 0.0000, -1.0000, 0.0000] | |
| ]) | |
| RANGES = [[0, 540], [100, 960]] | |
| TARGET = [500, -1] | |
| def resize(img): | |
| if TARGET[1] == -1: | |
| r = img.shape[0] / img.shape[1] | |
| img = cv2.resize(img, (TARGET[0], int(r * TARGET[0]))) | |
| else: | |
| img = cv2.resize(img, (TARGET[0], TARGET[1])) | |
| return img | |
| def scatter(u_pix, v_pix, distances, res, radius=5): | |
| distances -= 6 | |
| img = np.zeros(res) | |
| for (u, v, d) in zip(u_pix, v_pix, distances): | |
| v, u = int(v), int(u) | |
| f = np.exp(-d / 0.7) | |
| if radius == 0: | |
| img[v, u] = max(img[v, u], f) | |
| else: | |
| for t1 in range(-radius, radius): | |
| for t2 in range(-radius, radius): | |
| ty, tx = v - t1, u - t2 | |
| ty, tx = max(0, ty), max(0, tx) | |
| ty, tx = min(res[0] - 1, ty), min(res[1] - 1, tx) | |
| img[ty, tx] = max(img[ty, tx], f) | |
| return img | |
| def generate_roation(phi_x, phi_y, phi_z): | |
| def Rx(theta): | |
| return torch.tensor([[1, 0, 0], | |
| [0, math.cos(theta), -math.sin(theta)], | |
| [0, math.sin(theta), math.cos(theta)]]) | |
| def Ry(theta): | |
| return torch.tensor([[math.cos(theta), 0, math.sin(theta)], | |
| [0, 1, 0], | |
| [-math.sin(theta), 0, math.cos(theta)]]) | |
| def Rz(theta): | |
| return torch.tensor([[math.cos(theta), -math.sin(theta), 0], | |
| [math.sin(theta), math.cos(theta), 0], | |
| [0, 0, 1]]) | |
| return Rz(phi_z) @ Ry(phi_y) @ Rx(phi_x) | |
| def rotate_pc(pc, rx, ry, rz): | |
| rotation = generate_roation(rx, ry, rz) | |
| rotated = pc.clone() | |
| rotated[:, :3] = rotated[:, :3] @ rotation.T | |
| if rotated.shape[-1] == 6: | |
| rotated[:, 3:] = rotated[:, 3:] @ rotation.T | |
| return rotated | |
| def draw_pc(pc: torch.Tensor, res=(540, 960), radius=5, timer=None, dy=0, scale=1): | |
| xyz = pc[:, :3] | |
| xyz -= xyz.mean(dim=0) | |
| t_scale = xyz.norm(dim=-1).max() | |
| xyz /= t_scale | |
| xyz *= scale | |
| xyz[:, -1] += xyz[:, -1].min() | |
| n, _ = xyz.shape | |
| if timer is not None: | |
| with timer('project'): | |
| xyz_pad = torch.cat([xyz, torch.ones_like(pc[:, :1])], dim=-1) | |
| xyz_local = xyz_pad @ world_mat_inv.T | |
| distances = -xyz_local[:, 2] | |
| projected = xyz_local @ proj.T | |
| projected = projected / projected[:, 3:4] | |
| projected = projected[:, :3] | |
| u_pix = ((projected[0] + 1) / 2) * res[1] | |
| v_pix = ((projected[1] + 1) / 2) * res[0] + dy | |
| with timer('z-buffer'): | |
| z_buffer = scatter(u_pix, v_pix, distances, res, radius=radius)[:, :] | |
| else: | |
| xyz_pad = torch.cat([xyz, torch.ones_like(pc[:, :1])], dim=-1) | |
| xyz_local = xyz_pad @ world_mat_inv.T | |
| distances = -xyz_local[:, 2] | |
| projected = xyz_local @ proj.T | |
| projected = projected / projected[:, 3:4] | |
| projected = projected[:, :3] | |
| u_pix = ((projected[:, 0] + 1) / 2) * res[1] | |
| v_pix = ((projected[:, 1] + 1) / 2) * res[0] + dy | |
| z_buffer = scatter(u_pix, v_pix, distances, res, radius=radius)[:, :] | |
| z_buffer = z_buffer[RANGES[0][0]: RANGES[0][1], :] | |
| z_buffer = z_buffer[:, RANGES[1][0]:RANGES[1][1]] | |
| z_buffer = resize(z_buffer) | |
| return z_buffer | |