# Camera Model Helper ## Interface Definition **Interface Name**: `ICameraModel` ### Interface Methods ```python class ICameraModel(ABC): @abstractmethod def project(self, point_3d: np.ndarray, camera_params: CameraParameters) -> Tuple[float, float]: pass @abstractmethod def unproject(self, pixel: Tuple[float, float], depth: float, camera_params: CameraParameters) -> np.ndarray: pass @abstractmethod def get_focal_length(self, camera_params: CameraParameters) -> Tuple[float, float]: pass @abstractmethod def apply_distortion(self, pixel: Tuple[float, float], distortion_coeffs: List[float]) -> Tuple[float, float]: pass @abstractmethod def remove_distortion(self, pixel: Tuple[float, float], distortion_coeffs: List[float]) -> Tuple[float, float]: pass ``` ## Component Description Pinhole camera projection model with Brown-Conrady distortion handling. ## API Methods ### `project(point_3d: np.ndarray, camera_params: CameraParameters) -> Tuple[float, float]` **Description**: Projects 3D point to 2D image pixel. **Formula**: ``` x = fx * X/Z + cx y = fy * Y/Z + cy ``` --- ### `unproject(pixel: Tuple[float, float], depth: float, camera_params: CameraParameters) -> np.ndarray` **Description**: Unprojects pixel to 3D ray at given depth. **Formula**: ``` X = (x - cx) * depth / fx Y = (y - cy) * depth / fy Z = depth ``` --- ### `get_focal_length(camera_params: CameraParameters) -> Tuple[float, float]` **Description**: Returns (fx, fy) in pixels. **Formula**: ``` fx = focal_length_mm * image_width / sensor_width_mm fy = focal_length_mm * image_height / sensor_height_mm ``` --- ### `apply_distortion(pixel: Tuple[float, float], distortion_coeffs: List[float]) -> Tuple[float, float]` **Description**: Applies radial and tangential distortion (Brown-Conrady model). --- ### `remove_distortion(pixel: Tuple[float, float], distortion_coeffs: List[float]) -> Tuple[float, float]` **Description**: Removes distortion from observed pixel. ## Dependencies **External**: opencv-python, numpy ## Data Models ```python class CameraParameters(BaseModel): focal_length: float # mm sensor_width: float # mm sensor_height: float # mm resolution_width: int resolution_height: int principal_point: Tuple[float, float] # (cx, cy) pixels distortion_coefficients: List[float] # [k1, k2, p1, p2, k3] ```