Source code for ct.normalize
"""
Functions for normalizing points and cameras.
"""
import numpy as np
from jaxtyping import Float
[docs]
def compute_normalize_mat(points: Float[np.ndarray, "n 3"]) -> Float[np.ndarray, "4 4"]:
"""
Args:
points: (N, 3) numpy array.
Returns:
Returns normalize_mat, where `normalize_mat @ points_homo` is centered
at the origin and is scaled within the unit sphere (max norm equals 1).
Examples:
.. code-block:: python
# You can check the correctness of compute_normalize_mat by:
normalize_mat = ct.normalize.compute_normalize_mat(points)
points_normalized = ct.transform.transform_points(points, normalize_mat)
ct.stat.report_points_range(points_normalized)
# Typically, we also scale the camera after normalizing points. Given
# the camera parameter `K` and `T`, we can calculate `K_new` and `T_new`:
K_new = K
C = ct.convert.T_to_C(T)
C_new = ct.transform.transform_points(C.reshape((-1, 3)), normalize_mat).flatten()
pose_new = np.linalg.inv(T)
pose_new[:3, 3] = C_new
T_new = np.linalg.inv(pose_new)
"""
if points.ndim != 2 or points.shape[1] != 3:
raise ValueError(f"points must be (N, 3), but got {points.shape}.")
# Translate
points_center = points.mean(axis=0)
t = -points_center
t_mat = np.eye(4)
t_mat[:3, 3] = t
# Scale
max_norm = np.linalg.norm(points - points_center, axis=1).max()
s = 1.0 / max_norm
s_mat = np.eye(4) * s
s_mat[3, 3] = 1
return s_mat @ t_mat
[docs]
def report_points_range(points: Float[np.ndarray, "n 3"]) -> None:
"""
Report statistics about the points.
Args:
points: (N, 3) numpy array.
Prints:
- Center of the points
- Maximum radius with respect to center
- Maximum radius with respect to origin
- Range of points (min and max coordinates)
"""
points_center = points.mean(axis=0)
points_radii_wrt_center = np.linalg.norm(points - points_center, axis=1)
points_radii_wrt_origin = np.linalg.norm(points, axis=1)
print(f"center : {points_center}")
print(f"radius w.r.t center: {points_radii_wrt_center.max()}")
print(f"radius w.r.t origin: {points_radii_wrt_origin.max()}")
print(f"range : {points.min(axis=0)} to {points.max(axis=0)}")