symforce.cam.spherical_camera_cal module

class SphericalCameraCal(focal_length, principal_point, distortion_coeffs=(0.0, 0.0, 0.0, 0.0), critical_theta=None, max_theta=3.141592653589793)[source]

Bases: CameraCal

Kannala-Brandt camera model, where radial distortion is modeled relative to the 3D angle theta off the optical axis as opposed to radius within the image plane (i.e. ATANCamera)

I.e. the radius in the image plane as a function of the angle theta from the camera z-axis is assumed to be given by:

r(theta) = theta + d[0] * theta^3 + d[1] * theta^5 + d[2] * theta^7 + d[3] * theta^9

With no tangential coefficients, this model is over-parameterized in that we may scale all the distortion coefficients by a constant, and the focal length by the inverse of that constant. To fix this issue, we peg the first coefficient at 1. So while the distortion dimension is ‘4’, the actual total number of coeffs is 5.

Additionally, the storage for this class includes the critical theta, the maximum angle from the optical axis where projection is invertible; although the critical theta is a function of the other parameters, this function requires polynomial root finding, so it should be computed externally at runtime and set to the computed value.

Paper: A generic camera model and calibration method for conventional, wide-angle, and fish-eye lenses Kannala, Juho; Brandt, Sami S. PAMI 2006

This is the simpler “P9” model without any non-radially-symmetric distortion params.

The storage for this class is: [ fx fy cx cy critical_theta d0 d1 d2 d3 ]

Parameters:
  • focal_length (Sequence[float]) –

  • principal_point (Sequence[float]) –

  • distortion_coeffs (Sequence[float]) –

  • critical_theta (Optional[float]) –

  • max_theta (float) –

NUM_DISTORTION_COEFFS = 4
__init__(focal_length, principal_point, distortion_coeffs=(0.0, 0.0, 0.0, 0.0), critical_theta=None, max_theta=3.141592653589793)[source]
Parameters:
  • critical_theta (Optional[float]) – The maximum angle from the optical axis for which the projection is valid. In general, this should be at least as large as the FOV of the camera. If the distortion coeffs are all numerical, this will be computed automatically as either the first local maximum of r(theta) in the interval (0, max_theta), or as max_theta if there is no local maximum in the interval.

  • max_theta (float) – Used only to compute critical_theta when the distortion coefficients are all numerical, see the description for critical_theta. The default value of 180 degrees should generally be fine regardless of the actual field of view

  • focal_length (Sequence[float]) –

  • principal_point (Sequence[float]) –

  • distortion_coeffs (Sequence[float]) –

classmethod from_distortion_coeffs(focal_length, principal_point, distortion_coeffs=(), **kwargs)[source]

Construct a Camera Cal of type cls from the focal_length, principal_point, and distortion_coeffs.

kwargs are additional arguments which will be passed to the constructor.

Symbolic arguments may only be passed if the kwarg critical_theta is passed.

Parameters:
  • focal_length (Sequence[float]) –

  • principal_point (Sequence[float]) –

  • distortion_coeffs (Sequence[float]) –

  • kwargs (float) –

Return type:

SphericalCameraCal

classmethod storage_order()[source]

Return list of the names of values returned in the storage paired with the dimension of each value.

Return type:

Tuple[Tuple[str, int], …]

classmethod storage_dim()[source]

Dimension of underlying storage

Return type:

int

to_storage()[source]

Flat list representation of the underlying storage, length of STORAGE_DIM. This is used purely for plumbing, it is NOT like a tangent space.

Return type:

List[float]

classmethod from_storage(vec)[source]

Construct from a flat list representation. Opposite of .to_storage().

Parameters:

vec (Sequence[float]) –

Return type:

SphericalCameraCal

classmethod symbolic(name, **kwargs)[source]

Construct a symbolic element with the given name prefix. Kwargs are forwarded to sf.Symbol (for example, sympy assumptions).

Parameters:
  • name (str) –

  • kwargs (Any) –

Return type:

SphericalCameraCal

pixel_from_camera_point(point, epsilon=0.0)[source]

Project a 3D point in the camera frame into 2D pixel coordinates.

Returns:

(x, y) coordinate in pixels if valid is_valid: 1 if the operation is within bounds else 0

Return type:

pixel

Parameters:
  • point (Matrix31) –

  • epsilon (float) –

camera_ray_from_pixel(pixel, epsilon=0)[source]

Backproject a 2D pixel coordinate into a 3D ray in the camera frame.

TODO(hayk): Add a normalize boolean argument? Like in cam.Camera

Returns:

The ray in the camera frame (NOT normalized) is_valid: 1 if the operation is within bounds else 0

Return type:

camera_ray

Parameters:
  • pixel (Matrix21) –

  • epsilon (float) –