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))]) # 3x4 matrix 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 # tilt up 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') # tilt down 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') # pan right 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') # pan left 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') # Spin clockwise 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') # Spin anticlockwise 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') # right # direction = [1., abs(0.), abs(0.)] # camparam_right = translation_matrix(direction, length, args.num_frame).astype(np.float32) # np.savetxt(os.path.join(args.output_path, 'camera_R.txt'), camparam_right, 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)