Creates a smooth spline path between input keyframe camera poses. Spline is calculated with poses in format (position, lookat-point, up-point). Args: poses: (n, 3, 4) array of input pose keyframes. n_interp: returned path will have n_interp * (n - 1) total poses. spline_degree: pol
(poses, n_interp, spline_degree=5,
smoothness=.03, rot_weight=.1)
| 125 | return poses_recentered, transform |
| 126 | |
| 127 | def generate_interpolated_path(poses, n_interp, spline_degree=5, |
| 128 | smoothness=.03, rot_weight=.1): |
| 129 | """Creates a smooth spline path between input keyframe camera poses. |
| 130 | |
| 131 | Spline is calculated with poses in format (position, lookat-point, up-point). |
| 132 | |
| 133 | Args: |
| 134 | poses: (n, 3, 4) array of input pose keyframes. |
| 135 | n_interp: returned path will have n_interp * (n - 1) total poses. |
| 136 | spline_degree: polynomial degree of B-spline. |
| 137 | smoothness: parameter for spline smoothing, 0 forces exact interpolation. |
| 138 | rot_weight: relative weighting of rotation/translation in spline solve. |
| 139 | |
| 140 | Returns: |
| 141 | Array of new camera poses with shape (n_interp * (n - 1), 3, 4). |
| 142 | """ |
| 143 | |
| 144 | def poses_to_points(poses, dist): |
| 145 | """Converts from pose matrices to (position, lookat, up) format.""" |
| 146 | pos = poses[:, :3, -1] |
| 147 | lookat = poses[:, :3, -1] - dist * poses[:, :3, 2] |
| 148 | up = poses[:, :3, -1] + dist * poses[:, :3, 1] |
| 149 | return np.stack([pos, lookat, up], 1) |
| 150 | |
| 151 | def points_to_poses(points): |
| 152 | """Converts from (position, lookat, up) format to pose matrices.""" |
| 153 | return np.array([viewmatrix(p - l, u - p, p) for p, l, u in points]) |
| 154 | |
| 155 | def interp(points, n, k, s): |
| 156 | """Runs multidimensional B-spline interpolation on the input points.""" |
| 157 | sh = points.shape |
| 158 | pts = np.reshape(points, (sh[0], -1)) |
| 159 | k = min(k, sh[0] - 1) |
| 160 | tck, _ = scipy.interpolate.splprep(pts.T, k=k, s=s) |
| 161 | u = np.linspace(0, 1, n, endpoint=False) |
| 162 | new_points = np.array(scipy.interpolate.splev(u, tck)) |
| 163 | new_points = np.reshape(new_points.T, (n, sh[1], sh[2])) |
| 164 | return new_points |
| 165 | |
| 166 | ### Additional operation |
| 167 | # inter_poses = [] |
| 168 | # for pose in poses: |
| 169 | # tmp_pose = np.eye(4) |
| 170 | # tmp_pose[:3] = np.concatenate([pose.R.T, pose.T[:, None]], 1) |
| 171 | # tmp_pose = np.linalg.inv(tmp_pose) |
| 172 | # tmp_pose[:, 1:3] *= -1 |
| 173 | # inter_poses.append(tmp_pose) |
| 174 | # inter_poses = np.stack(inter_poses, 0) |
| 175 | # poses, transform = transform_poses_pca(inter_poses) |
| 176 | |
| 177 | points = poses_to_points(poses, dist=rot_weight) |
| 178 | new_points = interp(points, |
| 179 | n_interp * (points.shape[0] - 1), |
| 180 | k=spline_degree, |
| 181 | s=smoothness) |
| 182 | return points_to_poses(new_points) |
| 183 | |
| 184 |
no test coverage detected