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, and their leading dimensions broadcast against the points’. One depth scales both coordinates: any other trailing size raisesShapeError.
- 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:
- 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....is the broadcast of the points’ and the params’ leading shapes, as indistort_points_affine():Npoints with one set of params giveNJacobians.
- 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]])