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 = 1plane, a normalized coordinate rather than a pixel; applyingKwithdenormalize_points_with_intrinsics()gives the pixel.the
z > 0precondition above is not validated.
Warning
The divide is plain at every
z: atz = 0a component is infinite, ornanfor a zero numerator.project_points()instead skips its divide atabs(z) <= 1e-8and 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:
- 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:
extensionis the camera-framezof the unprojected point: the canonical point is multiplied by it and it becomes the third component.unproject()names the same argumentdepth. Both(...,)and(..., 1)extensions are accepted.
- 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 (…), matching the points’ leading dimensions. Defaults to unit depth. Default:None
- Return type:
- 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: theurow then thevrow, each holding the derivatives with respect tox,yandz.the same
z > 0precondition applies, and it is not validated either.
- Parameters:
points_in_camera (
Tensor) – torch.Tensor representing the points to project with shape (…, 3).- Return type:
- 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:
- 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:
extensionbecomes thezcomponent of the result; both a(N,)and a(N, 1)extension are accepted.
- Parameters:
- Return type:
- 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:
- 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_planeis a point on the normalized \(z = 1\) plane, not a pixel, andparamsis the flat vector[fx, fy, cx, cy]; the result is in pixels (integer pixel centres; seePinholeCamera).distort_points()is the same camera parametrized by a \((*, 3, 3)\)Kand an OpenCV coefficient vector; it takes a pixel input instead.undistort_points_affine()is the closed-form inverse.
- Parameters:
- Return type:
- 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_camerais a pixel coordinate and the result is a point on the normalized \(z = 1\) plane;paramsis the same[fx, fy, cx, cy]vector thatdistort_points_affine()takes, and this function is its closed-form inverse.paramsvalues are not validated (a design choice shared with the other intrinsics consumers): a zerofxorfygivesinfornanon that axis.
- Parameters:
- Return type:
- 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.
- Parameters:
- Return type:
- 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_planeis a point on the normalized \(z = 1\) plane, not a pixel, and the result is in pixels (integer pixel centres; seePinholeCamera).paramsis the flat vector[fx, fy, cx, cy, k0, k1, k2, k3]: the first four are the affine part thatdistort_points_affine()takes on its own, andk0tok3multiply \(\theta^2\), \(\theta^4\), \(\theta^6\) and \(\theta^8\) in the fish-eye polynomial.undistort_points_kannala_brandt()is the inverse map.
- Parameters:
- Return type:
- 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_camerais a pixel coordinate and the result is a point on the normalized \(z = 1\) plane;paramsis the same 8-element vector documented ondistort_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:
- Return type:
- 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-8the forward function uses its affine branch, so the Jacobian there isdiag(fx, fy).
- Parameters:
- Return type:
- 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]])