Spaces:
Running
on
Zero
Running
on
Zero
import os | |
import numpy as np | |
from PIL import Image | |
def load_image(fpath, sz=256): | |
img = Image.open(fpath) | |
img = img.resize((sz, sz)) | |
return np.asarray(img)[:, :, :3] | |
def spherical_to_cartesian(sph): | |
theta, azimuth, radius = sph | |
return np.array([ | |
radius * np.sin(theta) * np.cos(azimuth), | |
radius * np.sin(theta) * np.sin(azimuth), | |
radius * np.cos(theta), | |
]) | |
def cartesian_to_spherical(xyz): | |
xy = xyz[0]**2 + xyz[1]**2 | |
radius = np.sqrt(xy + xyz[2]**2) | |
theta = np.arctan2(np.sqrt(xy), xyz[2]) | |
azimuth = np.arctan2(xyz[1], xyz[0]) | |
return np.array([theta, azimuth, radius]) | |
def elu_to_c2w(eye, lookat, up): | |
if isinstance(eye, list): | |
eye = np.array(eye) | |
if isinstance(lookat, list): | |
lookat = np.array(lookat) | |
if isinstance(up, list): | |
up = np.array(up) | |
l = eye - lookat | |
if np.linalg.norm(l) < 1e-8: | |
l[-1] = 1 | |
l = l / np.linalg.norm(l) | |
s = np.cross(l, up) | |
if np.linalg.norm(s) < 1e-8: | |
s[0] = 1 | |
s = s / np.linalg.norm(s) | |
uu = np.cross(s, l) | |
rot = np.eye(3) | |
rot[0, :] = -s | |
rot[1, :] = uu | |
rot[2, :] = l | |
c2w = np.eye(4) | |
c2w[:3, :3] = rot.T | |
c2w[:3, 3] = eye | |
return c2w | |
def c2w_to_elu(c2w): | |
w2c = np.linalg.inv(c2w) | |
eye = c2w[:3, 3] | |
lookat_dir = -w2c[2, :3] | |
lookat = eye + lookat_dir | |
up = w2c[1, :3] | |
return eye, lookat, up | |
def qvec_to_rotmat(qvec): | |
return np.array([ | |
[ | |
1 - 2 * qvec[2]**2 - 2 * qvec[3]**2, | |
2 * qvec[1] * qvec[2] - 2 * qvec[0] * qvec[3], | |
2 * qvec[3] * qvec[1] + 2 * qvec[0] * qvec[2] | |
], [ | |
2 * qvec[1] * qvec[2] + 2 * qvec[0] * qvec[3], | |
1 - 2 * qvec[1]**2 - 2 * qvec[3]**2, | |
2 * qvec[2] * qvec[3] - 2 * qvec[0] * qvec[1] | |
], [ | |
2 * qvec[3] * qvec[1] - 2 * qvec[0] * qvec[2], | |
2 * qvec[2] * qvec[3] + 2 * qvec[0] * qvec[1], | |
1 - 2 * qvec[1]**2 - 2 * qvec[2]**2 | |
] | |
]) | |
def rotmat(a, b): | |
a, b = a / np.linalg.norm(a), b / np.linalg.norm(b) | |
v = np.cross(a, b) | |
c = np.dot(a, b) | |
# handle exception for the opposite direction input | |
if c < -1 + 1e-10: | |
return rotmat(a + np.random.uniform(-1e-2, 1e-2, 3), b) | |
s = np.linalg.norm(v) | |
kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]]) | |
return np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2 + 1e-10)) | |
def recenter_cameras(c2ws): | |
is_list = False | |
if isinstance(c2ws, list): | |
is_list = True | |
c2ws = np.stack(c2ws) | |
center = c2ws[..., :3, -1].mean(axis=0) | |
c2ws[..., :3, -1] = c2ws[..., :3, -1] - center | |
if is_list: | |
c2ws = [ c2w for c2w in c2ws ] | |
return c2ws | |
def rescale_cameras(c2ws, scale): | |
is_list = False | |
if isinstance(c2ws, list): | |
is_list = True | |
c2ws = np.stack(c2ws) | |
c2ws[..., :3, -1] *= scale | |
if is_list: | |
c2ws = [ c2w for c2w in c2ws ] | |
return c2ws | |