"""Functions for normalizing points and cameras."""importnumpyasnpfromjaxtypingimportFloat
[docs]defcompute_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) """ifpoints.ndim!=2orpoints.shape[1]!=3:raiseValueError(f"points must be (N, 3), but got {points.shape}.")# Translatepoints_center=points.mean(axis=0)t=-points_centert_mat=np.eye(4)t_mat[:3,3]=t# Scalemax_norm=np.linalg.norm(points-points_center,axis=1).max()s=1.0/max_norms_mat=np.eye(4)*ss_mat[3,3]=1returns_mat@t_mat
[docs]defreport_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)}")