Source code for sym.polynomial_camera_cal

# -----------------------------------------------------------------------------
# This file was autogenerated by symforce from template:
#     cam_package/CLASS.py.jinja
# Do NOT modify by hand.
# -----------------------------------------------------------------------------

from __future__ import annotations

import typing as T

import numpy

from .ops import polynomial_camera_cal as ops


[docs]class PolynomialCameraCal(object): """ Autogenerated Python implementation of :py:class:`symforce.cam.polynomial_camera_cal.PolynomialCameraCal`. Polynomial camera model in the style of OpenCV Distortion is a multiplicative factor applied to the image plane coordinates in the camera frame. Mapping between distorted image plane coordinates and image coordinates is done using a standard linear model. The distortion function is a 6th order even polynomial that is a function of the radius of the image plane coordinates:: r = (p_img[0] ** 2 + p_img[1] ** 2) ** 0.5 distorted_weight = 1 + c0 * r^2 + c1 * r^4 + c2 * r^6 uv = p_img * distorted_weight """ __slots__ = ["data"] # This is because of an issue where mypy doesn't recognize attributes defined in __slots__ # See https://github.com/python/mypy/issues/5941 if T.TYPE_CHECKING: data: list[float] = [] def __init__( self, focal_length: T.Union[T.Sequence[float], numpy.ndarray], principal_point: T.Union[T.Sequence[float], numpy.ndarray], critical_undistorted_radius: float, distortion_coeffs: T.Union[T.Sequence[float], numpy.ndarray], ) -> None: self.data: list[float] = [] if isinstance(focal_length, numpy.ndarray): if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( "Expected focal_length to be a vector of length 2; instead had shape {}".format( focal_length.shape ) ) elif len(focal_length) != 2: raise IndexError( "Expected focal_length to be a sequence of length 2, was instead length {}.".format( len(focal_length) ) ) if isinstance(principal_point, numpy.ndarray): if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( "Expected principal_point to be a vector of length 2; instead had shape {}".format( principal_point.shape ) ) elif len(principal_point) != 2: raise IndexError( "Expected principal_point to be a sequence of length 2, was instead length {}.".format( len(principal_point) ) ) if isinstance(distortion_coeffs, numpy.ndarray): if distortion_coeffs.shape in {(3, 1), (1, 3)}: distortion_coeffs = distortion_coeffs.flatten() elif distortion_coeffs.shape != (3,): raise IndexError( "Expected distortion_coeffs to be a vector of length 3; instead had shape {}".format( distortion_coeffs.shape ) ) elif len(distortion_coeffs) != 3: raise IndexError( "Expected distortion_coeffs to be a sequence of length 3, was instead length {}.".format( len(distortion_coeffs) ) ) self.data.extend(focal_length) self.data.extend(principal_point) self.data.append(critical_undistorted_radius) self.data.extend(distortion_coeffs) def __repr__(self) -> str: return "<{} {}>".format(self.__class__.__name__, self.data) # -------------------------------------------------------------------------- # CameraOps # --------------------------------------------------------------------------
[docs] def focal_length(self: PolynomialCameraCal) -> numpy.ndarray: """ Return the focal length. """ return ops.CameraOps.focal_length(self)
[docs] def principal_point(self: PolynomialCameraCal) -> numpy.ndarray: """ Return the principal point. """ return ops.CameraOps.principal_point(self)
[docs] def pixel_from_camera_point( self: PolynomialCameraCal, point: numpy.ndarray, epsilon: float ) -> tuple[numpy.ndarray, float]: """ Project a 3D point in the camera frame into 2D pixel coordinates. Returns: pixel: (x, y) coordinate in pixels if valid is_valid: 1 if the operation is within bounds else 0 """ return ops.CameraOps.pixel_from_camera_point(self, point, epsilon)
[docs] def pixel_from_camera_point_with_jacobians( self: PolynomialCameraCal, point: numpy.ndarray, epsilon: float ) -> tuple[numpy.ndarray, float, numpy.ndarray, numpy.ndarray]: """ Project a 3D point in the camera frame into 2D pixel coordinates. Returns: pixel: (x, y) coordinate in pixels if valid is_valid: 1 if the operation is within bounds else 0 pixel_D_cal: Derivative of pixel with respect to intrinsic calibration parameters pixel_D_point: Derivative of pixel with respect to point """ return ops.CameraOps.pixel_from_camera_point_with_jacobians(self, point, epsilon)
# -------------------------------------------------------------------------- # StorageOps concept # --------------------------------------------------------------------------
[docs] @staticmethod def storage_dim() -> int: return 8
[docs] def to_storage(self) -> list[float]: return list(self.data)
[docs] @classmethod def from_storage(cls, vec: T.Sequence[float]) -> PolynomialCameraCal: instance = cls.__new__(cls) if isinstance(vec, list): instance.data = vec else: instance.data = list(vec) if len(vec) != cls.storage_dim(): raise ValueError( "{} has storage dim {}, got {}.".format(cls.__name__, cls.storage_dim(), len(vec)) ) return instance
# -------------------------------------------------------------------------- # LieGroupOps concept # --------------------------------------------------------------------------
[docs] @staticmethod def tangent_dim() -> int: return 8
[docs] @classmethod def from_tangent(cls, vec: numpy.ndarray, epsilon: float = 1e-8) -> PolynomialCameraCal: if len(vec) != cls.tangent_dim(): raise ValueError( "Vector dimension ({}) not equal to tangent space dimension ({}).".format( len(vec), cls.tangent_dim() ) ) return ops.LieGroupOps.from_tangent(vec, epsilon)
[docs] def to_tangent(self, epsilon: float = 1e-8) -> numpy.ndarray: return ops.LieGroupOps.to_tangent(self, epsilon)
[docs] def retract(self, vec: numpy.ndarray, epsilon: float = 1e-8) -> PolynomialCameraCal: if len(vec) != self.tangent_dim(): raise ValueError( "Vector dimension ({}) not equal to tangent space dimension ({}).".format( len(vec), self.tangent_dim() ) ) return ops.LieGroupOps.retract(self, vec, epsilon)
[docs] def local_coordinates(self, b: PolynomialCameraCal, epsilon: float = 1e-8) -> numpy.ndarray: return ops.LieGroupOps.local_coordinates(self, b, epsilon)
[docs] def interpolate( self, b: PolynomialCameraCal, alpha: float, epsilon: float = 1e-8 ) -> PolynomialCameraCal: return ops.LieGroupOps.interpolate(self, b, alpha, epsilon)
# -------------------------------------------------------------------------- # General Helpers # -------------------------------------------------------------------------- def __eq__(self, other: T.Any) -> bool: if isinstance(other, PolynomialCameraCal): return self.data == other.data else: return False