|
import os |
|
import argparse |
|
import numpy as np |
|
from einops import rearrange, repeat |
|
import pdb |
|
|
|
|
|
def generate_rotation_extrinsics(direction: str, angle: float, num_frame: int): |
|
""" |
|
Generate extrinsic camera matrices with rotation only (no translation), |
|
allowing both positive and negative directions. |
|
|
|
Args: |
|
direction (str): '+x', '-x', '+y', '-y', '+z', or '-z' |
|
angle (float): total rotation angle in degrees |
|
num_frame (int): number of frames to interpolate the rotation |
|
|
|
Returns: |
|
List[np.ndarray]: List of 3x4 extrinsic matrices (rotation | zero translation) |
|
""" |
|
assert direction[0] in ('+', '-'), "direction must start with '+' or '-'" |
|
assert direction[1] in ('x', 'y', 'z'), "direction must be along x, y, or z" |
|
|
|
axis = direction[1] |
|
sign = 1 if direction[0] == '+' else -1 |
|
angle_rad = np.deg2rad(angle) * sign |
|
step = angle_rad / (num_frame - 1) |
|
|
|
extrinsics = [] |
|
for i in range(num_frame): |
|
theta = step * i |
|
print(theta) |
|
if axis == 'x': |
|
R = np.array([ |
|
[1, 0, 0], |
|
[0, np.cos(theta), -np.sin(theta)], |
|
[0, np.sin(theta), np.cos(theta)], |
|
]) |
|
elif axis == 'y': |
|
R = np.array([ |
|
[np.cos(theta), 0, np.sin(theta)], |
|
[0, 1, 0], |
|
[-np.sin(theta), 0, np.cos(theta)], |
|
]) |
|
elif axis == 'z': |
|
R = np.array([ |
|
[np.cos(theta), -np.sin(theta), 0], |
|
[np.sin(theta), np.cos(theta), 0], |
|
[0, 0, 1], |
|
]) |
|
|
|
Rt = np.hstack([R, np.zeros((3, 1))]) |
|
extrinsics.append(Rt) |
|
|
|
extrinsics = np.stack(extrinsics) |
|
|
|
K = np.array([0.474812, 0.844111, 0.500000, 0.500000, abs(0.000000), abs(0.000000)]) |
|
camparam = np.concatenate([repeat(K, 'n -> f n', f=num_frame), rearrange(extrinsics, 'f h w -> f (h w)')], axis=-1) |
|
|
|
return camparam |
|
|
|
def main(args): |
|
os.makedirs(args.output_path, exist_ok=True) |
|
|
|
angle = 90 |
|
|
|
|
|
direction = ('+', 'x') |
|
camparam_tilt_up = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Tilt_Up_{angle:01f}.txt'), camparam_tilt_up, fmt='%1.6f') |
|
|
|
|
|
direction = ('-', 'x') |
|
camparam_tilt_down = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Tilt_Down_{angle:01f}.txt'), camparam_tilt_down, fmt='%1.6f') |
|
|
|
|
|
direction = ('+', 'y') |
|
camparam_pan_right = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Pan_Right_{angle:01f}.txt'), camparam_pan_right, fmt='%1.6f') |
|
|
|
|
|
direction = ('-', 'y') |
|
camparam_pan_left = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Pan_Left_{angle:01f}.txt'), camparam_pan_left, fmt='%1.6f') |
|
|
|
|
|
direction = ('+', 'z') |
|
camparam_spin_clockwise = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Spin_Clockwise_{angle:01f}.txt'), camparam_spin_clockwise, fmt='%1.6f') |
|
|
|
|
|
direction = ('-', 'z') |
|
camparam_spin_anticlockwise = generate_rotation_extrinsics(direction, angle, args.num_frame).astype(np.float32) |
|
np.savetxt(os.path.join(args.output_path, f'Spin_AntiClockwise_{angle:01f}.txt'), camparam_spin_anticlockwise, fmt='%1.6f') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
parser = argparse.ArgumentParser() |
|
parser.add_argument("--output_path", type=str, required=True) |
|
parser.add_argument("--num_frame", type=int, default=49) |
|
|
|
args = parser.parse_args() |
|
main(args) |
|
|