kornia.geometry.depth#
- kornia.geometry.depth.depth_from_disparity(disparity, baseline, focal)[source]#
Compute depth from disparity.
- Convention:
the depth is
baseline * focal / disparity, elementwise:baselineis the distance between the two camera centres andfocalthe focal length in pixels, so a disparity of 2 with a baseline of 0.5 and a focal length of 100 gives a depth of 25.baselineandfocalare each a scalar (Python number, 0-d or \((1,)\) tensor) shared by the whole disparity, or a \((B,)\) tensor paired withdisparity[b], which then needs a leading batch axis of sizeB(otherwiseShapeError). The two may mix.disparityis \((*, H, W)\) and the result has its shape. Its sign is not checked.
Warning
The divisor is
disparity + 1e-8, so a zero disparity (no stereo match) returns a large finite depth set by the epsilon (5e9for baseline0.5, focal100) rather thaninf, except where the epsilon underflows: #4272.- Parameters:
disparity (
Tensor) – Disparity tensor of shape \((*, H, W)\).baseline (
float|Tensor) – Distance between the two lenses, as an int, float, or tensor of shape()or(1,), or of shape(B,)for one value per batch element.focal (
float|Tensor) – Focal length, as an int, float, or tensor of shape()or(1,), or of shape(B,)for one value per batch element.
- Return type:
- Returns:
Depth map of the shape \((*, H, W)\).
Example
>>> disparity = torch.rand(4, 1, 4, 4) >>> baseline = torch.rand(1) >>> focal = torch.rand(1) >>> depth_from_disparity(disparity, baseline, focal).shape torch.Size([4, 1, 4, 4])
- kornia.geometry.depth.depth_to_3d(depth, camera_matrix, normalize_points=False)[source]#
Compute a 3d point per pixel given its depth value and the camera intrinsics.
Note
kornia.geometry.depth.depth_to_3d_v2()computes the same points without building a meshgrid, in the \((B, H, W, 3)\) layout.- Convention:
depthis the camera-framezof each pixel and the result the camera-frame point((u - cx) z / fx, (v - cy) z / fy, z), channels-first \((B, 3, H, W)\), withuthe column andvthe row (integer pixel centres; seePinholeCamera). It equalsdepth_to_3d_v2()afterpermute(0, 2, 3, 1).normalize_points=Truereadsdepthas the Euclidean ray length instead ofz.an integer
depthis not rejected; the result takes the floating dtype ofcamera_matrix.
- Parameters:
depth (
Tensor) – image tensor containing a depth value per pixel with shape \((B, 1, H, W)\).camera_matrix (
Tensor) – tensor containing the camera intrinsics with shape \((B, 3, 3)\).normalize_points (
bool, optional) – whether to normalise the pointcloud. This must be set to True when the depth is represented as the Euclidean ray length from the camera position. Default:False
- Return type:
- Returns:
tensor with a 3d point per pixel of the same resolution as the input \((B, 3, H, W)\).
Example
>>> depth = torch.rand(1, 1, 4, 4) >>> K = torch.eye(3)[None] >>> depth_to_3d(depth, K).shape torch.Size([1, 3, 4, 4])
- kornia.geometry.depth.depth_to_3d_v2(depth, camera_matrix, normalize_points=False, xyz_grid=None)[source]#
Compute a 3d point per pixel given its depth value and the camera intrinsics.
Note
This is an alternative implementation of
kornia.geometry.depth.depth_to_3d()that does not require the creation of a meshgrid.- Convention:
depthis the camera-framezof each pixel and the result the camera-frame point((u - cx) z / fx, (v - cy) z / fy, z), channels-last \((*, H, W, 3)\), withuthe column andvthe row (integer pixel centres; seePinholeCamera). It equalsdepth_to_3d()afterpermute(0, 2, 3, 1).without
xyz_grid,camera_matrixmust be exactly \((B, 3, 3)\) (another shape raisesShapeError); withxyz_gridit is never read.normalize_points=Truereadsdepthas the Euclidean ray length instead ofz.xyz_gridreplaces the grid construction; pass whatunproject_meshgrid()returns for the same camera.
- Parameters:
depth (
Tensor) – image tensor containing a depth value per pixel with shape \((*, H, W)\).camera_matrix (
Tensor) – tensor containing the camera intrinsics with shape \((B, 3, 3)\).normalize_points (
bool, optional) – whether to normalise the pointcloud. This must be set to True when the depth is represented as the Euclidean ray length from the camera position. Default:Falsexyz_grid (
Optional[Tensor], optional) – explicit xyz point values. Default:None
- Return type:
- Returns:
tensor with a 3d point per pixel of the same resolution as the input, \((*, H, W, 3)\), whose leading dimensions are the broadcast of
depth’s and the grid’s: the Example broadcasts a \((4, 4)\) depth against a \((2, 3, 3)\) camera to \((2, 4, 4, 3)\), and a \((B, T, H, W)\) depth with anxyz_gridof shape \((B, 1, H, W, 3)\) returns \((B, T, H, W, 3)\).
Example
>>> depth = torch.rand(4, 4) >>> K = torch.eye(3).repeat(2,1,1) >>> depth_to_3d_v2(depth, K).shape torch.Size([2, 4, 4, 3])
- kornia.geometry.depth.unproject_meshgrid(height, width, camera_matrix, normalize_points=False, device=None, dtype=None)[source]#
Compute a 3d point per pixel given its depth value and the camera intrinsics.
Tip
This function should be used in conjunction with
kornia.geometry.depth.depth_to_3d_v2()to cache the meshgrid computation when warping multiple frames with the same camera intrinsics.- Convention:
the result is the camera-frame ray through each pixel at depth 1, \((B, H, W, 3)\), so multiplying it by a \((B, H, W)\) depth map reproduces
depth_to_3d_v2()(itsxyz_gridcache). Pixel centres are integers; seePinholeCamera.camera_matrixmust be \((B, 3, 3)\); an unbatched matrix or extra leading dimensions raiseShapeError.normalize_points=Truereturns the unit ray instead of the ray whosezis 1.
- Parameters:
height (
int) – height of image.width (
int) – width of image.camera_matrix (
Tensor) – tensor containing the camera intrinsics with shape \((B, 3, 3)\).normalize_points (
bool, optional) – whether to normalize the pointcloud. This must be set to True when the depth is represented as the Euclidean ray length from the camera position. Default:Falsedevice (
Optional[device], optional) – device to place the result on. Default:Nonedtype (
Optional[dtype], optional) – dtype of the result. Default:None
- Return type:
- Returns:
tensor with a 3d point per pixel, with shape \((B, H, W, 3)\).
- kornia.geometry.depth.depth_to_normals(depth, camera_matrix, normalize_points=False)[source]#
Compute the normal surface per pixel.
- Convention:
both spatial dimensions must be at least 2: a surface normal requires two tangent directions.
the normal is the unit cross product
d/dxxd/dyof the unprojected point cloud, so a fronto-parallel plane gets(0, 0, 1), pointing away from the camera; a depth growing along the columns tilts it towards-x, one growing along the rows towards-y.the arguments mean what they mean for
depth_to_3d(), and the result has its \((B, 3, H, W)\) layout.
- Parameters:
depth (
Tensor) – image tensor containing a depth value per pixel with shape \((B, 1, H, W)\), with \(H \geq 2\) and \(W \geq 2\).camera_matrix (
Tensor) – tensor containing the camera intrinsics with shape \((B, 3, 3)\).normalize_points (
bool, optional) – whether to normalize the pointcloud. This must be set to True when the depth is Default:Falseposition. (represented as the Euclidean ray length from the camera)
- Return type:
- Returns:
tensor with a normal surface vector per pixel of the same resolution as the input \((B, 3, H, W)\).
- Raises:
ShapeError – if either spatial dimension of
depthis smaller than 2.
Example
>>> depth = torch.rand(1, 1, 4, 4) >>> K = torch.eye(3)[None] >>> depth_to_normals(depth, K).shape torch.Size([1, 3, 4, 4])
- kornia.geometry.depth.depth_from_plane_equation(plane_normals, plane_offsets, points_uv, camera_matrix, eps=1e-8)[source]#
Compute depth values from plane equations and pixel coordinates.
- Convention:
the plane is given in Hessian form \(n \cdot X = d\), with the normal
plane_normalsand the offsetplane_offsetsin the camera frame:n = (0, 0, 1)withd = 2is the planez = 2, and every pixel on it has depth 2.points_uvare pixels (integer centres; seePinholeCamera), normalized here withcamera_matrix.the result is the camera-frame
zof each pixel, \((B, N)\): a list of depths, not a map.a ray-plane dot product inside \((-eps, eps)\) is replaced by \(\pm\)
epswith its sign (+epsfor an exact zero), so a grazing ray returns the large signed depthd / epsrather thaninf. In float16 a positiveepsis floored at the smallest subnormal,2**-24, because the default1e-8rounds to zero there;d / 2**-24is stillinfin float16 once|d|exceeds about3.9e-3, so pass a largerepsfor a finite depth (eps=1e-4keeps|d| <= 6.5finite).
- Parameters:
plane_normals (torch.Tensor) – Plane normal vectors of shape (B, 3).
plane_offsets (torch.Tensor) – Plane offsets of shape (B, 1).
points_uv (torch.Tensor) – Pixel coordinates of shape (B, N, 2).
camera_matrix (torch.Tensor) – Camera intrinsic matrix of shape (B, 3, 3).
eps (
float, optional) – epsilon for numerical stability. Default:1e-8
- Returns:
Computed depth values at the given pixels, shape (B, N).
- Return type:
- kornia.geometry.depth.warp_frame_depth(image_src, depth_dst, src_trans_dst, camera_matrix, normalize_points=False)[source]#
Warp a tensor from a source to destination frame by the depth in the destination.
Compute 3d points from the depth, transform them using given transformation, then project the point cloud to an image plane.
- Convention:
the depth belongs to the destination frame (
depth_dst) and the image to the source frame (image_src), andsrc_trans_dstmaps destination-frame points into the source frame. Withfx = fy = 1and a unit depth, a \(+1\) translation inxsamplesimage_srcone pixel to the right of each destination pixel.the unprojection is
depth_to_3d_v2()and the reprojectionproject_points(), whose conventions apply.the sampling is bilinear
grid_samplewith a fixedalign_corners=Trueandpadding_mode="zeros"; the output is \((B, D, H, W)\) withimage_src’s channels.
Warning
DepthWarperperforms the same warp under the opposite naming: this function’sdst(holding the depth) is that class’ssrc, andimage_srcis itspatch_dst: #4273.- Parameters:
image_src (
Tensor) – image tensor in the source frame with shape \((B,D,H,W)\).depth_dst (
Tensor) – depth tensor in the destination frame with shape \((B,1,H,W)\).src_trans_dst (
Tensor) – transformation matrix from destination to source with shape \((B,4,4)\).camera_matrix (
Tensor) – tensor containing the camera intrinsics with shape \((B,3,3)\).normalize_points (
bool, optional) – whether to normalize the pointcloud. This must be set toTruewhen the depth is represented as the Euclidean ray length from the camera position. Default:False
- Return type:
- Returns:
image_srcresampled onto the destination pixel grid, with shape \((B,D,H,W)\).
- kornia.geometry.depth.depth_warp(pinhole_dst, pinhole_src, depth_src, patch_dst, height, width, align_corners=True)[source]#
Warp a tensor from destination frame to reference given the depth in the reference frame.
See the Convention block on
DepthWarper.This function is that class’s functional form: it constructs a
DepthWarper, calls itscompute_projection_matrixand returns its output, which is equal to the class’s bit for bit under the defaultmodeandpadding_mode, the only ones this function offers (align_cornersis forwarded).- Return type:
Example
>>> # pinholes camera models >>> pinhole_dst = PinholeCamera(torch.randn(1, 4, 4), torch.randn(1, 4, 4), ... torch.tensor([32]), torch.tensor([32])) >>> pinhole_src = PinholeCamera(torch.randn(1, 4, 4), torch.randn(1, 4, 4), ... torch.tensor([32]), torch.tensor([32])) >>> # warp the destination frame to reference by depth >>> depth_src = torch.ones(1, 1, 32, 32) # Nx1xHxW >>> image_dst = torch.rand(1, 3, 32, 32) # NxCxHxW >>> image_src = depth_warp(pinhole_dst, pinhole_src, depth_src, image_dst, 32, 32) # NxCxHxW
- class kornia.geometry.depth.DepthWarper(pinhole_dst, height, width, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#
Warp a patch by depth.
\[ \begin{align}\begin{aligned}P_{src}^{\{dst\}} = K_{dst} * T_{src}^{\{dst\}}\\\begin{split}I_{src} = \\omega(I_{dst}, P_{src}^{\{dst\}}, D_{src})\end{split}\end{aligned}\end{align} \]- Convention:
the depth lives in the source frame and the image in the destination frame:
forward()takes(depth_src, patch_dst), samplespatch_dstat the pixels the source-frame depth projects to, and returns a \((B, C, H, W)\) tensor carryingpatch_dst’s channel count.this is a two-step API:
compute_projection_matrix()has to be called first. Until it has been,warp_grid()andforward()raiseValueErrorandcompute_subpixel_step()raisesRuntimeError.compute_projection_matrix()storesK_dst @ (E_dst @ inverse(E_src)), the matrix above, from the constructor’spinhole_dstand that method’spinhole_src(bothPinholeCamera, world-to-camera extrinsics). Both cameras use only the top-left 3x3 block of their intrinsics, embedded in homogeneous 4x4 form; the stored fourth row and column are ignored.the
gridattribute is the homogeneous integer-centre pixel grid (pixel(0, 0)is(0, 0, 1));warp_grid()returns sampling positions ingrid_sample’salign_corners=Truenormalized coordinates of the destination image.align_corners(defaultTrue),modeandpadding_modeare forwarded togrid_sample.depth_warp()is the functional form and exposesalign_cornersonly.
Warning
warp_frame_depth()performs the same warp under the opposite naming: this class’ssrc(holding the depth) is that function’sdst, andpatch_dstis itsimage_src; reading “dst” as “dst” across the two gives the inverse warp: #4273. The two agree to rounding for float32/float64 away fromz = 0, and split atz = 0, wherecam2pixelsends every pixel with a nonzero projected numerator far outside the image: #4267.- Parameters:
pinhole_dst (
PinholeCamera) – the pinhole model for the destination frame.height (
int) – the height of the image to warp.width (
int) – the width of the image to warp.mode (
str, optional) – interpolation mode to calculate output values'bilinear'|'nearest'. Default:"bilinear"padding_mode (
str, optional) – padding mode for outside grid values'zeros'|'border'|'reflection'. Default:"zeros"align_corners (
bool, optional) – interpolation flag. Default:True
- compute_projection_matrix(pinhole_src)[source]#
Compute the projection matrix from the source to destination frame.
See the Convention block on
DepthWarper.- Return type:
- compute_subpixel_step()[source]#
Compute the inverse depth step for sub pixel accurate sampling of the depth cost volume, per camera.
See the Convention block on
DepthWarper.Szeliski, Richard, and Daniel Scharstein. “Symmetric sub-pixel stereo matching.” European Conference on Computer Vision. Springer Berlin Heidelberg, 2002.
- Return type:
- forward(depth_src, patch_dst)[source]#
Warp a tensor from destination frame to reference given the depth in the reference frame.
See the Convention block on
DepthWarper.- Parameters:
- Return type:
- Returns:
the warped patch from destination frame to reference.
- Shape:
Input: \((B, 1, H, W)\) and \((B, C, H, W)\).
Output: \((B, C, H, W)\) where C = number of channels.
Example
>>> # pinholes camera models >>> pinhole_dst = PinholeCamera(torch.randn(1, 4, 4), torch.randn(1, 4, 4), ... torch.tensor([32]), torch.tensor([32])) >>> pinhole_src = PinholeCamera(torch.randn(1, 4, 4), torch.randn(1, 4, 4), ... torch.tensor([32]), torch.tensor([32])) >>> # create the depth warper, compute the projection matrix >>> warper = DepthWarper(pinhole_dst, 32, 32) >>> _ = warper.compute_projection_matrix(pinhole_src) >>> # warp the destination frame to reference by depth >>> depth_src = torch.ones(1, 1, 32, 32) # Nx1xHxW >>> image_dst = torch.rand(1, 3, 32, 32) # NxCxHxW >>> image_src = warper(depth_src, image_dst) # NxCxHxW
- warp_grid(depth_src)[source]#
Compute a grid for warping a given the depth from the reference pinhole camera.
See the Convention block on
DepthWarper.The function compute_projection_matrix has to be called beforehand in order to have precomputed the relative projection matrices encoding the relative pose and the intrinsics between the reference and a non reference camera.
- Return type: