Spaces:
Runtime error
Runtime error
File size: 2,926 Bytes
7a11626 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
import numpy as np
from numpy import sin, cos
from math import pi as π
from my3d import camera_pose
from my.config import BaseConf
import random
def get_K(H, W, FoV_x):
FoV_x = FoV_x / 180 * π # to rad
f = 1 / np.tan(FoV_x / 2) * (W / 2)
K = np.array([
[f, 0, -(W/2 - 0.5)],
[0, -f, -(H/2 - 0.5)],
[0, 0, -1]
])
return K
SIDEVIEW_PROMPTS = [
"front view of", "side view of", "backside view of", "side view of"
]
TOPVIEW_PROMPT = "overhead view of"
def train_eye_with_prompts(r, n):
hs = np.random.rand(n) * 360
vs = np.random.rand(n) * np.deg2rad(100)
vs = np.clip(vs, 1e-2, π-1e-2)
prompts = []
v_thresh = np.deg2rad(30)
for i in range(n):
_p = ""
if vs[i] < v_thresh:
_p = TOPVIEW_PROMPT
else:
_a = hs[i]
_a = (_a + 45) % 360
_quad = int(_a // 90)
_p = SIDEVIEW_PROMPTS[_quad]
prompts.append(_p)
θ = np.deg2rad(hs)
# φ = v
φ = np.arccos(1 - 2 * (vs / π))
eyes = np.zeros((n, 3))
eyes[:, 0] = r * sin(φ) * cos(π-θ) # x
eyes[:, 2] = r * sin(φ) * sin(π-θ) # z
eyes[:, 1] = r * cos(φ) # y
return eyes, prompts
def spiral_poses(
radius, height,
num_steps=20, num_rounds=1,
center=np.array([0, 0, 0]), up=np.array([0, 1, 0]),
):
eyes = []
for i in range(num_steps):
ratio = (i + 1) / num_steps
Δy = height * (1 - ratio)
θ = ratio * (360 * num_rounds)
θ = θ / 180 * π
# _r = max(radius * ratio, 0.5)
_r = max(radius * sin(ratio * π / 2), 0.5)
Δx, Δz = _r * np.array([np.cos(θ), np.sin(θ)])
eyes.append(center + [Δx, Δy, Δz])
poses = [
camera_pose(e, center - e, up) for e in eyes
]
return poses
class PoseConfig(BaseConf):
rend_hw: int = 64
FoV: float = 60.0
R: float = 1.5
def make(self):
cfgs = self.dict()
hw = cfgs.pop("rend_hw")
cfgs["H"] = hw
cfgs["W"] = hw
return Poser(**cfgs)
class Poser():
def __init__(self, H, W, FoV, R):
self.H, self.W = H, W
self.R = R
self.K = get_K(H, W, FoV)
def sample_train(self, n):
eyes, prompts = train_eye_with_prompts(r=self.R, n=n)
up = np.array([0, 1, 0])
poses = [
camera_pose(e, -e, up) for e in eyes
]
poses = np.stack(poses, 0)
# FoV during training: [40,70]
random_Ks = [
get_K(self.H, self.W, random.random() * 30 + 40)
for i in range(len(poses))
# self.K for i in range(len(poses))
]
# return self.K, poses, prompts
return random_Ks, poses, prompts
def sample_test(self, n):
poses = spiral_poses(self.R, self.R, n, num_rounds=3)
poses = np.stack(poses, axis=0)
return self.K, poses
|