Source code for xrprimer.ops.projection.base_projector

# yapf: disable
import logging
from operator import itemgetter
from typing import List, Union

import numpy as np

from xrprimer.data_structure.camera import (
    FisheyeCameraParameter,
    PinholeCameraParameter,
)
from xrprimer.transform.convention.camera import convert_camera_parameter
from xrprimer.utils.log_utils import get_logger

# yapf: enable


# Super class of all projectors, cannot be built
[docs]class BaseProjector: """BaseProjector for points projection.""" CAMERA_CONVENTION = 'opencv' CAMERA_WORLD2CAM = False def __init__(self, camera_parameters: List[Union[PinholeCameraParameter, str]], logger: Union[None, str, logging.Logger] = None) -> None: """Initialization for BaseProjector. Args: camera_parameters (List[Union[PinholeCameraParameter, str]]): A list of PinholeCameraParameter, or a list of paths to dumped PinholeCameraParameters. logger (Union[None, str, logging.Logger], optional): Logger for logging. If None, root logger will be selected. Defaults to None. """ self.camera_parameters = [] self.set_cameras(camera_parameters) self.logger = get_logger(logger)
[docs] def set_cameras( self, camera_parameters: List[Union[PinholeCameraParameter, FisheyeCameraParameter]] ) -> None: """Set cameras for this projector. Args: camera_parameters (List[Union[PinholeCameraParameter, str]]): A list of PinholeCameraParameter or FisheyeCameraParameter. """ self.camera_parameters = [] for input_cam_param in camera_parameters: cam_param = input_cam_param.clone() if cam_param.world2cam != self.__class__.CAMERA_WORLD2CAM: cam_param.inverse_extrinsic() if cam_param.convention != self.__class__.CAMERA_CONVENTION: cam_param = convert_camera_parameter( cam_param=cam_param, dst=self.__class__.CAMERA_CONVENTION) self.camera_parameters.append(cam_param)
[docs] def project( self, points: Union[np.ndarray, list, tuple], points_mask: Union[np.ndarray, list, tuple] = None) -> np.ndarray: """Project points with self.camera_parameters. Args: points (Union[np.ndarray, list, tuple]): An ndarray or a nested list of points3d, in shape [n_point, 3]. points_mask (Union[np.ndarray, list, tuple], optional): An ndarray or a nested list of mask, in shape [n_point, 1]. If points_mask[index] == 1, points[index] is valid for projection, else it is ignored. Defaults to None. Returns: np.ndarray: An ndarray of points2d, in shape [n_view, n_point, 2]. """ raise NotImplementedError
[docs] def project_single_point( self, points: Union[np.ndarray, list, tuple]) -> np.ndarray: """Project a single point with self.camera_parameters. Args: points (Union[np.ndarray, list, tuple]): An ndarray or a list of points3d, in shape [3]. Returns: np.ndarray: An ndarray of points2d, in shape [n_view, 2]. """ raise NotImplementedError
def __get_camera_parameters_slice__( self, index: Union[slice, int, list, tuple]) -> list: """Slice self.camera_parameters, return a sub-list. Args: index (Union[slice, int, list, tuple]): The index for slicing. Returns: list: A sliced list of self.camera_parameters, with selected cameras. """ if isinstance(index, int): index = [index] if isinstance(index, list) or isinstance(index, tuple): new_cam_param_list = itemgetter(*index)(self.camera_parameters) if len(index) == 1: new_cam_param_list = [ new_cam_param_list, ] else: new_cam_param_list = self.camera_parameters[index] new_cam_param_list = list(new_cam_param_list) return new_cam_param_list def __getitem__(self, index: Union[slice, int, list, tuple]) -> 'BaseProjector': """Slice the projector by batch dim. Args: index (Union[slice, int, list, tuple]): The index for slicing. Returns: BaseProjector: A sliced Projector of origin class, with selected cameras. """ new_cam_param_list = self.__get_camera_parameters_slice__(index) new_projector = self.__class__(camera_parameters=new_cam_param_list) return new_projector