kornia.geometry.camera#

Projections#

kornia.geometry.camera.project_points_z1(points_in_camera)[source]#

Project one or more points from the camera frame into the canonical z=1 plane through perspective division.

\[\begin{split}\begin{bmatrix} u \\ v \\ w \end{bmatrix} = \begin{bmatrix} x \\ y \\ z \end{bmatrix} / z\end{split}\]

Note

This function has a precondition that the points are in front of the camera, i.e. z > 0. If this is not the case, the points will be projected to the canonical plane, but the resulting points will be behind the camera and causing numerical issues for z == 0.

Convention:
  • the input is a camera-frame point and the output its position on the canonical z = 1 plane, a normalized coordinate rather than a pixel; applying K with denormalize_points_with_intrinsics() gives the pixel.

  • the z > 0 precondition above is not validated.

Warning

The divide is plain at every z: at z = 0 a component is infinite, or nan for a zero numerator. project_points() instead skips its divide at abs(z) <= 1e-8 and returns finite pixels there, so the two disagree below that threshold: #4267.

Parameters:

points_in_camera (Tensor) – torch.Tensor representing the points to project with shape (…, 3).

Return type:

Tensor

Returns:

torch.Tensor representing the projected points with shape (…, 2).

Example

>>> points = torch.tensor([1., 2., 3.])
>>> project_points_z1(points)
tensor([0.3333, 0.6667])
kornia.geometry.camera.unproject_points_z1(points_in_cam_canonical, extension=None)[source]#

Unproject one or more points from the canonical z=1 plane into the camera frame.

\[\begin{split}\begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} u \\ v \end{bmatrix} \cdot w\end{split}\]
Convention:
  • extension is the camera-frame z of the unprojected point: the canonical point is multiplied by it and it becomes the third component. unproject() names the same argument depth. Both (...,) and (..., 1) extensions are accepted, and their leading dimensions broadcast against the points’. One depth scales both coordinates: any other trailing size raises ShapeError.

Parameters:
  • points_in_cam_canonical (Tensor) – torch.Tensor representing the points to unproject with shape (…, 2).

  • extension (Optional[Tensor], optional) – torch.Tensor representing the extension (depth) of the points to unproject with shape (…, 1) or (…), broadcastable against the points’ leading dimensions. Defaults to unit depth. Default: None

Return type:

Tensor

Returns:

torch.Tensor representing the unprojected points with shape (…, 3).

Example

>>> points = torch.tensor([1., 2.])
>>> extension = torch.tensor([3.])
>>> unproject_points_z1(points, extension)
tensor([3., 6., 3.])
kornia.geometry.camera.dx_project_points_z1(points_in_camera)[source]#

Compute the derivative of the x projection with respect to the x coordinate.

Returns point derivative of inverse depth point projection with respect to the x coordinate.

\[\begin{split}\frac{\partial \pi}{\partial x} = \begin{bmatrix} \frac{1}{z} & 0 & -\frac{x}{z^2} \\ 0 & \frac{1}{z} & -\frac{y}{z^2} \end{bmatrix}\end{split}\]

Note

This function has a precondition that the points are in front of the camera, i.e. z > 0. If this is not the case, the points will be projected to the canonical plane, but the resulting points will be behind the camera and causing numerical issues for z == 0.

Convention:
  • the result is the full Jacobian of project_points_z1() with shape (..., 2, 3), laid out row-major in the output index: the u row then the v row, each holding the derivatives with respect to x, y and z.

  • the same z > 0 precondition applies, and it is not validated either.

Parameters:

points_in_camera (Tensor) – torch.Tensor representing the points to project with shape (…, 3).

Return type:

Tensor

Returns:

torch.Tensor representing the derivative of the x projection with respect to the x coordinate with shape (…, 2, 3).

Example

>>> points = torch.tensor([1., 2., 3.])
>>> dx_project_points_z1(points)
tensor([[ 0.3333,  0.0000, -0.1111],
        [ 0.0000,  0.3333, -0.2222]])
kornia.geometry.camera.project_points_orthographic(points_in_camera)[source]#

Project points from the camera frame into the canonical z=1 plane through orthographic projection.

\[\begin{split}\begin{bmatrix} u \\ v \end{bmatrix} = \begin{bmatrix} x \\ y \\ z \end{bmatrix}\end{split}\]
Parameters:

points_in_camera (Tensor) – torch.Tensor representing the points to project.

Return type:

Tensor

Returns:

torch.Tensor representing the projected points.

Example

