Source code for xrprimer.calibration.mview_pinhole_calibrator

import json
import logging
from typing import List, Union

from xrprimer.data_structure.camera import PinholeCameraParameter
from xrprimer_cpp import \
    VectorPinholeCameraParameter as VectorPinholeCameraParameter_cpp
from xrprimer_cpp import calibrator as calibrator_cpp
from .base_calibrator import BaseCalibrator


[docs]class MviewPinholeCalibrator(BaseCalibrator): """Multi-view extrinsic calibrator for pinhole cameras.""" def __init__(self, chessboard_width: int, chessboard_height: int, chessboard_square_size: int, calibrate_intrinsic: bool = False, calibrate_extrinsic: bool = True, logger: Union[None, str, logging.Logger] = None) -> None: """Initialization for MviewPinholeCalibrator class. Args: chessboard_width (int): How many internal corners along the horizontal edge of the chessboard. chessboard_height (int): How many internal corners along the vertical edge of the chessboard. chessboard_square_size (int): The edge length of a unit square in millimeter. calibrate_intrinsic (bool, optional): Whether to calibrate intrinsic. Defaults to False. calibrate_extrinsic (bool, optional): Whether to calibrate extrinsic. Defaults to True. logger (Union[None, str, logging.Logger], optional): Logger for logging. If None, root logger will be selected. Defaults to None. """ BaseCalibrator.__init__(self, logger=logger) self.chessboard_width = chessboard_width self.chessboard_height = chessboard_height self.chessboard_square_size = chessboard_square_size if calibrate_intrinsic: self.logger.error('Intrinsic calibration not implemented yet.') raise NotImplementedError if (calibrate_intrinsic or calibrate_extrinsic) is False: self.logger.error( 'Please select at least one parameter to calibrate.') raise ValueError self.calibrate_intrinsic = calibrate_intrinsic self.calibrate_extrinsic = calibrate_extrinsic
[docs] def calibrate( self, frames: List[List[str]], pinhole_param_list: List[PinholeCameraParameter], ) -> List[PinholeCameraParameter]: """Calibrate multi-PinholeCameraParameters with a chessboard. Args: frames (List[List[str]]): A nested list of image paths. The shape is [n_frame, n_view], and each element is the path to an image file. '' stands for an empty image. pinhole_param_list (List[PinholeCameraParameter]): A list of PinholeCameraParameters. Intrinsic matrix is necessary for calibration. Returns: List[PinholeCameraParameter]: A list of calibrated pinhole cameras, name, logger, resolution will be kept. """ if len(frames) <= 0: self.logger.error('Frames are necessary for pinhole extrinsic' + ' calibration.') raise ValueError if len(frames[0]) != len(pinhole_param_list): self.logger.error( 'n_view of frames must be equal to len(pinhole_param_list).') raise ValueError chessboard_config_dict = dict( chessboard_width=self.chessboard_width, chessboard_height=self.chessboard_height, chessboard_square_size=self.chessboard_square_size) ret_list = [] if self.calibrate_extrinsic: chessboard_config_str = json.dumps(chessboard_config_dict) pinhole_vector = VectorPinholeCameraParameter_cpp( pinhole_param_list) calibrator_cpp.CalibrateMultiPinholeCamera(chessboard_config_str, frames, pinhole_vector) for cam_idx, pinhole_param_cpp in enumerate(pinhole_vector): pinhole_param = PinholeCameraParameter( name=pinhole_param_list[cam_idx].name, K=pinhole_param_cpp.intrinsic, R=pinhole_param_cpp.extrinsic_r, T=pinhole_param_cpp.extrinsic_t, height=pinhole_param_list[cam_idx].height, width=pinhole_param_list[cam_idx].width, world2cam=False, convention='opencv', logger=pinhole_param_list[cam_idx].logger) ret_list.append(pinhole_param) return ret_list