>>> points = torch.tensor([1., 2., 3.])
>>> project_points_orthographic(points)
tensor([1., 2.])
kornia.geometry.camera.unproject_points_orthographic(points_in_camera, extension)[source]#

Unproject one or more points from the canonical z=1 plane into the camera frame.

\[\begin{split}\begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} u \\ v \\ w \end{bmatrix}\end{split}\]
Convention:
  • extension becomes the z component of the result; both a (N,) and a (N, 1) extension are accepted.

Parameters:
  • points_in_camera (Tensor) – torch.Tensor representing the points to unproject with shape (…, 2).

  • extension (Tensor) – torch.Tensor representing the extension of the points to unproject with shape (…, 1).

Return type:

Tensor

Returns:

torch.Tensor representing the unprojected points with shape (…, 3).

Example

>>> points = torch.tensor([1., 2.])
>>> extension = torch.tensor([3.])
>>> unproject_points_orthographic(points, extension)
tensor([1., 2., 3.])
kornia.geometry.camera.dx_project_points_orthographic(points_in_camera)[source]#

Compute the derivative of the x projection with respect to the x coordinate.

\[\frac{\partial u}{\partial x} = 1\]
Parameters:

points_in_camera (Tensor) – torch.Tensor representing the points to project.

Return type:

Tensor

Returns:

torch.Tensor representing the derivative of the x projection with respect to the x coordinate.

Example

>>> points = torch.tensor([1., 2., 3.])
>>> dx_project_points_orthographic(points)
tensor([1.])

Distortion#

kornia.geometry.camera.distort_points_affine(projected_points_in_camera_z1_plane, params)[source]#

Distort one or more points from the canonical z=1 plane into the camera frame.

\[\begin{split}\begin{bmatrix} u \\ v \end{bmatrix} = \begin{bmatrix} f_x & 0 \\ 0 & f_y \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} c_x \\ c_y \end{bmatrix}\end{split}\]
Convention:
  • projected_points_in_camera_z1_plane is a point on the normalized \(z = 1\) plane, not a pixel, and params is the flat vector [fx, fy, cx, cy]; the result is in pixels (integer pixel centres; see PinholeCamera).

  • distort_points() is the same camera parametrized by a \((*, 3, 3)\) K and an OpenCV coefficient vector; it takes a pixel input instead.

  • undistort_points_affine() is the closed-form inverse.

Parameters:
  • projected_points_in_camera_z1_plane (Tensor) – torch.Tensor representing the points to distort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the affine distortion model with shape (…, 4).

Return type:

Tensor

Returns:

torch.Tensor representing the distorted points with shape (…, 2).

Example

>>> points = torch.tensor([319.5, 239.5])  # center of a 640x480 image
>>> params = torch.tensor([600., 600., 319.5, 239.5])
>>> distort_points_affine(points, params)
tensor([192019.5000, 143939.5000])
kornia.geometry.camera.undistort_points_affine(distorted_points_in_camera, params)[source]#

Undistort one or more points from the camera frame into the canonical z=1 plane.

\[\begin{split}\begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} f_x & 0 \\ 0 & f_y \end{bmatrix}^{-1} \left( \begin{bmatrix} u \\ v \end{bmatrix} - \begin{bmatrix} c_x \\ c_y \end{bmatrix} \right)\end{split}\]
Convention:
  • distorted_points_in_camera is a pixel coordinate and the result is a point on the normalized \(z = 1\) plane; params is the same [fx, fy, cx, cy] vector that distort_points_affine() takes, and this function is its closed-form inverse.

  • params values are not validated (a design choice shared with the other intrinsics consumers): a zero fx or fy gives inf or nan on that axis.

Parameters:
  • distorted_points_in_camera (Tensor) – torch.Tensor representing the points to undistort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the affine distortion model with shape (…, 4).

Return type:

Tensor

Returns:

torch.Tensor representing the undistorted points with shape (…, 2).

Example

>>> points = torch.tensor([319.5, 239.5])  # center of a 640x480 image
>>> params = torch.tensor([600., 600., 319.5, 239.5])
>>> undistort_points_affine(points, params)
tensor([0., 0.])
kornia.geometry.camera.dx_distort_points_affine(projected_points_in_camera_z1_plane, params)[source]#

Compute the Jacobian of the affine distortion with respect to the point.

\[\begin{split}\frac{\partial (u, v)}{\partial (x, y)} = \begin{bmatrix} f_x & 0 \\ 0 & f_y \end{bmatrix}\end{split}\]
Convention:
  • the result is the \((..., 2, 2)\) Jacobian of distort_points_affine() with respect to the point: rows are the output components (u, v), columns the input components (x, y).

  • the map is affine, so that Jacobian is diag(fx, fy) and does not depend on the point.

  • ... is the broadcast of the points’ and the params’ leading shapes, as in distort_points_affine(): N points with one set of params give N Jacobians.

Parameters:
  • projected_points_in_camera_z1_plane (Tensor) – torch.Tensor representing the points to distort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the affine distortion model with shape (…, 4).

Return type:

Tensor

Returns:

torch.Tensor representing the Jacobian of the distortion with respect to the point with shape (…, 2, 2).

Example

>>> points = torch.tensor([319.5, 239.5])  # center of a 640x480 image
>>> params = torch.tensor([600., 600., 319.5, 239.5])
>>> dx_distort_points_affine(points, params)
tensor([[600.,   0.],
        [  0., 600.]])
kornia.geometry.camera.distort_points_kannala_brandt(projected_points_in_camera_z1_plane, params)[source]#

Distort points from the canonical z=1 plane into the camera frame using the Kannala-Brandt model.

Convention:
  • projected_points_in_camera_z1_plane is a point on the normalized \(z = 1\) plane, not a pixel, and the result is in pixels (integer pixel centres; see PinholeCamera).

  • params is the flat vector [fx, fy, cx, cy, k0, k1, k2, k3]: the first four are the affine part that distort_points_affine() takes on its own, and k0 to k3 multiply \(\theta^2\), \(\theta^4\), \(\theta^6\) and \(\theta^8\) in the fish-eye polynomial.

  • undistort_points_kannala_brandt() is the inverse map.

Parameters:
  • projected_points_in_camera_z1_plane (Tensor) – torch.Tensor representing the points to distort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the Kannala-Brandt distortion model with shape (…, 8).

Return type:

Tensor

Returns:

torch.Tensor representing the distorted points with shape (…, 2).

Example

>>> points = torch.tensor([319.5, 239.5])  # center of a 640x480 image
>>> params = torch.tensor([1000.0, 1000.0, 320.0, 280.0, 0.1, 0.01, 0.001, 0.0001])
>>> distort_points_kannala_brandt(points, params)
tensor([1982.6832, 1526.3619])
kornia.geometry.camera.undistort_points_kannala_brandt(distorted_points_in_camera, params)[source]#

Undistort points from the camera frame into the canonical z=1 plane using the Kannala-Brandt model.

Convention:
  • distorted_points_in_camera is a pixel coordinate and the result is a point on the normalized \(z = 1\) plane; params is the same 8-element vector documented on distort_points_kannala_brandt().

  • the inverse is a fixed number of Gauss-Newton steps with no convergence test and no caller-visible step count, so the round trip through distort_points_kannala_brandt() closes only to the accuracy that iteration reaches.

  • a zero distorted radius maps to the origin.

Parameters:
  • distorted_points_in_camera (Tensor) – torch.Tensor representing the points to undistort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the Kannala-Brandt distortion model with shape (…, 8).

Return type:

Tensor

Returns:

torch.Tensor representing the undistorted points with shape (…, 2).

Example

>>> points = torch.tensor([319.5, 239.5])  # center of a 640x480 image
>>> params = torch.tensor([1000.0, 1000.0, 320.0, 280.0, 0.1, 0.01, 0.001, 0.0001])
>>> undistort_points_kannala_brandt(points, params).shape
torch.Size([2])
kornia.geometry.camera.dx_distort_points_kannala_brandt(projected_points_in_camera_z1_plane, params)[source]#

Return the analytic Jacobian of the Kannala-Brandt distortion model.

Convention:
  • the result has shape \((..., 2, 2)\) and is laid out like the Jacobian that dx_distort_points_affine() returns: rows are the output components (u, v), columns the input components (x, y).

  • for squared radii <= 1e-8 the forward function uses its affine branch, so the Jacobian there is diag(fx, fy).

Parameters:
  • projected_points_in_camera_z1_plane (Tensor) – torch.Tensor representing the points to distort with shape (…, 2).

  • params (Tensor) – torch.Tensor representing the parameters of the Kannala-Brandt distortion model with shape (…, 8).

Return type:

Tensor

Returns:

torch.Tensor representing the derivative of the distortion with respect to the point with shape (…, 2, 2).

Example

>>> points = torch.tensor([1., 2.])
>>> params = torch.tensor([1000.0, 1000.0, 320.0, 280.0, 0.1, 0.01, 0.001, 0.0001])
>>> dx_distort_points_kannala_brandt(points, params)
tensor([[ 524.3779, -136.9029],
        [-136.9029,  319.0236]])