kornia.geometry.transform#

The functions in this section warp, resize, crop, flip and register 2D images and 3D volumes. The warps take a matrix that maps source pixels to destination pixels (warp_perspective(), warp_affine() and their 3D forms), except homography_warp() and homography_warp3d(), which take a destination→source homography in normalized \([-1, 1]\) coordinates by default. The 2D image transforms rotate(), translate(), scale() and shear() take parameters instead of a matrix and affine() takes a matrix, all at the image size; resize() and rescale() change the size. align_corners defaults differ between these functions; see Conventions & Pitfalls.

Warp operators#

Warp images (B, C, H, W) or volumes (B, C, D, H, W) to the output size dsize by a source→destination pixel homography (warp_perspective(), warp_perspective3d()) or affine matrix (warp_affine(), warp_affine3d()), or by a destination→source homography in normalized coordinates (homography_warp(), homography_warp3d()). Sample an image at per-pixel source coordinates with remap(), or warp it by thin-plate-spline control points with warp_image_tps() (and points with warp_points_tps()). warp_grid() and warp_grid3d() return the warped sampling grid without sampling.

kornia.geometry.transform.warp_perspective(src, M, dsize, mode='bilinear', padding_mode='zeros', align_corners=True, fill_value=None)[source]#

Warp an image by a source→destination homography in pixel coordinates.

out = warp_perspective(src, M, dsize) takes images (B, C, H, W) and one (B, 3, 3) homography per image that maps source pixels to destination pixels, and returns the (B, C, h, w) destination images for dsize = (h, w). Pixel centres are integers, so an identity M with a smaller dsize returns the top-left dsize window of the image, not a resized image. This is the warp for the homographies that get_perspective_transform(), find_homography_dlt() and RANSAC return; for a destination→source homography in normalized \([-1, 1]\) coordinates, use homography_warp(), and for a (B, 2, 3) affine matrix, warp_affine().

Each output pixel (x, y) samples the source at the inverse of M applied to it:

\[\text{dst} (x, y) = \text{src} \left( \frac{M^{-1}_{11} x + M^{-1}_{12} y + M^{-1}_{13}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}} , \frac{M^{-1}_{21} x + M^{-1}_{22} y + M^{-1}_{23}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}} \right )\]
Convention:

See Conventions & Pitfalls for transform direction, pixel centres, normalized coordinates and align_corners sampling rules.

  • M is the source→destination pixel homography (B, 3, 3) (contrast homography_warp(), which by default consumes destination→source normalized)

  • M has the batch of src: a (1, 3, 3) M is not shared by a larger batch, as it is in warp_affine()

  • a nonzero scalar multiple of M describes the same warp; uniformly small or large nonzero entries are rescaled toward unit magnitude before the coordinate change and inversion

  • a one-pixel source axis is sampled like a longer one, so positions outside it get padding_mode. Under align_corners=True, where grid_sample alone would land them all on that pixel, 'zeros' and 'fill' read it as the first of two pixels, the second holding the padding (#6433)

  • src sets the dtype: a float32 M with a float64 src samples in float64, and a float64 M with a float32 src raises RuntimeError

  • a caller’s autocast region does not change the matrix arithmetic or the sampling grid, outside TorchScript (in the region, a src and M that mix float32 and half dtypes run in float32)

  • a zero output dimension returns an autograd-connected empty tensor; negative output dimensions raise ValueError

Parameters:
  • src (Tensor) – input image with shape (B, C, H, W).

  • M (Tensor) – transformation matrix with shape (B, 3, 3).

  • dsize (tuple[int, int]) – size of the output image (height, width).

  • 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' | 'fill'. Default: "zeros"

  • align_corners (bool, optional) – interpolation flag. Default: True

  • fill_value (Optional[Tensor], optional) – torch.Tensor of shape (C) or (1) that fills the padding area, or any shape that broadcasts to the output (B, C, h, w) without changing it, such as a per-sample (B, C, 1, 1) fill. Defaults to zeros. Default: None

Return type:

Tensor

Returns:

the warped input image (B, C, h, w), spatial sizes given by dsize.

See also

  • homography_warp(): a destination→source homography, normalized to \([-1, 1]\) by default.

  • warp_perspective3d(): the same warp for (B, C, D, H, W) volumes by (B, 4, 4) homographies.

  • warp_affine(): a (B, 2, 3) affine matrix instead, where a single (1, 2, 3) one serves a batch.

  • get_perspective_transform(): the homography that maps four source points onto four destination points.

  • remap(): sample at given per-pixel source coordinates instead of by a matrix.

  • crop_by_transform_mat(): dispatches to this warp or warp_affine() by matrix shape, casting the matrix to the image dtype and broadcasting a batch-1 matrix.

  • normalize_homography(): M in normalized \([-1, 1]\) coordinates, the conversion this warp applies before sampling.

Example

>>> img = torch.rand(1, 4, 5, 6)
>>> H = torch.eye(3)[None]
>>> out = warp_perspective(img, H, (4, 2), align_corners=True)
>>> print(out.shape)
torch.Size([1, 4, 4, 2])

Note

See a working example here.

kornia.geometry.transform.warp_perspective3d(src, M, dsize, flags='bilinear', border_mode='zeros', align_corners=False)[source]#

Warp a volume by a source→destination 4x4 homography in voxel coordinates.

out = warp_perspective3d(src, M, dsize) takes volumes (B, C, D, H, W) and one (B, 4, 4) homography per volume that maps source voxels (x, y, z) to destination voxels, and returns the (B, C, d, h, w) destination volumes for dsize = (d, h, w); flags is the interpolation mode and border_mode the padding mode. Pass align_corners=True: at the default False the sampling grid is corner-aligned while grid_sample reads half-voxel coordinates, so even an identity M resamples the volume (#4503). For images, use warp_perspective(); for a (B, 3, 4) affine matrix, warp_affine3d().

Each output voxel samples the source at:

\[\text{dst}(x, y, z) = \text{src}\left( \pi\left( M^{-1} \cdot (x, y, z, 1)^{T} \right) \right)\]

where \(\pi\) divides by the fourth (homogeneous) coordinate.

Convention:
  • M is the source→destination pixel homography (B, 4, 4), with the batch of src; an unbatched (4, 4) M is accepted for a single volume

  • align_corners: False by default (differs from the 2D warp_perspective(), whose default is True)

  • border_mode: 'zeros' by default

  • under align_corners=True, a one-voxel source axis is sampled like a longer one, so positions outside it get border_mode: 'zeros' reads it as the first of two voxels, the second holding the padding (#6433)

  • a caller’s autocast region does not change the matrix arithmetic or the sampling grid, outside TorchScript (in the region, a src and M that mix float32 and half dtypes run in float32)

  • a zero output dimension returns an autograd-connected empty tensor; negative output dimensions raise ValueError

Parameters:
  • src (Tensor) – input image with shape (B, C, D, H, W).

  • M (Tensor) – transformation matrix with shape (B, 4, 4).

  • dsize (tuple[int, int, int]) – size of the output image (depth, height, width).

  • flags (str, optional) – interpolation mode to calculate output values 'bilinear' | 'nearest'. Default: "bilinear"

  • border_mode (str, optional) – padding mode for outside grid values 'zeros' | 'border' | 'reflection'. Default: "zeros"

  • align_corners (bool, optional) – interpolation flag. Default: False

Return type:

Tensor

Returns:

the warped input image (B, C, d, h, w), spatial sizes given by dsize.

See also

kornia.geometry.transform.warp_affine(src, M, dsize, mode='bilinear', padding_mode='zeros', align_corners=True, fill_value=None)[source]#

Warp an image by a source→destination affine matrix in pixel coordinates.

out = warp_affine(src, M, dsize) takes images (B, C, H, W) and (B, 2, 3) affine matrices that map source pixels to destination pixels, and returns the (B, C, h, w) destination images for dsize = (h, w). A single (1, 2, 3) matrix serves every image of a non-empty batch. Build M with get_rotation_matrix2d(), or take the top two rows M[:, :2] of the (B, 3, 3) matrix of get_affine_matrix2d(); invert_affine_transform() gives the matrix that warps back. To keep the input size, use affine(), or pass an angle, a shift or a scale instead of a matrix to rotate(), translate() or scale(); for a (B, 3, 3) homography, use warp_perspective().

_images/warp_affine.png

Each output pixel (x, y) samples the source at:

\[\text{dst}(x, y) = \text{src} \left( M^{-1}_{11} x + M^{-1}_{12} y + M^{-1}_{13} , M^{-1}_{21} x + M^{-1}_{22} y + M^{-1}_{23} \right )\]

where \(M^{-1}\) is the inverse of the \(3 \times 3\) homogeneous extension of M.

Convention:

See Conventions & Pitfalls for transform direction, pixel centres, normalized coordinates and align_corners sampling rules.

  • M is the source→destination pixel affine matrix (B, 2, 3)

  • a one-pixel source axis is sampled like a longer one, so positions outside it get padding_mode. Under align_corners=True, where grid_sample alone would land them all on that pixel, 'zeros' and 'fill' read it as the first of two pixels, the second holding the padding (#6433)

  • src sets the dtype: a float32 M with a float64 src samples in float64, and a float64 M with a float32 src raises RuntimeError

  • a caller’s autocast region does not change the matrix arithmetic or the sampling grid, outside TorchScript (in the region, a src and M that mix float32 and half dtypes run in float32)

  • a zero output dimension returns an autograd-connected empty tensor; negative output dimensions raise ValueError

Parameters:
  • src (Tensor) – input torch.Tensor of shape (B, C, H, W).

  • M (Tensor) – affine transformation of shape (B, 2, 3), or (1, 2, 3) for the whole batch.

  • dsize (tuple[int, int]) – size of the output image (height, width).

  • 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' | 'fill'. Default: "zeros"

  • align_corners (bool, optional) – mode for grid_generation. Default: True

  • fill_value (Optional[Tensor], optional) – torch.Tensor of shape (C) or (1) that fills the padding area, or any shape that broadcasts to the output (B, C, h, w) without changing it, such as a per-sample (B, C, 1, 1) fill. Defaults to zeros. Default: None

Return type:

Tensor

Returns:

the warped torch.Tensor with shape (B, C, h, w), spatial sizes given by dsize.

See also

Example

>>> img = torch.rand(1, 4, 5, 6)
>>> A = torch.eye(2, 3)[None]
>>> out = warp_affine(img, A, (4, 2), align_corners=True)
>>> print(out.shape)
torch.Size([1, 4, 4, 2])

Note

See a working example here.

kornia.geometry.transform.warp_affine3d(src, M, dsize, flags='bilinear', padding_mode='zeros', align_corners=True)[source]#

Warp a volume by a source→destination 3x4 affine matrix in voxel coordinates.

out = warp_affine3d(src, M, dsize) takes volumes (B, C, D, H, W) and one (B, 3, 4) affine matrix per volume that maps source voxels (x, y, z) to destination voxels, and returns the (B, C, d, h, w) destination volumes for dsize = (d, h, w); flags is the interpolation mode. Keep the default align_corners=True: at False the matrix is normalized for corner-aligned voxels while grid_sample reads half-voxel ones, so a translation of t voxels moves the volume t * size / (size - 1) voxels along that axis (#4503). For a (B, 4, 4) homography, use warp_perspective3d(); for images, warp_affine(); to keep the input size, affine3d().

Warning

This API signature it is experimental and might suffer some changes in the future.

Convention:
  • align_corners: True by default

  • padding_mode: 'zeros' by default

  • M has the batch of src: one matrix is not shared by a larger batch

  • under align_corners=True, a one-voxel source axis is sampled like a longer one, so positions outside it get padding_mode: 'zeros' reads it as the first of two voxels, the second holding the padding (#6433)

  • a caller’s autocast region does not change the matrix arithmetic or the sampling grid (there, a src and M that mix float32 and half dtypes run in float32)

  • an empty batch returns shape (0, C, d, h, w) with gradients connected to both inputs even when a source spatial dimension is zero

  • a zero output dimension returns an autograd-connected empty tensor; negative output dimensions raise ValueError

  • a nonempty batch requires positive source spatial dimensions for a nonempty output

Parameters:
  • src (Tensor) – input torch.Tensor of shape (B, C, D, H, W).

  • M (Tensor) – affine transformation matrix of shape (B, 3, 4).

  • dsize (tuple[int, int, int]) – size of the output image (depth, height, width).

  • flags (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) – mode for grid_generation. Default: True

Returns:

the warped 3d torch.tensor with shape (B, C, d, h, w), spatial sizes given by dsize.

Return type:

torch.Tensor

See also

  • warp_affine(): the 2D warp of images by (B, 2, 3) matrices.

  • warp_perspective3d(): a (B, 4, 4) homography; its default align_corners=False resamples even an identity.

  • affine3d(): keeps the input size and accepts an unbatched (C, D, H, W) volume.

  • get_projective_transform(): the (B, 3, 4) matrix of a rotation and a scale about a centre.

  • crop_by_transform_mat3d(): calls this warp with the top three rows of a (B, 3, 4) or (B, 4, 4) matrix, and broadcasts a batch-1 matrix.

kornia.geometry.transform.warp_image_tps(image, kernel_centers, kernel_weights, affine_weights, align_corners=False, padding_mode='zeros')[source]#

Warp images by a thin-plate spline that maps each output pixel to the input pixel it samples.

out = warp_image_tps(image, kernel_centers, kernel_weights, affine_weights) takes images (B, C, H, W) and a spline as in warp_points_tps() (one per image, or a batch of 1 for all), applies the spline to the normalized coordinates of every output pixel and returns the (B, C, H, W) images bilinearly sampled there. The spline therefore maps output space to input space: to move control points points_src of the input onto points_dst, fit get_tps_transform(points_dst, points_src) and pass points_dst as kernel_centers, with both point sets in normalized coordinates. For one global matrix, use warp_perspective(); for random spline warps in an augmentation pipeline, RandomThinPlateSpline.

_images/warp_image_tps.png
Convention:
  • a float16/bfloat16 image with centers and weights of its dtype builds its grid and samples in float32 on every device and returns the input dtype: a half-precision grid is off by half a pixel or more at 256 px

  • image: (B, C, H, W); the weights come from get_tps_transform() called reversed, get_tps_transform(points_dst, points_src), and kernel_centers is points_dst, the first argument of that call (see its Convention block); points_src gives a wrong warp of the right shape

  • all control points live in the normalized grid_sample frame selected by align_corners: the half-pixel \(x_{norm} = (2x+1)/W - 1\) at the default False, the corner-aligned \(x_{norm} = 2x/(W-1) - 1\) at True; values outside \([-1, 1]\) sample the padding. Pixel-space control points silently give a wrong warp of the right shape

  • align_corners: False by default (the matrix warps default to True)

  • for float32 points, a caller’s autocast region does not change the sampling positions, outside TorchScript (in the region, a mix of float32, float16 and bfloat16 points meets in float32, except that CPU and MPS autocast raise on a half image of a dtype other than the region’s)

Parameters:
  • image (Tensor) – input image torch.Tensor (B, C, H, W).

  • kernel_centers (Tensor) – kernel center points (B, K, 2).

  • kernel_weights (Tensor) – torch.Tensor of kernel weights (B, K, 2).

  • affine_weights (Tensor) – torch.Tensor of affine weights (B, 3, 2).

  • align_corners (bool, optional) – interpolation flag used by grid_sample. Default: False

  • padding_mode (str, optional) – padding flag used by grid_sample. Default: "zeros"

Return type:

Tensor

Returns:

warped image torch.Tensor (B, C, H, W).

See also

Example

>>> points_src = torch.rand(1, 5, 2)
>>> points_dst = torch.rand(1, 5, 2)
>>> image = torch.rand(1, 3, 32, 32)
>>> # note that we are getting the reverse transform: dst -> src
>>> kernel_weights, affine_weights = get_tps_transform(points_dst, points_src)
>>> warped_image = warp_image_tps(image, points_dst, kernel_weights, affine_weights)
kornia.geometry.transform.warp_points_tps(points_src, kernel_centers, kernel_weights, affine_weights)[source]#

Move 2D points by a thin-plate spline given as kernel centres and weights.

warped = warp_points_tps(points_src, kernel_centers, kernel_weights, affine_weights) takes (B, N, 2) points and the (B, K, 2) kernel centres, (B, K, 2) kernel weights and (B, 3, 2) affine weights of a spline, and returns the (B, N, 2) warped points in the same frame, unclamped. With the weights of get_tps_transform(points_src, points_dst), pass points_src as kernel_centers: that function centres the kernels there. In the weight tensors, [..., 0] holds the weights of the x transform and [..., 1] those of the y transform. To warp an image, use warp_image_tps().

Convention:
  • points: (B, N, 2) (or (B, K, 2) for kernel centers) in (x, y) order; no normalization is applied, and the output is in the same frame, not clamped

  • kernel_centers must be the first argument passed to get_tps_transform() (see its Convention block). Nothing checks this, and any other tensor of that shape, the second argument included, gives a wrong warp of the right shape. The right centres give kernel_weights.mT @ kernel_centers of zero up to round-off. A caller can assert that to catch the second argument, but it does not identify the centres, as a translated set passes it too

  • for float32 points, a caller’s autocast region does not change the result, outside TorchScript (in the region, a mix of float32, float16 and bfloat16 points meets in float32)

Parameters:
  • points_src (Tensor) – torch.Tensor of source points (B, N, 2).

  • kernel_centers (Tensor) – torch.Tensor of kernel center points (B, K, 2).

  • kernel_weights (Tensor) – torch.Tensor of kernel weights (B, K, 2).

  • affine_weights (Tensor) – torch.Tensor of affine weights (B, 3, 2).

Return type:

Tensor

Returns:

The (B, N, 2) torch.Tensor of warped source points, from applying the TPS transform.

See also

Example

>>> points_src = torch.rand(1, 5, 2)
>>> points_dst = torch.rand(1, 5, 2)
>>> kernel_weights, affine_weights = get_tps_transform(points_src, points_dst)
>>> warped = warp_points_tps(points_src, points_src, kernel_weights, affine_weights)
>>> warped_correct = torch.allclose(warped, points_dst)
kornia.geometry.transform.warp_grid(grid, src_homo_dst)[source]#

Warp a grid of 2D points by homographies, returning the coordinates without sampling an image.

warped = warp_grid(grid, src_homo_dst) applies the homographies src_homo_dst to every (x, y) point of grid and returns the (N, H, W, 2) points after the homogeneous division, in the dtype of src_homo_dst. It does not normalize: the points stay in the coordinates that grid and the homography share, so a normalized grid from create_meshgrid() and a normalized homography give positions that torch.nn.functional.grid_sample() reads directly. To warp an image, use homography_warp(), which builds such a grid, warps it with this function and samples the image.

Convention:
  • grid coordinates: (x, y) (last dim), shape (1, H, W, 2) or (N, H, W, 2)

  • src_homo_dst is the destination→source homography (1, 3, 3), (N, 3, 3) or (N, 1, 3, 3)

  • only the (1, H, W, 2) grid broadcasts over homography batches; a batched grid requires a matching batch of N homographies

  • src_homo_dst is divided by a detached scale toward unit magnitude before the homogeneous division, as in warp_perspective(), so a nonzero scalar multiple of it returns the same grid, except at grid points whose homogeneous coordinate is within 1e-8 of zero after that rescaling: those are left undivided, as convert_points_from_homogeneous() does for points at infinity

  • a caller’s autocast region does not change the grid, outside TorchScript

Parameters:
  • grid (Tensor) – Unwrapped grid of the shape (1, H, W, 2), or (N, H, W, 2) with a matching batch of N homographies.

  • src_homo_dst (Tensor) – Homography or homographies (stacked) to transform all points in the grid. Shape of the homography has to be (1, 3, 3), (N, 3, 3) or (N, 1, 3, 3).

Return type:

Tensor

Returns:

the transformed grid of shape (N, H, W, 2).

Raises:

ShapeError – If grid is not (B, H, W, 2), or src_homo_dst is not (B, 3, 3) or (B, 1, 3, 3). A single (3, 3) homography needs a leading batch dimension.

See also

kornia.geometry.transform.warp_grid3d(grid, src_homo_dst)[source]#

Warp a grid of 3D points by 4x4 homographies, returning the coordinates without sampling a volume.

warped = warp_grid3d(grid, src_homo_dst) applies the homographies src_homo_dst to every (x, y, z) point of grid and returns the (N, D, H, W, 3) points after the homogeneous division, in the dtype of src_homo_dst. It does not normalize or reorder: the last axis must already be (x, y, z), the order the homography and torch.nn.functional.grid_sample() read, whereas create_meshgrid3d() returns (d, x, y). To warp a volume, use homography_warp3d(), which builds and reorders the grid, warps it with this function and samples the volume.

Convention:
  • grid coordinates: (x, y, z) (last dim), shape (1, D, H, W, 3) or (N, D, H, W, 3)

  • src_homo_dst is the destination→source homography (1, 4, 4), (N, 4, 4) or (N, 1, 4, 4)

  • only the (1, D, H, W, 3) grid broadcasts over homography batches; a batched grid requires a matching batch of N homographies

  • src_homo_dst is divided by a detached scale toward unit magnitude before the homogeneous division, as in warp_perspective(), so a nonzero scalar multiple of it returns the same grid, except at grid points whose homogeneous coordinate is within 1e-8 of zero after that rescaling: those are left undivided, as convert_points_from_homogeneous() does for points at infinity

  • a caller’s autocast region does not change the grid, outside TorchScript

Parameters:
  • grid (Tensor) – Unwrapped grid of the shape (1, D, H, W, 3), or (N, D, H, W, 3) with a matching batch of N homographies.

  • src_homo_dst (Tensor) – Homography or homographies (stacked) to transform all points in the grid. Shape of the homography has to be (1, 4, 4), (N, 4, 4) or (N, 1, 4, 4).

Return type:

Tensor

Returns:

the transformed grid of shape (N, D, H, W, 3).

Raises:

ShapeError – If grid is not (B, D, H, W, 3), or src_homo_dst is not (B, 4, 4) or (B, 1, 4, 4). A single (4, 4) homography needs a leading batch dimension.

See also

  • warp_grid(): the same for a 2D (x, y) grid and (N, 3, 3) homographies.

  • homography_warp3d(): builds and reorders the grid, warps it with this function and samples the volume.

  • create_meshgrid3d(): a grid in (d, x, y) order, to reorder before passing it in.

kornia.geometry.transform.remap(image, map_x, map_y, mode='bilinear', padding_mode='zeros', align_corners=None, normalized_coordinates=False)[source]#

Sample an image at per-pixel source coordinates given as an x map and a y map.

out = remap(image, map_x, map_y) takes images (B, C, H, W) and two (B, h, w) maps that hold, for every output pixel, the source column x and row y to sample, and returns (B, C, h, w). The maps are absolute pixel coordinates, not displacements, so the identity maps are the two channels of create_meshgrid() with normalized_coordinates=False; with normalized_coordinates=True they are the \([-1, 1]\) coordinates of torch.nn.functional.grid_sample(). Maps of batch 1 serve every image. With pixel maps, pass align_corners=True: the default resamples even an identity map. For a warp given by a matrix, use warp_affine() or warp_perspective().

_images/remap.png
\[\text{dst}(x, y) = \text{src}(map_x(x, y), map_y(x, y))\]
Convention:
  • align_corners: None by default, resolved to False internally

  • pixel maps are normalized with the align_corners=True convention whatever flag reaches grid_sample, so at False/None even an identity map resamples the image; pass align_corners=True (#4504)

  • the output spatial size comes from the maps; a zero map axis returns an autograd-connected empty output, including when the matching source axis is empty

Parameters:
  • image (Tensor) – the torch.Tensor to remap with shape (B, C, H, W). Where C is the number of channels.

  • map_x (Tensor) – the source x coordinate (column) to sample for each output pixel, with shape (B, h, w) or (1, h, w); in pixels unless normalized_coordinates=True.

  • map_y (Tensor) – the source y coordinate (row) to sample for each output pixel, with the shape of map_x.

  • 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 (Optional[bool], optional) – mode for grid_generation. Default: None

  • normalized_coordinates (bool, optional) – whether the input coordinates are normalized in the range of [-1, 1]. Default: False

Return type:

Tensor

Returns:

the sampled images (B, C, h, w), with the spatial size of the maps.

See also

Example

>>> import torch
>>> from kornia.geometry import create_meshgrid
>>> grid = create_meshgrid(2, 2, False)  # 1x2x2x2
>>> grid += 1  # apply offset in both directions
>>> input = torch.ones(1, 1, 2, 2)
>>> remap(input, grid[..., 0], grid[..., 1], align_corners=True)   # 1x1x2x2
tensor([[[[1., 0.],
          [0., 0.]]]])
kornia.geometry.transform.homography_warp(patch_src, src_homo_dst, dsize, mode='bilinear', padding_mode='zeros', align_corners=False, normalized_coordinates=True, normalized_homography=True)[source]#

Warp an image by a destination→source homography in normalized [-1, 1] coordinates.

out = homography_warp(patch_src, src_homo_dst, dsize) takes images (N, C, H, W) and one (N, 3, 3) homography per image that maps destination points to source points in normalized \([-1, 1]\) coordinates, and returns the (N, C, h, w) destination images for dsize = (h, w). In normalized coordinates an identity maps the whole source onto the whole output, so a different dsize resizes the image. For a source→destination homography in pixel coordinates, as get_perspective_transform(), find_homography_dlt() and RANSAC return it, use warp_perspective(). Passed here unchanged, such a homography is read as a normalized destination→source one, which typically samples outside the source, so the output is mostly or entirely zeros (with the default padding_mode="zeros").

normalized_coordinates=False reads the same destination→source homography in pixels, and normalized_homography=False instead hands a pixel source→destination homography to warp_perspective() with this function’s align_corners=False default, which for a pixel homography samples the same positions as align_corners=True (see align_corners below), up to which pixel mode="nearest" takes for a sample exactly halfway between two pixels.

Convention:

See Conventions & Pitfalls for homography direction, normalized coordinates and align_corners sampling rules.

  • src_homo_dst is the destination→source homography (N, 3, 3) when normalized_homography=True (default), in normalized \([-1, 1]\) coordinates by default (normalized_coordinates=True). With normalized_coordinates=False it is in pixel coordinates, pixel centres at integers: it maps the pixel (x, y) of the dsize output to the source pixel it samples, so an identity returns the top-left dsize window of the input

  • with normalized_homography=False it is consumed as the source→destination pixel homography, exactly like warp_perspective(), and normalized_coordinates is ignored

  • src_homo_dst has the batch of patch_src: a (1, 3, 3) homography is not shared by a larger batch

  • a float16/bfloat16 patch with a homography of its dtype builds its grid and samples in float32 on every device and returns the input dtype

  • with normalized_coordinates=False the pixel grid is warped and normalized in at least float32, also under a half default dtype and in a caller’s autocast region, and then cast to the homography’s dtype

  • with normalized_coordinates=True a caller’s autocast region does not change the sampling grid, outside TorchScript (in the region, a patch and homography that mix float32 and half dtypes run in float32)

  • align_corners: False by default (differs from warp_perspective()). A pixel homography samples the same positions under both settings, which then differ only in padding_mode="reflection" and, with mode="nearest", in which pixel a sample exactly halfway between two pixels takes. A normalized homography reads the whole \([-1, 1]\) range of a one-pixel source axis as that pixel under align_corners=True

  • negative output dimensions raise ValueError

Parameters:
  • patch_src (Tensor) – The image or torch.Tensor to warp. Should be from source of shape (N, C, H, W).

  • src_homo_dst (Tensor) – The homography or torch.stack of homographies of shape (N, 3, 3) — destination to source when normalized_homography=True (default), source to destination (pixel) when normalized_homography=False.

  • dsize (tuple[int, int]) – output size (h, w).

  • 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: False

  • normalized_coordinates (bool, optional) – whether src_homo_dst is in normalized \([-1, 1]\) coordinates (True) or in pixel coordinates (False). Ignored when normalized_homography=False. Default: True

  • normalized_homography (bool, optional) – whether src_homo_dst is a destination→source homography in the coordinates normalized_coordinates selects (True, default) or a pixel source→destination homography (False). Default: True

Return type:

Tensor

Returns:

the warped images (N, C, h, w), sampled at the source locations of the destination pixels.

See also

  • warp_perspective(): takes the source→destination homography in pixel coordinates.

  • HomographyWarper: the module form, which can precompute the sampling grid for repeated warps.

  • homography_warp3d(): the same warp for (N, C, D, H, W) volumes by (N, 4, 4) homographies.

  • warp_grid(): the warped sampling grid alone, without sampling the image.

  • normalize_homography(): convert a pixel source→destination homography to normalized coordinates, with this function’s align_corners (it defaults to True there); invert the result for this function.

Example

>>> input = torch.rand(1, 3, 32, 32)
>>> homography = torch.eye(3).view(1, 3, 3)
>>> output = homography_warp(input, homography, (32, 32))

Example

>>> img = torch.rand(1, 4, 5, 6)
>>> H = torch.eye(3)[None]
>>> out = homography_warp(img, H, (4, 2), align_corners=True, normalized_homography=False)
>>> print(out.shape)
torch.Size([1, 4, 4, 2])
kornia.geometry.transform.homography_warp3d(patch_src, src_homo_dst, dsize, mode='bilinear', padding_mode='zeros', align_corners=False, normalized_coordinates=True)[source]#

Warp a volume by a destination→source 3D homography in normalized coordinates.

out = homography_warp3d(patch_src, src_homo_dst, dsize) takes volumes (N, C, D, H, W) and one (N, 4, 4) homography per volume that maps destination points (x, y, z) to source points in normalized \([-1, 1]\) coordinates, and returns the (N, C, d, h, w) destination volumes for dsize = (d, h, w). In normalized coordinates, pass align_corners=True: the normalized grid is always corner-aligned, so at the default False even an identity resamples the volume (#4503). For a source→destination homography in voxel coordinates, use warp_perspective3d() with align_corners=True, which at its default False resamples even an identity for the same reason, or pass the inverse of that homography here with normalized_coordinates=False. This function has no normalized_homography switch.

Convention:
  • input: (N, C, D, H, W); dsize is the output size (d, h, w)

  • src_homo_dst is the destination→source homography (N, 4, 4), in normalized \([-1, 1]\) coordinates by default (normalized_coordinates=True), and acts on (x, y, z, 1) column vectors: x indexes W, y indexes H, z indexes D. That is the order torch.nn.functional.grid_sample() reads a 5-D grid in, and the order warp_grid3d() takes. kornia’s own 3-D grids and pixel coordinates are (d, x, y) (see create_meshgrid3d()), so the sampling grid is reordered here before the homography is applied; nothing else in the module changes its order

  • with normalized_coordinates=False src_homo_dst is in voxel coordinates, voxel centres at integers, in the same (x, y, z) order: it maps the voxel (x, y, z) of the dsize output to the source voxel it samples, so an identity returns the dsize window of the input that starts at voxel (0, 0, 0). The warped voxel grid is normalized with the source size under align_corners before grid_sample

  • with normalized_coordinates=False the voxel grid is warped and normalized in at least float32, also under a half default dtype and in a caller’s autocast region, and then cast to the homography’s dtype

  • with normalized_coordinates=True a caller’s autocast region does not change the sampling grid, outside TorchScript (in the region, a patch and homography that mix float32 and half dtypes run in float32)

  • align_corners: False by default. With normalized_coordinates=False, a voxel homography samples the same positions under both settings, which then differ only in padding_mode="reflection" and, with mode="nearest", in which voxel a sample exactly halfway between two voxels takes

  • padding_mode: 'zeros' by default

  • negative output dimensions raise ValueError

Parameters:
  • patch_src (Tensor) – The image or torch.Tensor to warp. Should be from source of shape (N, C, D, H, W).

  • src_homo_dst (Tensor) – The homography or torch.stack of homographies from destination to source of shape (N, 4, 4).

  • dsize (tuple[int, int, int]) – output size (d, h, w).

  • 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: False

  • normalized_coordinates (bool, optional) – whether src_homo_dst is in normalized \([-1, 1]\) coordinates (True) or in voxel coordinates (False). Default: True

Return type:

Tensor

Returns:

the warped volumes (N, C, d, h, w), sampled at the source locations of the destination voxels.

See also

Example

>>> input = torch.rand(1, 3, 8, 32, 32)
>>> homography = torch.eye(4).view(1, 4, 4)
>>> output = homography_warp3d(input, homography, (8, 32, 32))

Image 2D transforms#

Rotate, shift, zoom or shear an image by parameters (rotate(), translate(), scale(), shear()), or warp it by an affine matrix (affine()), at the input size; change the size with resize(), rescale() or resize_to_be_divisible(). Mirror or turn it by reversing axes, without interpolation (hflip(), vflip(), rot180()); deform it by a smoothed displacement field (elastic_transform2d()); blur and resize it by one pyramid level (pyrdown(), pyrup()), or build a Gaussian or Laplacian pyramid (build_pyramid(), build_laplacian_pyramid(), with the integer helpers is_powerof_two() and find_next_powerof_two()).

kornia.geometry.transform.affine(tensor, matrix, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Warp an image by a source→destination affine matrix, keeping its size.

out = affine(tensor, matrix) warps (C, H, W) or (B, C, H, W) images by (B, 2, 3) source→destination pixel affine matrices and returns them at their own size: warp_affine() with dsize=(H, W), plus an unbatched image and broadcasting. One matrix, (1, 2, 3) or (2, 3), serves every image of a batch, and one image, unbatched or of batch 1, is warped by every matrix, so it returns (B, C, H, W) for B > 1 matrices. For another output size, use warp_affine(); to build the matrix from an angle, a shift, a scale and a shear, use Affine.

_images/warp_affine.png
Convention:

See Conventions & Pitfalls for the align_corners defaults and sampling rules.

  • matrix is the source→destination pixel affine matrix (B, 2, 3); an unbatched (2, 3) matrix is read as (1, 2, 3).

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, H, W) or (B, C, H, W).

  • matrix (Tensor) – The 2x3 affine transformation matrices, with shape (B, 2, 3), or one (2, 3) matrix.

  • 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

Return type:

Tensor

Returns:

The warped image with the same shape as the input, except that one image warped by B > 1 matrices returns (B, C, H, W).

See also

  • warp_affine(): the same warp with an explicit output size, for batched images.

  • affine3d(): the same for volumes, by (B, 3, 4) matrices.

  • Affine: a module built from an angle, a translation, a scale and a shear instead of a matrix.

  • rotate(): rotate about the centre without building the matrix.

Example

>>> img = torch.rand(1, 2, 3, 5)
>>> aff = torch.eye(2, 3)[None]
>>> out = affine(img, aff)
>>> print(out.shape)
torch.Size([1, 2, 3, 5])
kornia.geometry.transform.rotate(tensor, angle, center=None, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Rotate an image counter-clockwise by an angle in degrees about its centre or a given point.

out = rotate(tensor, angle) rotates (C, H, W) or (B, C, H, W) images by angle degrees, (B,) or one value for all, counter-clockwise as displayed, about center ((B, 2) (x, y) pixels, by default the image centre ((W - 1) / 2, (H - 1) / 2)), and returns them at their size; the uncovered corners are padded by padding_mode. For a stored angle, use Rotate; for volumes, rotate3d(); for the matrix, to compose or reuse it, get_rotation_matrix2d().

_images/rotate.png
Convention:
  • center is (x, y) in pixels, origin at top-left; defaults to the tensor center

  • positive angle rotates counter-clockwise as displayed (y-down image axes)

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, H, W) or (B, C, H, W).

  • angle (Tensor) – The angle through which to rotate. The tensor must have a shape of (B), where B is batch size.

  • center (Optional[Tensor], optional) – The center through which to rotate. The tensor must have a shape of (B, 2), where B is batch size and last dimension contains cx and cy. Default: None

  • 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

Return type:

Tensor

Returns:

The rotated tensor with shape as input.

See also

  • Rotate: the module form, with the angle stored.

  • rotate3d(): rotate volumes by an axis-angle vector; a positive z angle turns clockwise on screen (3D rotations are right-handed by design).

  • get_rotation_matrix2d(): the (B, 2, 3) matrix of this rotation, with a scale.

  • rot180(): a half turn by flipping both axes, without interpolation.

Note

See a working example here.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> angle = torch.tensor([90.])
>>> out = rotate(img, angle)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
kornia.geometry.transform.translate(tensor, translation, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Shift an image by a translation in pixels.

out = translate(tensor, translation) shifts (C, H, W) or (B, C, H, W) images by translation (B, 2), (dx, dy) in pixels, a positive dx to the right and a positive dy down, and returns them at their size; a fractional shift interpolates, and the uncovered border is padded by padding_mode. One translation, (1, 2) or (2,), serves every image of a batch, and one image, unbatched or of batch 1, is shifted by every translation. For a stored translation, use Translate; for the matrix, get_translation_matrix2d().

_images/translate.png
Convention:
  • translation is (dx, dy) in pixels

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, H, W) or (B, C, H, W).

  • translation (Tensor) – tensor containing the amount of pixels to translate in the x and y direction. The tensor must have a shape of (B, 2), where B is batch size, last dimension contains dx dy, or (2,) for one translation.

  • 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

Return type:

Tensor

Returns:

The translated tensor with shape as input, except that one image shifted by B > 1 translations returns (B, C, H, W).

See also

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> translation = torch.tensor([[1., 0.]])
>>> out = translate(img, translation)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
kornia.geometry.transform.scale(tensor, scale_factor, center=None, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Zoom an image about its centre by a scale factor, keeping its size.

out = scale(tensor, scale_factor) scales the content of (C, H, W) or (B, C, H, W) images by scale_factor, (B,) for both axes or (B, 2) as (sx, sy), about center ((B, 2) (x, y) pixels, by default the image centre), and returns them at their size: a factor above 1 zooms in and crops, one below 1 shrinks the content and pads the border. To change the image size instead, use rescale() or resize(); for a stored factor, Scale.

_images/scale.png
Convention:
  • center is (x, y) in pixels, origin at top-left; defaults to the tensor center

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, H, W) or (B, C, H, W).

  • scale_factor (Tensor) – The scale factor apply. The tensor must have a shape of (B) or (B, 2), where B is batch size. If (B), isotropic scaling will perform. If (B, 2), x-y-direction specific scaling will perform.

  • center (Optional[Tensor], optional) – The center through which to scale. The tensor must have a shape of (B, 2), where B is batch size and last dimension contains cx and cy. Default: None

  • 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

Return type:

Tensor

Returns:

The scaled tensor with the same shape as the input.

See also

  • Scale: the module form, with the factor stored.

  • rescale(): change the image size by a factor, given height first.

  • get_rotation_matrix2d(): the matrix of this scaling, with a zero angle.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> scale_factor = torch.tensor([[2., 2.]])
>>> out = scale(img, scale_factor)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
kornia.geometry.transform.shear(tensor, shear, mode='bilinear', padding_mode='zeros', align_corners=False)[source]#

Shear an image by raw shear factors about pixel (0, 0).

out = shear(tensor, shear) shears (C, H, W) or (B, C, H, W) images by shear (B, 2), the raw factors (shx, shy) described below, and returns them at their size. One pair of factors, (1, 2) or (2,), serves every image of a batch, and one image, unbatched or of batch 1, is sheared by every pair. For shear angles in radians, use Affine, about the image centre by default, or get_shear_matrix2d(), about a centre you pass; both shear by the negative tangent, so values below pi / 2 in magnitude shear the other way there. For stored factors, use Shear.

_images/shear.png
Convention:
  • shear is a pair of raw factors (shx, shy) about pixel (0, 0): x_out = x + shx * y, y_out = y + shy * x (x right, y down).

  • Known defect: Affine reads its shear as angles in radians about the image centre and shears by their negative tangent, so the same tensor shears the other way there while its values stay below pi / 2 in magnitude (#5661).

  • align_corners: False by default (differs from the other 2D affine warps and from Shear, which default to True)

Parameters:
  • tensor (Tensor) – The image tensor to be skewed with shape of (C, H, W) or (B, C, H, W).

  • shear (Tensor) – tensor containing raw shear factors in the x and y direction about pixel (0, 0). The tensor must have a shape of (B, 2), where B is batch size, last dimension contains shx shy, or (2,) for one pair.

  • 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: False

Return type:

Tensor

Returns:

The skewed tensor with shape same as the input, except that one image sheared by B > 1 pairs of factors returns (B, C, H, W).

See also

  • Shear: the module form, which defaults to align_corners=True.

  • get_shear_matrix2d(): a shear given as angles in radians about a centre, the reading of Affine.

  • affine(): warp by any affine matrix at the input size.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> shear_factor = torch.tensor([[0.5, 0.0]])
>>> out = shear(img, shear_factor)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
kornia.geometry.transform.hflip(input)[source]#

Mirror images left to right by reversing the width axis.

out = hflip(input) reverses the last axis of (*, W) tensors, the width of (*, H, W) images, and returns the same shape. To flip top to bottom, use vflip(); for a half turn, rot180(); for random flips in an augmentation pipeline, RandomHorizontalFlip.

_images/hflip.png
Convention:
  • flips the last dimension (dim -1); accepts any rank \(\geq 1\) (rank 0 is outside the contract)

Parameters:

input (Tensor) – input torch.Tensor.

Return type:

Tensor

Returns:

The horizontally flipped image torch.Tensor, with the shape of the input.

See also

kornia.geometry.transform.vflip(input)[source]#

Flip images top to bottom by reversing the height axis.

out = vflip(input) reverses the second-to-last axis of (*, H, W) tensors and returns the same shape. To mirror left to right, use hflip(); for a half turn, rot180(); for random flips in an augmentation pipeline, RandomVerticalFlip.

_images/vflip.png
Convention:
  • flips along the height axis (the second-to-last dimension)

  • requires rank ≥ 2 (operates on dim -2): unbatched (H, W)/ (C, H, W) or batched (*, C, H, W) all work

Parameters:

input (Tensor) – input torch.Tensor.

Return type:

Tensor

Returns:

The vertically flipped image torch.Tensor, with the shape of the input.

See also

kornia.geometry.transform.rot180(input)[source]#

Turn images by 180 degrees by reversing the height and width axes.

out = rot180(input) reverses the last two axes of (*, H, W) tensors and returns the same shape: the image turned by a half turn, exactly, without the interpolation of rotate(). For any other angle, or a turn about another centre, use rotate(); for the module form, Rot180.

_images/rot180.png
Convention:
  • flips both the height and width axes (equivalent to vflip() followed by hflip())

  • requires rank ≥ 2: unbatched (H, W)/(C, H, W) or batched (*, C, H, W) all work

Parameters:

input (Tensor) – input torch.Tensor.

Return type:

Tensor

Returns:

The rotated image torch.Tensor, with the shape of the input.

See also

  • Rot180: the module form.

  • rotate(): rotates by any angle about the centre or a given point, with interpolation; at 180 degrees about the default centre it matches rot180 up to float rounding.

  • hflip(): reverses the width axis only.

  • vflip(): reverses the height axis only.

kornia.geometry.transform.resize(input, size, interpolation='bilinear', align_corners=None, side='short', antialias=False)[source]#

Resize an image to a given size, or one side to a given length keeping the aspect ratio.

out = resize(input, size) resamples the last two dimensions of (*, H, W) tensors to size = (h, w) with torch.nn.functional.interpolate() and returns (*, h, w). An int size sets the length of one side and keeps the aspect ratio, truncating the other side to an integer: the shorter side by default, or the longer side, the height or the width with side='long', 'vert' or 'horz'. antialias=True blurs with a Gaussian before downscaling. To scale by a factor, use rescale(); to zoom the content and keep the size, scale().

_images/resize.png
Convention:

See Conventions & Pitfalls for sampling and align_corners conventions. When resizing camera images, see camera and world conventions for matching intrinsics scaling.

  • input: (*, H, W); size is (h, w)

  • align_corners: None by default (follows torch.nn.functional.interpolate; note warp_perspective()/rotate() default True)

  • side resizing preserves aspect ratio using the named side

Parameters:
  • input (Tensor) – The image tensor to resize, with shape (*, H, W); * means any number of dimensions.

  • size (Union[int, Tuple[int, int]]) – Desired output size. If size is a sequence like (h, w), output size will be matched to this. If size is an int, the side that side names will be matched to this number; with the default side='short', if height > width, the image will be rescaled to (size * height / width, size)

  • interpolation (str, optional) – algorithm used for upsampling: 'nearest' | 'nearest-exact' | 'bilinear' | 'bicubic' | 'area'. Default: "bilinear"

  • align_corners (Optional[bool], optional) – interpolation flag. Default: None

  • side (str, optional) – Corresponding side if size is an integer. Can be one of 'short', 'long', 'vert', or 'horz'. Default: "short"

  • antialias (bool, optional) – if True, then image will be filtered with Gaussian before downscaling. No effect for upscaling. Default: False

Return type:

Tensor

Returns:

The resized tensor with the shape as the specified size.

See also

  • Resize: the module form, with the size stored.

  • rescale(): the output size as a factor of the input size.

  • resize_to_be_divisible(): the nearest size whose sides are multiples of a factor.

  • scale(): zoom the content about the centre and keep the size.

  • crop_and_resize(): resamples a box of each image, not the whole image, to a fixed size.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> out = resize(img, (6, 8))
>>> print(out.shape)
torch.Size([1, 3, 6, 8])
kornia.geometry.transform.resize_to_be_divisible(input, divisible_factor, interpolation='bilinear', align_corners=None, side=None, antialias=False)[source]#

Resize an image so that its height and width are multiples of a factor.

out = resize_to_be_divisible(input, divisible_factor) resizes (*, H, W) tensors with resize() to the nearest multiples of divisible_factor, at least divisible_factor for a positive side, and returns (*, h, w); an empty side stays empty. A side halfway between two multiples rounds as Python’s round() does, to an even quotient, so with a factor of 4 both 6 and 10 become 8. side is deprecated and has no effect. For a given size, use resize().

Convention:
  • see the convention block of resize()

  • rounds height/width to the nearest multiple of divisible_factor before delegating to resize(); a positive side becomes at least divisible_factor, and an empty side stays empty

Parameters:
  • input (torch.Tensor) – Input tensor to be resized.

  • divisible_factor (int) – The factor to which the image should be divisible.

  • interpolation (str, optional) – Interpolation flag. Defaults to “bilinear”. Default: "bilinear"

  • align_corners (Optional[bool], optional) – whether to align the corners of the input and output. Defaults to None. Default: None

  • side (str, optional) – Deprecated and ignored. Both sides are rounded independently to a multiple of divisible_factor. In eager mode, any explicit non-None value emits a DeprecationWarning. Defaults to None. This argument will be removed in a future release. Default: None

  • antialias (bool, optional) – If True, then image will be filtered with Gaussian before downscaling. Defaults to False. Default: False

Returns:

The resized tensor.

Return type:

torch.Tensor

Raises:
  • TypeError – If input is not a tensor.

  • ValueError – If input has fewer than two dimensions, or divisible_factor is not a positive integer.

See also

kornia.geometry.transform.rescale(input, factor, interpolation='bilinear', align_corners=None, antialias=False)[source]#

Resize an image by a scale factor per side, given height first.

out = rescale(input, factor) resizes (*, H, W) tensors with resize() to (int(H * factor_h), int(W * factor_w)), truncating, and returns (*, h, w). factor is one float for both sides or a pair (factor_h, factor_w), height first, unlike the (sx, sy) of scale(); a single int raises TypeError. To set the output size directly, use resize(); for a stored factor, Rescale.

_images/rescale.png
Convention:
  • factor is (factor_h, factor_w) when a pair — height first (contrast scale(), whose scale_factor is x-first)

  • delegates to resize() after converting factor to an output size

  • ONNX: an export with a dynamic height or width keeps it dynamic for the 'nearest', 'bilinear' and 'bicubic' modes without antialias; the other modes keep the output size of the traced input. The exported graph computes the size in float32, which can be one pixel off eager when factor is not a power of two (0.7 at a side of 90 gives 63, eager 62)

Parameters:
  • input (Tensor) – The image tensor to be scale with shape of (*, H, W).

  • factor (Union[float, Tuple[float, float]]) – Desired scaling factor as (factor_h, factor_w) — height first. If a single float, the value is used for both height and width (an int raises TypeError).

  • interpolation (str, optional) – algorithm used for upsampling: 'nearest' | 'nearest-exact' | 'bilinear' | 'bicubic' | 'area'. Default: "bilinear"

  • align_corners (Optional[bool], optional) – interpolation flag. Default: None

  • antialias (bool, optional) – if True, then image will be filtered with Gaussian before downscaling. No effect for upscaling. Default: False

Return type:

Tensor

Returns:

The rescaled tensor with the shape as the specified size.

See also

  • Rescale: the module form, which defaults to align_corners=True.

  • resize(): the output size instead of a factor.

  • scale(): zoom the content by a factor and keep the size.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> out = rescale(img, (2, 3))
>>> print(out.shape)
torch.Size([1, 3, 8, 12])
kornia.geometry.transform.elastic_transform2d(image, noise, kernel_size=(63, 63), sigma=(32.0, 32.0), alpha=(1.0, 1.0), align_corners=False, mode='bilinear', padding_mode='zeros')[source]#

Deform images by a displacement field smoothed from noise, as described in [SSP03].

out = elastic_transform2d(image, noise) takes images (B, C, H, W) and a noise field (B, 2, H, W), smooths each channel of the noise with a Gaussian of kernel_size and sigma, scales it by alpha and returns the (B, C, H, W) images sampled at the displaced pixels. The displacements are in the normalized \([-1, 1]\) coordinates of grid_sample: an x displacement of 1 moves a sample by \(W / 2\) pixels at the default align_corners=False and by \((W - 1) / 2\) at True, and a y displacement likewise by the height. One Gaussian and one alpha serve the whole batch. For random fields in an augmentation pipeline, use RandomElasticTransform; for a smooth warp set by control points, warp_image_tps().

_images/elastic_transform2d.png
Convention:
  • a float16/bfloat16 image with a noise field of its dtype builds its grid and samples in float32 on every device and returns the input dtype: a half-precision grid is off by half a pixel or more at 256 px

  • image: (B, C, H, W); noise: (B, 2, H, W) with channel 0 the x- and channel 1 the y-displacement of the sampling grid (positive x-noise shifts image content left)

  • displacements are smoothed with a Gaussian (kernel_size, sigma) and scaled by alpha; kernel_size and sigma are (y, x) pairs, but alpha is (x, y)

  • align_corners: False by default (the matrix warps default to True); zero noise is an identity under either setting

  • coordinates displaced outside the image are filled by padding_mode as in grid_sample: zeros, the edge value, or the reflected image

  • a caller’s autocast region does not change the displacement field or the grid, and the result stays in the dtype of image. Under torch.compile on MPS it still changes the field: a convolution under the guard raises there, so the smoothing runs in the region’s dtype

Parameters:
  • image (Tensor) – Input image to be transformed with shape (B, C, H, W).

  • noise (Tensor) – Noise image used to spatially transform the input image. Same resolution as the input image with shape (B, 2, H, W). The coordinates order it is expected to be in x-y.

  • kernel_size (Tuple[int, int], optional) – the size of the Gaussian kernel, in the y and x directions, respectively; both odd. Default: (63, 63)

  • sigma (Union[Tuple[float, float], Tensor], optional) – The standard deviation of the Gaussian in the y and x directions, respectively, as a pair or a (2,) tensor. Larger sigma results in smaller pixel displacements. Default: (32.0, 32.0)

  • alpha (Union[Tuple[float, float], Tensor], optional) – The scaling factor that controls the intensity of the deformation in the x and y directions, respectively, as a pair or a (2,) tensor. Default: (1.0, 1.0)

  • align_corners (bool, optional) – Interpolation flag used by grid_sample. Default: False

  • mode (str, optional) – Interpolation mode used by grid_sample. Either 'bilinear' or 'nearest'. Default: "bilinear"

  • padding_mode (str, optional) – The padding used by grid_sample. Either 'zeros', 'border' or 'reflection'. Default: "zeros"

Return type:

Tensor

Returns:

the elastically transformed input image with shape (B, C, H, W).

See also

  • RandomElasticTransform: draws uniform noise in \([-1, 1]\) for each call and applies it with probability p, in an augmentation pipeline.

  • warp_image_tps(): a smooth deformation set by control-point pairs.

  • remap(): samples an image at per-pixel coordinates given directly.

Example

>>> image = torch.rand(1, 3, 5, 5)
>>> noise = torch.rand(1, 2, 5, 5, requires_grad=True)
>>> image_hat = elastic_transform2d(image, noise, (3, 3))
>>> image_hat.mean().backward()
>>> image = torch.rand(1, 3, 5, 5)
>>> noise = torch.rand(1, 2, 5, 5)
>>> sigma = torch.tensor([4., 4.], requires_grad=True)
>>> image_hat = elastic_transform2d(image, noise, (3, 3), sigma)
>>> image_hat.mean().backward()
>>> image = torch.rand(1, 3, 5, 5)
>>> noise = torch.rand(1, 2, 5, 5)
>>> alpha = torch.tensor([16., 32.], requires_grad=True)
>>> image_hat = elastic_transform2d(image, noise, (3, 3), alpha=alpha)
>>> image_hat.mean().backward()
kornia.geometry.transform.pyrdown(input, border_type='reflect', align_corners=False, factor=2.0)[source]#

Blur images with the 5x5 pyramid kernel and downsample them by a factor, one pyramid level down.

out = pyrdown(input) takes images (B, C, H, W), blurs them with the 5x5 binomial kernel and resizes them bilinearly to (B, C, floor(H / factor), floor(W / factor)), half the size at the default factor=2.0. It resamples bilinearly where OpenCV’s pyrDown keeps every second pixel, and rounds an odd side down where OpenCV rounds it up. For the step up, use pyrup(); for every level at once, build_pyramid(); to keep every second pixel of a blurred map, blur_pool2d().

_images/pyrdown.png
Convention:
  • input: (B, C, H, W)

  • output spatial size is floor(side / factor) per dimension (\(5 \times 5 \to 2 \times 2\) at the default factor=2.0 — note OpenCV’s pyrDown rounds up instead)

  • Dynamo ONNX uses float32 reciprocal-scale arithmetic for dynamic sides, which can differ from eager by one pixel for some fractional factors (for example, side 33 and factor 1.1)

  • border_type: 'reflect' by default (blur before downsample), including short positive axes; the resized output must still have at least one pixel along each axis

  • align_corners: False by default

Parameters:
  • input (Tensor) – the torch.Tensor to be downsampled.

  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

  • factor (float, optional) – the downsampling factor Default: 2.0

Return type:

Tensor

Returns:

the downsampled torch.Tensor.

See also

  • PyrDown: the module form.

  • pyrup(): one level up, to twice the size.

  • build_pyramid(): the list of levels from repeated pyrdown calls.

  • blur_pool2d(): a zero-padded binomial blur sampled at a stride, from pixel 0; blur_pool2d(x, 5, 2) blurs with this kernel and returns ceil(H / 2) rows.

Examples

>>> input = torch.arange(16, dtype=torch.float32).reshape(1, 1, 4, 4)
>>> pyrdown(input, align_corners=True)
tensor([[[[ 3.7500,  5.2500],
          [ 9.7500, 11.2500]]]])
kornia.geometry.transform.pyrup(input, border_type='reflect', align_corners=False)[source]#

Upsample images to twice their size and blur them with the 5x5 pyramid kernel, one pyramid level up.

out = pyrup(input) takes images (B, C, H, W), resizes them bilinearly to (B, C, H * 2, W * 2) and then blurs them with the 5x5 binomial kernel; it has no factor. With pyrdown it builds the levels of build_laplacian_pyramid(). For the step down, use pyrdown(); to change the size without blurring, resize().

_images/pyrup.png
Convention:
  • input: (B, C, H, W)

  • output spatial size is exactly doubled per dimension (no factor parameter, unlike pyrdown(); \(3 \times 3 \to 6 \times 6\))

  • border_type: 'reflect' by default (blur after upsample)

  • align_corners: False by default

Parameters:
  • input (Tensor) – the torch.Tensor to be upsampled.

  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

Return type:

Tensor

Returns:

the upsampled torch.Tensor.

See also

Examples

>>> input = torch.arange(4, dtype=torch.float32).reshape(1, 1, 2, 2)
>>> pyrup(input, align_corners=True)
tensor([[[[0.7500, 0.8750, 1.1250, 1.2500],
          [1.0000, 1.1250, 1.3750, 1.5000],
          [1.5000, 1.6250, 1.8750, 2.0000],
          [1.7500, 1.8750, 2.1250, 2.2500]]]])
kornia.geometry.transform.build_pyramid(input, max_level, border_type='reflect', align_corners=False)[source]#

Build a Gaussian pyramid: the image and its successively halved levels, as a list.

levels = build_pyramid(input, max_level) takes images (B, C, H, W) and returns a list of max_level tensors: the input itself, then each previous level through pyrdown(), (B, C, H // 2, W // 2) and so on. Every level must have at least one pixel per side, so H and W must be at least 2 ** (max_level - 1). The blur extends its reflected border across the final 2 by 2 level. For band-pass levels, use build_laplacian_pyramid(); for octaves of several blurs each, with their sigmas, ScalePyramid.

_images/build_pyramid.png
Convention:
  • input: (B, C, H, W)

  • max_level is the total number of levels returned (including the unchanged original as level 0), not a 0-based index of the last level

  • each subsequent level is produced by pyrdown() (floor(side / 2) per dimension)

Parameters:
  • input (Tensor) – the torch.Tensor to be used to construct the pyramid.

  • max_level (int) – a positive integer giving the number of pyramid levels to return, including the unchanged original image as level 0.

  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

Return type:

list[Tensor]

Shape:
  • Input: (B, C, H, W)

  • Output [(B, C, H, W), (B, C, H // 2, W // 2), ...]

See also

kornia.geometry.transform.build_laplacian_pyramid(input, max_level, border_type='reflect', align_corners=False, *, minimal_padding=None)[source]#

Build a Laplacian pyramid: band-pass differences of Gaussian levels, ending with the coarsest level.

levels = build_laplacian_pyramid(input, max_level) takes images (B, C, H, W) and returns a list of max_level tensors: level i is Gaussian level i of build_pyramid() minus pyrup() of Gaussian level i + 1, and the last is the coarsest Gaussian level. Starting from x = levels[-1], x = pyrup(x, border_type, align_corners) + levels[i] for i from max_level - 2 down to 0, with the border_type and align_corners the pyramid was built with, rebuilds the input up to float rounding. The input is first reflect-padded at the right and bottom to the next power of two per side when neither side is a power of two or a side does not halve evenly max_level - 1 times (see Convention); every level is then shaped from the padded size, and the rebuilt image is the padded one. That rule is deprecated since kornia 0.9.1: with the default minimal_padding=None, an eager call that minimal_padding=True would shape differently emits a FutureWarning. minimal_padding=True gives the rule of a future minor release, which pads only to the next multiple of 2 ** (max_level - 1), and minimal_padding=False keeps the current rule without the warning. For the Gaussian levels themselves, use build_pyramid().

See [BA87] for more details.

Convention:
  • input: (B, C, H, W)

  • max_level is the total number of levels returned, not a 0-based index of the last level

  • levels 0 through max_level - 2 are band-pass residuals: level i = build_pyramid() Gaussian level i minus a pyrup()-expanded Gaussian level i + 1; only the last element (index max_level - 1) is the unsubtracted final Gaussian level — level 0 is not the unchanged original image whenever max_level > 1

  • the input is reflect-padded up to the next power of two (per dimension) when neither side is already a power of two, or when max_level > 1 and a side is not divisible by 2 ** (max_level - 1). When padding is applied, every returned level — including level 0 — is shaped from the padded size

  • with minimal_padding=True, the input is padded only when a side is not divisible by 2 ** (max_level - 1), and only that side, to the next multiple. So 480x640 at 3 levels stays 480x640, where the rule above gives 512x1024. A side too small for the padding to reflect repeats its last row or column instead, whatever border_type

  • border_type: 'reflect' by default

  • align_corners: False by default

Parameters:
  • input (Tensor) – the torch.Tensor to be used to construct the pyramid with shape (B, C, H, W).

  • max_level (int) – a positive integer giving the number of pyramid levels to return (see Convention above for what each level contains).

  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

  • minimal_padding (bool | None, optional) – True pads only as max_level needs (see Convention above), the future default. False keeps the power-of-two rule without a warning. None, the current default, uses the power-of-two rule and warns on a call that True would shape differently. Once True is the default, False keeps the power-of-two rule for one more minor release, with a deprecation warning, and then the keyword is removed. Default: None

Returns:

[(B, C, H', W'), (B, C, H' / 2, W' / 2), ...], where (H', W') equals the input (H, W) unless padding was applied (see Convention above), in which case it is the padded size.

Return type:

Output

See also

  • build_pyramid(): the Gaussian levels these are differences of.

  • pyrup(): the upsampling step between levels, also the one that rebuilds the image.

  • ScalePyramid: octaves of blurred levels for keypoint detection, with their sigmas.

Example

>>> levels = build_laplacian_pyramid(torch.rand(1, 1, 480, 640), 3, minimal_padding=True)
>>> [tuple(level.shape[-2:]) for level in levels]
[(480, 640), (240, 320), (120, 160)]
kornia.geometry.transform.is_powerof_two(x)[source]#

Check whether an integer is a positive power of two.

is_powerof_two(x) returns True for 1, 2, 4, 8, … and False for every other integer, 0 and negative numbers included. build_laplacian_pyramid() uses it to decide whether to pad an image.

Parameters:

x (int) – the integer to check.

Return type:

bool

Returns:

True if x is a positive power of two, False otherwise (including for 0).

See also

Example

>>> is_powerof_two(64)
True
>>> is_powerof_two(100)
False
kornia.geometry.transform.find_next_powerof_two(x)[source]#

Find the smallest power of two that is greater than or equal to a positive integer.

find_next_powerof_two(x) returns x itself when it is a power of two, and the next one above otherwise. It is defined for positive integers only. build_laplacian_pyramid() pads each side of an image to it.

Parameters:

x (int) – a positive integer.

Return type:

int

Returns:

the smallest power of two not below x.

See also

Example

>>> find_next_powerof_two(100)
128
>>> find_next_powerof_two(64)
64

Image 3D transforms#

Warp a volume by an affine matrix (affine3d()) or rotate it about its centre by an axis-angle vector (rotate3d()), at the input size.

kornia.geometry.transform.affine3d(tensor, matrix, mode='bilinear', padding_mode='zeros', align_corners=False)[source]#

Warp a volume by a source→destination 3x4 affine matrix, keeping its size.

out = affine3d(tensor, matrix) warps (C, D, H, W) or (B, C, D, H, W) volumes by (B, 3, 4) source→destination voxel affine matrices and returns them at their own size, as warp_affine3d() with dsize=(D, H, W) does; one matrix serves every volume of a batch. Pass align_corners=True: at the default False the warp mixes two voxel normalizations, so a translation of t voxels moves the volume t * size / (size - 1) voxels along that axis (#4503). For images, use affine().

Convention:
  • matrix is the source→destination pixel affine matrix (B, 3, 4)

  • align_corners: False by default (the 2D affine() defaults to True)

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, D, H, W) or (B, C, D, H, W).

  • matrix (Tensor) – The affine transformation matrix with shape (B, 3, 4).

  • 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: False

Return type:

Tensor

Returns:

The warped image, with the shape of the input.

See also

  • affine(): the 2D warp of images, whose default align_corners=True is correct.

  • warp_affine3d(): the same warp with an explicit output size.

  • rotate3d(): rotate a volume about its centre without building the matrix.

Example

>>> img = torch.rand(1, 2, 4, 3, 5)
>>> aff = torch.eye(3, 4)[None]
>>> out = affine3d(img, aff)
>>> print(out.shape)
torch.Size([1, 2, 4, 3, 5])
kornia.geometry.transform.rotate3d(tensor, yaw, pitch, roll, center=None, mode='bilinear', padding_mode='zeros', align_corners=False)[source]#

Rotate a volume by an axis-angle vector of yaw, pitch and roll in degrees.

out = rotate3d(tensor, yaw, pitch, roll) rotates (C, D, H, W) or (B, C, D, H, W) volumes by the axis-angle vector (yaw, pitch, roll) in degrees, (B,) each, about center ((B, 3) (x, y, z) pixels, by default the volume centre), and returns them at their size. Positive angles follow the right-hand rule, so a positive roll, about z, turns clockwise on screen, the opposite of rotate() (3D rotations are right-handed by design). Pass align_corners=True: at the default False the warp mixes two voxel normalizations, which changes the rotation unless it turns about the volume centre in a plane whose two sizes are equal, as any rotation of a cube about its centre does (#4503).

Convention:
  • center is (x, y, z) in pixels, origin at the top-left of the first depth slice (z = 0); defaults to the tensor center

  • yaw, pitch and roll are one axis-angle vector (rx, ry, rz) in degrees, not three composed per-axis Euler rotations: the three are concatenated and handed to get_projective_transform(), which applies Rodrigues’ formula. The rotation axis is (rx, ry, rz) / ||(rx, ry, rz)|| and the angle is ||(rx, ry, rz)|| degrees, so (90, 90, 0) turns through 90 * sqrt(2) degrees about (1, 1, 0) / sqrt(2) while (30, 0, 0) is a 30-degree turn about x. A single non-zero component therefore is the per-axis rotation it names, which is why one angle reads the same under either reading; two or more do not, and neither Euler order reproduces the axis-angle result.

  • align_corners: False by default (the 2D rotate() defaults to True)

Parameters:
  • tensor (Tensor) – The image tensor to be warped in shapes of (C, D, H, W) or (B, C, D, H, W).

  • yaw (Tensor) – The rx component of the axis-angle vector. The tensor must have a shape of (B), where B is batch size.

  • pitch (Tensor) – The ry component of the axis-angle vector. The tensor must have a shape of (B), where B is batch size.

  • roll (Tensor) – The rz component of the axis-angle vector. The tensor must have a shape of (B), where B is batch size.

  • center (Optional[Tensor], optional) – The center through which to rotate. The tensor must have a shape of (B, 3), where B is batch size and last dimension contains x, y and z. Default: None

  • 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: False

Returns:

The rotated tensor with shape as input.

Return type:

torch.Tensor

See also

Matrix transformations#

Build the matrices the warps take: a homography from point pairs (get_perspective_transform(), and get_perspective_transform3d() from box corners), an affine matrix from a rotation, a translation, a shear or all of them (get_rotation_matrix2d(), get_translation_matrix2d(), get_shear_matrix2d(), get_affine_matrix2d(), and in 3D get_projective_transform(), get_shear_matrix3d(), get_affine_matrix3d()), the inverse of an affine matrix (invert_affine_transform()) and [R | t] (projection_from_Rt()). get_tps_transform() fits the thin-plate spline that warp_image_tps() takes.

kornia.geometry.transform.get_perspective_transform(points_src, points_dst)[source]#

Compute the homography that maps four source points exactly onto four destination points.

M = get_perspective_transform(points_src, points_dst) takes two (B, 4, 2) sets of (x, y) points, matched by index, and returns the (B, 3, 3) homography, scaled to M[2, 2] = 1 where it can be, that maps each source point onto its destination point: the source→destination pixel homography that warp_perspective() takes. It solves the four-point system in closed form, by Heckbert’s square-to-quadrilateral mappings, rather than with the DLT, whose exact solution it equals, so it needs no linear solver. For more than four or noisy correspondences, use find_homography_dlt() or RANSAC.

The matrix maps each source point onto its destination point, up to the projective scale:

\[\begin{split}\begin{bmatrix} x^{'} \\ y^{'} \\ 1 \\ \end{bmatrix} = \begin{bmatrix} h_1 & h_2 & h_3 \\ h_4 & h_5 & h_6 \\ h_7 & h_8 & h_9 \\ \end{bmatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \\ \end{bmatrix}\end{split}\]
Convention:
  • points: (x, y), pixel centers, origin at top-left; shape (B, 4, 2)

  • a degenerate quadrilateral, such as one with three collinear points or two equal ones, does not raise: a degenerate source returns a non-finite matrix, a degenerate destination a non-finite or a singular one

  • M is scaled to M[2, 2] = 1 wherever that form is finite in the output dtype. Where it is not, because the computed bottom-right entry is exactly zero, as for some homographies that send source pixel (0, 0) to infinity although neither quadrilateral is degenerate, or because the form overflows the dtype, such as a float16 one with entries beyond 65504, M is divided instead by the geometric mean of its largest and smallest nonzero magnitudes, which keeps both in range where the dtype can hold their ratio. When the true bottom-right entry is zero but rounding leaves a small residue, M[2, 2] = 1 holds and the other entries are large, about the inverse of that residue; the matrix still maps the points. find_homography_dlt() returns the same map at another scale

  • float16 and bfloat16 points are solved in float32, and the result is cast back to their dtype

  • integer or boolean points give a matrix in the default floating dtype; floating points keep theirs

  • a caller’s autocast region does not change the result, outside TorchScript

Parameters:
  • points_src (Tensor) – coordinates of quadrangle vertices in the source image with shape (B, 4, 2).

  • points_dst (Tensor) – coordinates of the corresponding quadrangle vertices in the destination image with shape (B, 4, 2).

Return type:

Tensor

Returns:

the perspective transformation with shape (B, 3, 3).

See also

Example

>>> x1 = torch.tensor([[[0., 0.], [1., 0.], [1., 1.], [0., 1.]]])
>>> x2 = torch.tensor([[[1., 0.], [0., 0.], [0., 1.], [1., 1.]]])
>>> x2_trans_x1 = get_perspective_transform(x1, x2)
kornia.geometry.transform.get_perspective_transform3d(src, dst)[source]#

Compute the 3D homography that maps five source box corners exactly onto destination ones.

M = get_perspective_transform3d(src, dst) takes two (B, 8, 3) sets of (x, y, z) box corners in bbox_generator3d() order and returns the (B, 4, 4) homography, with M[3, 3] = 1, that maps corners 0, 1, 2, 5 and 7 of src onto those of dst: the source→destination voxel homography that warp_perspective3d() takes. The other three corners map onto theirs only when all eight pairs are related by one homography. For 2D points, use get_perspective_transform().

The function calculates the matrix of a perspective transform so that:

\[\begin{split}\begin{bmatrix} t_{i}x_{i}^{'} \\ t_{i}y_{i}^{'} \\ t_{i}z_{i}^{'} \\ t_{i} \\ \end{bmatrix} = \textbf{map_matrix} \cdot \begin{bmatrix} x_{i} \\ y_{i} \\ z_{i} \\ 1 \\ \end{bmatrix}\end{split}\]

where

\[dst(i) = (x_{i}^{'},y_{i}^{'},z_{i}^{'}), src(i) = (x_{i}, y_{i}, z_{i}), i = 0,1,2,5,7\]

Concrete math is as below:

\[\[ u_i =\frac{c_{00} * x_i + c_{01} * y_i + c_{02} * z_i + c_{03}} {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \] \[ v_i =\frac{c_{10} * x_i + c_{11} * y_i + c_{12} * z_i + c_{13}} {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \] \[ w_i =\frac{c_{20} * x_i + c_{21} * y_i + c_{22} * z_i + c_{23}} {c_{30} * x_i + c_{31} * y_i + c_{32} * z_i + c_{33}} \]\]
\[\begin{split}\begin{pmatrix} x_0 & y_0 & z_0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_0*u_0 & -y_0*u_0 & -z_0 * u_0 \\ x_1 & y_1 & z_1 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_1*u_1 & -y_1*u_1 & -z_1 * u_1 \\ x_2 & y_2 & z_2 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_2*u_2 & -y_2*u_2 & -z_2 * u_2 \\ x_5 & y_5 & z_5 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_5*u_5 & -y_5*u_5 & -z_5 * u_5 \\ x_7 & y_7 & z_7 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -x_7*u_7 & -y_7*u_7 & -z_7 * u_7 \\ 0 & 0 & 0 & 0 & x_0 & y_0 & z_0 & 1 & 0 & 0 & 0 & 0 & -x_0*v_0 & -y_0*v_0 & -z_0 * v_0 \\ 0 & 0 & 0 & 0 & x_1 & y_1 & z_1 & 1 & 0 & 0 & 0 & 0 & -x_1*v_1 & -y_1*v_1 & -z_1 * v_1 \\ 0 & 0 & 0 & 0 & x_2 & y_2 & z_2 & 1 & 0 & 0 & 0 & 0 & -x_2*v_2 & -y_2*v_2 & -z_2 * v_2 \\ 0 & 0 & 0 & 0 & x_5 & y_5 & z_5 & 1 & 0 & 0 & 0 & 0 & -x_5*v_5 & -y_5*v_5 & -z_5 * v_5 \\ 0 & 0 & 0 & 0 & x_7 & y_7 & z_7 & 1 & 0 & 0 & 0 & 0 & -x_7*v_7 & -y_7*v_7 & -z_7 * v_7 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_0 & y_0 & z_0 & 1 & -x_0*w_0 & -y_0*w_0 & -z_0 * w_0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_1 & y_1 & z_1 & 1 & -x_1*w_1 & -y_1*w_1 & -z_1 * w_1 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_2 & y_2 & z_2 & 1 & -x_2*w_2 & -y_2*w_2 & -z_2 * w_2 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_5 & y_5 & z_5 & 1 & -x_5*w_5 & -y_5*w_5 & -z_5 * w_5 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & x_7 & y_7 & z_7 & 1 & -x_7*w_7 & -y_7*w_7 & -z_7 * w_7 \\ \end{pmatrix}\end{split}\]
Convention:
  • points: (x, y, z), pixel centers, origin at the top-left of the first depth slice; shape (B, 8, 3)

  • the 15 unknowns are solved exactly from points 0, 1, 2, 5 and 7, the corners 000, 100, 110, 101 and 011 in bbox_generator3d() order; points 3, 4 and 6 are not used, so they map onto their dst only when all eight pairs are related by one homography

  • returns the source→destination pixel homography (B, 4, 4)

  • integer or boolean points give a matrix in the default floating dtype; floating points keep theirs

Parameters:
  • src (Tensor) – coordinates of the box corners in the source volume with shape (B, 8, 3).

  • dst (Tensor) – coordinates of the corresponding box corners in the destination volume with shape (B, 8, 3).

Return type:

Tensor

Returns:

the perspective transformation with shape (B, 4, 4).

See also

kornia.geometry.transform.get_projective_transform(center, angles, scales)[source]#

Compute the 3x4 affine matrix of a 3D scaling and axis-angle rotation about a centre.

P = get_projective_transform(center, angles, scales) takes (B, 3) centres (x, y, z) in pixels, axis-angle vectors (rx, ry, rz) in degrees and per-axis scale factors, and returns the (B, 3, 4) source→destination pixel matrix that scales and then rotates about center, as warp_affine3d() takes. The rotation is Rodrigues’ formula on angles converted to radians and follows the right-hand rule, so a positive rotation about z turns clockwise on screen, the opposite of get_rotation_matrix2d(). The matrix is affine, not projective; to add a translation and shears, use get_affine_matrix3d(), whose angles turn the other way (#4408).

Warning

This API signature it is experimental and might suffer some changes in the future.

Convention:
  • center is (x, y, z) in pixels, origin at the top-left of the first depth slice (z = 0)

  • rotation follows the right-hand rule (see kornia.geometry.conversions.axis_angle_to_rotation_matrix()); a positive rotation about +z is clockwise on screen (y-down image axes) — opposite of get_rotation_matrix2d()

  • returns the projection matrix (B, 3, 4) in pixel coordinates

  • a caller’s autocast region does not change the result

  • float16 and bfloat16 angles are converted and rotated in float32, and the rotation is rounded once to the input dtype

Parameters:
  • center (Tensor) – center of the rotation (x,y,z) in the source with shape (B, 3).

  • angles (Tensor) – axis angle vector containing the rotation angles in degrees in the form of (rx, ry, rz) with shape (B, 3). Internally it calls Rodrigues to compute the rotation matrix from axis-angle.

  • scales (Tensor) – per-axis scale factors (sx, sy, sz) with shape (B, 3), or (1, 3) or (3,) shared across the batch. A (3,) tensor always means per-axis factors, including when B = 3. Use (B, 1) for one isotropic factor per sample, or (1,) for one factor shared across all samples and axes. Per-sample isotropic factors must have shape (B, 1), not (B,).

Return type:

Tensor

Returns:

the projection matrix of 3D rotation with shape (B, 3, 4).

Raises:

ShapeError – If scales is not (B, 3), (B, 1), (1, 3), (3,) or (1,).

See also

kornia.geometry.transform.get_rotation_matrix2d(center, angle, scale)[source]#

Compute the 2D affine matrix that scales and rotates counter-clockwise, in degrees, about a centre.

M = get_rotation_matrix2d(center, angle, scale) takes centres (B, 2) as (x, y) pixels, angles (B,) in degrees and scale factors (B, 2) for x and y, and returns the (B, 2, 3) source→destination pixel matrix that scales and then rotates about center, which stays fixed. A positive angle turns counter-clockwise as displayed, with y pointing down. Pass M to warp_affine(); to add a translation and a shear in one (B, 3, 3) matrix, use get_affine_matrix2d(), and to rotate an image directly, rotate().

With equal scale factors scale, the matrix is:

\[\begin{split}\begin{bmatrix} \alpha & \beta & (1 - \alpha) \cdot \text{x} - \beta \cdot \text{y} \\ -\beta & \alpha & \beta \cdot \text{x} + (1 - \alpha) \cdot \text{y} \end{bmatrix}\end{split}\]

where

\[\begin{split}\alpha = \text{scale} \cdot \cos(\text{angle}) \\ \beta = \text{scale} \cdot \sin(\text{angle})\end{split}\]

With two different factors, the left 2x2 block is the rotation times diag(scale[:, 0], scale[:, 1]). A caller’s autocast region does not change the result.

Convention:
  • center is (x, y) in pixels, origin at top-left

  • positive angle rotates counter-clockwise as displayed (y-down image axes)

  • returns (B, 2, 3) affine matrix in pixel coordinates

Parameters:
  • center (Tensor) – center of the rotation in the source image with shape (B, 2).

  • angle (Tensor) – rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner) with shape (B).

  • scale (Tensor) – scale factor for x, y scaling with shape (B, 2).

Return type:

Tensor

Returns:

the affine matrix of 2D rotation with shape (B, 2, 3).

Raises:
  • TypeError – If any input is not a tensor.

  • ValueError – If input shapes are invalid, or batch sizes, devices or dtypes do not match.

See also

Example

>>> center = torch.zeros(1, 2)
>>> scale = torch.ones((1, 2))
>>> angle = 45. * torch.ones(1)
>>> get_rotation_matrix2d(center, angle, scale)
tensor([[[ 0.7071,  0.7071,  0.0000],
         [-0.7071,  0.7071,  0.0000]]])
kornia.geometry.transform.get_translation_matrix2d(translations)[source]#

Compute the 3x3 matrix of a 2D translation in pixels.

M = get_translation_matrix2d(translations) takes (B, 2) shifts (dx, dy) in pixels and returns the (B, 3, 3) matrix that moves every point by them, a positive dx to the right and a positive dy down. Pass M[:, :2] to warp_affine() or M to warp_perspective(); to shift an image directly, use translate().

Convention:
  • translations is (dx, dy) in pixels; returns (B, 3, 3) affine matrix in pixel coordinates

Parameters:

translations (Tensor) – torch.Tensor containing the translation vector with shape (B, 2).

Return type:

Tensor

Returns:

the affine transformation matrix (B, 3, 3).

Raises:

ShapeError – If translations is not (B, 2). A single translation needs shape (1, 2).

See also

kornia.geometry.transform.get_shear_matrix2d(center, sx=None, sy=None)[source]#

Compute the 3x3 matrix of a 2D shear given as two angles in radians about a centre.

M = get_shear_matrix2d(center, sx, sy) takes (B, 2) centres (x, y) in pixels and optional (B,) shear angles sx and sy in radians (zero when omitted), and returns the (B, 3, 3) source→destination pixel matrix that shears along x by -tan(sx) and then along y by -tan(sy), both about center. Affine and get_affine_matrix2d() read shear angles this way; shear() and Shear take raw factors about pixel (0, 0) instead, which shear the other way for the same values below pi / 2 in magnitude (#5661).

\[\begin{split}\begin{bmatrix} 1 & b \\ a & ab + 1 \\ \end{bmatrix}\end{split}\]

Here \(a = -\tan(sy)\) and \(b = -\tan(sx)\).

Convention:
  • center is (x, y) in pixels, origin at top-left

  • sx and sy are angles in radians; about center = (cx, cy), the forward mapping is x_out = x - tan(sx) * (y - cy), then y_out = y - tan(sy) * (x_out - cx). Pixel x increases rightward and y downward. This differs from shear()’s raw factors.

  • returns (B, 3, 3) affine matrix in pixel coordinates

Parameters:
  • center (Tensor) – shearing center coordinates of (x, y).

  • sx (Optional[Tensor], optional) – shearing angle along x axis in radians. Default: None

  • sy (Optional[Tensor], optional) – shearing angle along y axis in radians Default: None

Return type:

Tensor

Returns:

the shear matrix with shape (B, 3, 3), to be passed to the affine transformation.

See also

  • get_shear_matrix3d(): the 3D shear from up to six angles, (B, 4, 4).

  • shear(): shear an image by raw factors about pixel (0, 0), which shear the other way below pi / 2.

  • get_affine_matrix2d(): this shear composed with a rotation, a scale and a translation.

Examples

>>> rng = torch.manual_seed(0)
>>> sx = torch.randn(1)
>>> sx
tensor([1.5410])
>>> center = torch.tensor([[0., 0.]])  # Bx2
>>> get_shear_matrix2d(center, sx=sx)
tensor([[[  1.0000, -33.5468,   0.0000],
         [ -0.0000,   1.0000,   0.0000],
         [  0.0000,   0.0000,   1.0000]]])
kornia.geometry.transform.get_shear_matrix3d(center, sxy=None, sxz=None, syx=None, syz=None, szx=None, szy=None)[source]#

Compute the 4x4 matrix of a 3D shear given as up to six angles in radians about a centre.

M = get_shear_matrix3d(center, sxy, sxz, syx, syz, szx, szy) takes (B, 3) centres (x, y, z) in pixels and optional (B,) shear angles in radians (zero when omitted), and returns the (B, 4, 4) source→destination pixel matrix below, whose translation keeps center fixed. With \(S_{ab} = -\tan(s_{ab})\), the angle sab on its own adds \(S_{ab}\) times coordinate a to coordinate b. sxy and sxz form one shear, syx and syz a second and szx and szy a third, and the linear part is the product of the three in that order, so a point is sheared by szx and szy first and by sxy and sxz last.

\[\begin{split}\begin{bmatrix} 1 & o & r & x - (x + oy + rz) \\ m & p & s & y - (mx + py + sz) \\ n & q & t & z - (nx + qy + tz) \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} Where: m = S_{xy} n = S_{xz} o = S_{yx} p = S_{xy}S_{yx} + 1 q = S_{xz}S_{yx} + S_{yz} r = S_{zx} + S_{yx}S_{zy} s = S_{xy}S_{zx} + (S_{xy}S_{yx} + 1)S_{zy} t = S_{xz}S_{zx} + (S_{xz}S_{yx} + S_{yz})S_{zy} + 1\end{split}\]

Here \(S_{ab} = -\tan(s_{ab})\), and \((x, y, z)\) is center.

Convention:
  • center is (x, y, z) in pixels, origin at the top-left of the first depth slice (z = 0); it is a fixed point of the returned matrix for every combination of shears

  • returns (B, 4, 4) affine matrix in pixel coordinates

Parameters:
  • center (Tensor) – shearing center coordinates of (x, y, z), with shape (B, 3).

  • sxy (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{xy} x\) to y. Default: None

  • sxz (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{xz} x\) to z. Default: None

  • syx (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{yx} y\) to x. Default: None

  • syz (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{yz} y\) to z. Default: None

  • szx (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{zx} z\) to x. Default: None

  • szy (Optional[Tensor], optional) – shearing angle in radians that adds \(S_{zy} z\) to y. Default: None

Return type:

Tensor

Returns:

the shear matrix with shape (B, 4, 4), to be passed to the affine transformation.

See also

Examples

>>> rng = torch.manual_seed(0)
>>> sxy, sxz, syx, syz = torch.randn(4, 1)
>>> sxy, sxz, syx, syz
(tensor([1.5410]), tensor([-0.2934]), tensor([-2.1788]), tensor([0.5684]))
>>> center = torch.tensor([[0., 0., 0.]])  # Bx3
>>> get_shear_matrix3d(center, sxy=sxy, sxz=sxz, syx=syx, syz=syz)
tensor([[[  1.0000,  -1.4369,   0.0000,   0.0000],
         [-33.5468,  49.2039,   0.0000,   0.0000],
         [  0.3022,  -1.0729,   1.0000,   0.0000],
         [  0.0000,   0.0000,   0.0000,   1.0000]]])
kornia.geometry.transform.get_affine_matrix2d(translations, center, scale, angle, sx=None, sy=None)[source]#

Compose a 2D affine matrix from a translation, clockwise rotation, scale and shear about a centre.

M = get_affine_matrix2d(translations, center, scale, angle, sx, sy) takes (B, 2) translations (dx, dy), centres (x, y) and scale factors for x and y, (B,) angles in degrees and optional (B,) shear angles sx and sy in radians, and returns the (B, 3, 3) source→destination pixel matrix that shears, scales, rotates and then translates, the first three about center. A positive angle turns clockwise as displayed, unlike get_rotation_matrix2d(), rotate() and Affine (#4408). Pass M[:, :2] to warp_affine() or M to warp_perspective().

Convention:
  • center is (x, y) in pixels, origin at top-left

  • positive angle rotates clockwise as displayed — this function negates angle before delegating to get_rotation_matrix2d(), whose convention is CCW-positive

  • sx and sy are angles in radians, using get_shear_matrix2d()’s negative-tangent, x-then-y shear about center, applied before rotation, scale and translation

  • returns (B, 3, 3) affine matrix in pixel coordinates

  • a caller’s autocast region does not change the result (there, mixed float32 and half center and shears run in float32)

Parameters:
  • translations (Tensor) – torch.Tensor containing the translation vector with shape (B, 2).

  • center (Tensor) – torch.Tensor containing the center vector with shape (B, 2).

  • scale (Tensor) – torch.Tensor containing the scale factor with shape (B, 2).

  • angle (Tensor) – torch.Tensor of angles in degrees (B).

  • sx (Optional[Tensor], optional) – torch.Tensor containing the shear angle in radians in the x-direction with shape (B). Default: None

  • sy (Optional[Tensor], optional) – torch.Tensor containing the shear angle in radians in the y-direction with shape (B). Default: None

Return type:

Tensor

Returns:

the affine transformation matrix (B, 3, 3).

See also

  • get_rotation_matrix2d(): rotation and scale only, (B, 2, 3), counter-clockwise for a positive angle.

  • get_affine_matrix3d(): the 3D composition, (B, 4, 4), whose positive z angle turns counter-clockwise on screen.

  • Affine: warp an image by these parameters in one module, counter-clockwise for a positive angle.

  • get_shear_matrix2d(): the shear part alone.

  • find_affine(): an affine matrix fitted to point correspondences instead of built from parameters.

kornia.geometry.transform.get_affine_matrix3d(translations, center, scale, angles, sxy=None, sxz=None, syx=None, syz=None, szx=None, szy=None)[source]#

Compose a 3D affine matrix from a translation, axis-angle rotation, scale and shears about a centre.

M = get_affine_matrix3d(translations, center, scale, angles) takes (B, 3) translations (dx, dy, dz), centres (x, y, z) in pixels, per-axis scale factors and axis-angle vectors in degrees, plus up to six optional (B,) shear angles in radians, and returns the (B, 4, 4) source→destination pixel matrix that shears, scales, rotates and then translates, the first three about center. The angles are negated before get_projective_transform(), so they turn the other way from that function and rotate3d(): a positive rotation about z turns counter-clockwise on screen, as rotate() does and get_affine_matrix2d() does not (#4408). Pass M[:, :3] to warp_affine3d() or M to warp_perspective3d().

Convention:
  • center is (x, y, z) in pixels, origin at the top-left of the first depth slice (z = 0)

  • angles are negated before delegating to get_projective_transform(), whose own rotation convention follows the right-hand rule (see kornia.geometry.conversions.axis_angle_to_rotation_matrix())

  • returns (B, 4, 4) affine matrix in pixel coordinates

  • a caller’s autocast region does not change the result (there, mixed float32 and half center and shears run in float32)

Parameters:
  • translations (Tensor) – torch.Tensor containing the translation vector (dx,dy,dz) with shape (B, 3).

  • center (Tensor) – torch.Tensor containing the center vector (x,y,z) with shape (B, 3).

  • scale (Tensor) – per-axis scale factors (sx, sy, sz) with shape (B, 3), or (1, 3) or (3,) shared across the batch. A (3,) tensor always means per-axis factors, including when B = 3. Use (B, 1) for one isotropic factor per sample, or (1,) for one factor shared across all samples and axes. Per-sample isotropic factors must have shape (B, 1), not (B,).

  • angles (Tensor) – axis angle vector containing the rotation angles in degrees in the form of (rx, ry, rz) with shape (B, 3). Internally it calls Rodrigues to compute the rotation matrix from axis-angle.

  • sxy (Optional[Tensor], optional) – the shear angle sxy of get_shear_matrix3d(), in radians, with shape (B). Default: None

  • sxz (Optional[Tensor], optional) – the shear angle sxz of get_shear_matrix3d(), in radians, with shape (B). Default: None

  • syx (Optional[Tensor], optional) – the shear angle syx of get_shear_matrix3d(), in radians, with shape (B). Default: None

  • syz (Optional[Tensor], optional) – the shear angle syz of get_shear_matrix3d(), in radians, with shape (B). Default: None

  • szx (Optional[Tensor], optional) – the shear angle szx of get_shear_matrix3d(), in radians, with shape (B). Default: None

  • szy (Optional[Tensor], optional) – the shear angle szy of get_shear_matrix3d(), in radians, with shape (B). Default: None

Return type:

Tensor

Returns:

the 3d affine transformation matrix (B, 4, 4).

Raises:

ShapeError – If scale is not (B, 3), (B, 1), (1, 3), (3,) or (1,); see get_projective_transform().

See also

kornia.geometry.transform.invert_affine_transform(matrix)[source]#

Invert 2D affine matrices of shape (B, 2, 3).

M_inv = invert_affine_transform(M) returns, for each (B, 2, 3) affine matrix, the (B, 2, 3) inverse of its 3x3 extension with the last row (0, 0, 1), in the dtype of M. It is pure matrix inversion, so the result keeps the input’s coordinates, pixel or normalized: the inverse of a source→destination matrix maps destination to source, and warps a warp_affine() result back. For (B, 3, 3) homographies, use torch.linalg.inv().

The input is the matrix:

\[\begin{split}\begin{bmatrix} a_{11} & a_{12} & b_{1} \\ a_{21} & a_{22} & b_{2} \\ \end{bmatrix}\end{split}\]
Convention:
  • matrix is a (B, 2, 3) affine transform in any coordinate convention (pixel or normalized) — pure matrix inversion; the result stays in the input’s convention

  • in eager mode a singular matrix raises torch.linalg.LinAlgError

Parameters:

matrix (Tensor) – original affine transform. The torch.Tensor must be in the shape of (B, 2, 3).

Return type:

Tensor

Returns:

the reverse affine transform with shape (B, 2, 3).

See also

kornia.geometry.transform.projection_from_Rt(rmat, tvec)[source]#

Stack rotations and translations into [R | t] matrices of shape (*, 3, 4).

P = projection_from_Rt(rmat, tvec) concatenates rotations (*, 3, 3) and translations (*, 3, 1) with the same leading dimensions into the (*, 3, 4) matrices \(P = [R | t]\). It applies no intrinsics: for a camera projection matrix \(K [R | t]\), use projection_from_KRt(), and for a 4x4 pose, Rt_to_matrix4x4().

Warning

This API signature it is experimental and might suffer some changes in the future.

Convention:
  • returns the concatenation \([R | t]\) with shape (*, 3, 4)

Parameters:
  • rmat (Tensor) – the rotation matrix with shape (*, 3, 3).

  • tvec (Tensor) – the translation vector with shape (*, 3, 1).

Return type:

Tensor

Returns:

the projection matrix with shape (*, 3, 4).

See also

kornia.geometry.transform.get_tps_transform(points_src, points_dst)[source]#

Fit a thin-plate-spline warp that maps source points exactly onto target points.

kernel_weights, affine_weights = get_tps_transform(points_src, points_dst) takes (B, N, 2) point pairs and returns the (B, N, 2) kernel weights and (B, 3, 2) affine weights of Bookstein’s thin-plate spline, whose kernels are centred on the points where it interpolates: warp_points_tps(points_src, points_src, kernel_weights, affine_weights) returns points_dst. It is the same spline as scipy.interpolate.RBFInterpolator(points_src, points_dst, kernel="thin_plate_spline", degree=1). To warp an image, fit the reverse mapping and use warp_image_tps() (see Convention); for a homography from four point pairs, use get_perspective_transform().

Convention:
  • points_src/points_dst: (B, N, 2) in (x, y) order, in whatever coordinate frame the caller supplies; no normalization is applied

  • returns kernel weights (B, N, 2) and affine weights (B, 3, 2); the identity mapping gives zero kernel weights and an identity affine up to solver round-off, and any pairs related by an affine map, a constant map included, give zero kernel weights. The kernel weights w satisfy w.sum(1) == 0 and w.mT @ points_src == 0, so the warp leaves its affine part only like log r far from the landmarks

  • for float32 points, a caller’s autocast region does not change the result, outside TorchScript (in the region, a mix of float32, float16 and bfloat16 points meets in float32); any other dtype mismatch raises RuntimeError

  • zero or one point makes the linear system singular and torch.linalg.solve raises; two points, like any set of points_src all on one line, make it singular too, but round-off can hide that, and the solve then returns huge affine weights that throw points off that line far away and may miss the landmarks themselves. Repeated points_src are singular in the same way; repeated points_dst are fine

  • the tensor passed as the first argument is the kernel_centers that the warp function must receive with these weights. warp_points_tps() is composed in the natural (points_src, points_dst) order; warp_image_tps() samples from output space back into input space, so it is composed reversed, with both point sets in the normalized frame given in its Convention block:

    kernel_weights, affine_weights = get_tps_transform(points_dst, points_src)
    warped = warp_image_tps(image, kernel_centers=points_dst,
                            kernel_weights=kernel_weights, affine_weights=affine_weights)
    
  • in kornia 0.9.1, a call outside TorchScript and torch.compile emits a FutureWarning that repeats which tensor to pass as kernel_centers; it reads no tensor and does not change the result

Parameters:
  • points_src (Tensor) – batch of source points (B, N, 2) as \((x, y)\) coordinate vectors.

  • points_dst (Tensor) – batch of target points (B, N, 2) as \((x, y)\) coordinate vectors.

Return type:

tuple[Tensor, Tensor]

Returns:

(B, N, 2) torch.Tensor of kernel weights and (B, 3, 2)

torch.Tensor of affine weights. The last dimension contains the x-transform and y-transform weights as separate columns. Row 0 of the affine weights is the translation and rows 1 and 2 the matrix A that multiplies a point as p @ A.

See also

Example

>>> points_src = torch.rand(1, 5, 2)
>>> points_dst = torch.rand(1, 5, 2)
>>> kernel_weights, affine_weights = get_tps_transform(points_src, points_dst)

Crop operators#

Crop (B, C, H, W) images by integer slicing of axis-aligned boxes (crop_by_indices()), by resampling a four-corner box to a fixed size (crop_and_resize()) or onto a second box whose size sets the output (crop_by_boxes()), by a source→destination pixel matrix (crop_by_transform_mat()), or at the centre (center_crop(), and its module form CenterCrop2D). A box is (B, 4, 2): its (x, y) corners clockwise from the top-left, as inclusive pixel positions.

kornia.geometry.transform.crop_by_indices(input_tensor, src_box, size=None, interpolation='bilinear', align_corners=None, antialias=False, shape_compensation='resize')[source]#

Crop axis-aligned boxes by integer slicing, then resize or pad each crop to a common size.

patches = crop_by_indices(input_tensor, src_box, size) takes images (B, C, H, W) and one box per image, (B, 4, 2), slices each box out with integer indices and returns (B, C, h, w) for size = (h, w). Outside graph export (see the notes) it slices by the top-left corner, the right edge (x of vertex 1) and the bottom edge (y of vertex 3) of a box, and truncates float coordinates toward zero; without size it takes the size from the box as infer_bbox_shape() does, whose height reads y of vertex 2, and every box must have the same size. A slice of another size than size, from a box of another size or one clipped by the image border, is resized (shape_compensation='resize') or zero-padded or trimmed to it ('pad'). The crop is differentiable with respect to the image, not the box: for sub-pixel, rotated or differentiable boxes, use crop_and_resize().

Convention:
  • input: (B, C, H, W); size is (h, w) if given, else inferred from src_box; a single box does not broadcast over a batch of images

  • src_box: (B, 4, 2) corner points in (x, y) order top-left, top-right, bottom-right, bottom-left — same convention as crop_and_resize()

  • unlike the other crop operators in this module: interpolation= (not mode=), align_corners=None by default (not True), and an antialias=False option

  • shape_compensation ('resize' by default) applies whenever the cropped slice does not match size, whether or not src_box is identical across the batch — each row’s output depends only on its own box.

  • the part of a box outside the image is clipped on every side, a box that starts left of or above the image included, and shape_compensation then applies. With 'pad' the padding goes on the side where the box overflowed, so every kept pixel stays at its position in the box.

Note

Under torch.compile() a non-empty batch with size given, 'bilinear', 'bicubic' or 'nearest' interpolation, antialias=False and shape_compensation='resize' is cropped by a gather that keeps the box coordinates on the device, so it traces with fullgraph=True and matches the eager result up to float rounding. Every other call keeps the eager path, which reads the box coordinates back to Python and breaks the graph. Graph export is described in the note below.

Parameters:
  • input_tensor (Tensor) – the 2D image torch.Tensor with shape (B, C, H, W).

  • src_box (Tensor) – a torch.Tensor with shape (B, 4, 2) containing the coordinates of the bounding boxes to be extracted, where each box is defined in the clockwise order: top-left, top-right, bottom-right and bottom-left. The coordinates must be in x, y order.

  • size (Optional[Tuple[int, int]], optional) – output size. An auto resize or F.pad will be performed according to shape_compensation if the cropped slice sizes are not exactly align size. If None, will auto-infer from src_box. Default: None

  • interpolation (str, optional) – algorithm used for upsampling: 'nearest' | 'nearest-exact' | 'bilinear' | 'bicubic' | 'area'. Default: "bilinear"

  • align_corners (Optional[bool], optional) – interpolation flag. Default: None

  • antialias (bool, optional) – if True, then image will be filtered with Gaussian before downscaling. No effect for upscaling. Default: False

  • shape_compensation (str, optional) – how to compensate when the cropped slice size differs from size: 'resize' resamples, while 'pad' pads or trims. 'F.pad' is a legacy alias for 'pad'. Default: "resize"

Return type:

Tensor

Returns:

The cropped torch.Tensor with shape (B, C, h, w), where (h, w) is size if given, otherwise the shape inferred from src_box.

Raises:

ValueError – if shape_compensation is not 'resize', 'pad' or 'F.pad', or size is None and the boxes differ in size.

See also

  • crop_and_resize(): resamples any four-corner box, differentiably with respect to its corners.

  • CenterCrop2D: slices the central window with this function in its default mode, unless the size exceeds the input on an axis, where it zero-pads and slices directly.

  • RandomCrop: random boxes, sliced with this function in its default mode, in an augmentation pipeline.

Note

Under graph export (torch.export.export() / torch.onnx.export()) the box coordinates cannot be read back to Python, so the crop is captured as the same warp as crop_and_resize() (align_corners=True), which keeps the box coordinates dynamic. This needs size: a box that is exactly size pixels (what RandomCrop and CenterCrop2D produce) is reproduced exactly, any other box is resampled to size with align_corners=True regardless of shape_compensation and align_corners. Without size the eager path is kept: it reads the box coordinates back to Python, which breaks the graph under torch.compile() and is rejected by torch.export as data-dependent.

kornia.geometry.transform.crop_by_boxes(input_tensor, src_box, dst_box, mode='bilinear', padding_mode='zeros', align_corners=True, validate_boxes=None)[source]#

Crop images by mapping a source box onto a destination box, whose size sets the output size.

patches = crop_by_boxes(input_tensor, src_box, dst_box) takes images (B, C, H, W) and two boxes per image, (B, 4, 2) each (both (1, 4, 2) for all images), warps each image by the homography that maps src_box onto dst_box and returns the (B, C, h, w) window at destination pixels (0, 0)..``(w - 1, h - 1)``, where (h, w) is the inclusive size of dst_box. Every dst_box in the batch must have that same size, since the output is one tensor, and a dst_box that does not start at (0, 0) shifts the crop by its offset, partly out of the window. The size is read from the dst_box values on the host. When dst_box is the window (0, 0)..``(w - 1, h - 1)`` itself and (h, w) is known, crop_and_resize() with size=(h, w) gives the same crop without that read; it always places the destination box at the origin, so it cannot reproduce an offset dst_box. For volumes, use crop_by_boxes3d().

Convention:
  • input: (B, C, H, W)

  • src_box/dst_box: (B, 4, 2) corner points in (x, y) order top-left, top-right, bottom-right, bottom-left — same convention as crop_and_resize(); dst_box determines the output resolution

  • a single box (batch size 1) broadcasts over a batch of images, but a single image does not broadcast over a batch of boxes; src_box and dst_box have the same batch size

  • an empty batch has no dst_box to read a size from and returns (0, C, 0, 0)

  • a box axis of one pixel in one box but not in the other returns NaN (a meaningless finite value with mode='nearest'), as in crop_and_resize() (#4747)

  • a float16 or bfloat16 image is cropped in float32, its homography solved and kept in float32, and the patches rounded once to the image dtype

Parameters:
  • input_tensor (Tensor) – the 2D image torch.Tensor with shape (B, C, H, W).

  • src_box (Tensor) – a torch.Tensor with shape (B, 4, 2) containing the coordinates of the bounding boxes to be extracted, where each box is defined in the clockwise order: top-left, top-right, bottom-right and bottom-left. The coordinates must be in x, y order.

  • dst_box (Tensor) – a torch.Tensor with shape (B, 4, 2) containing the coordinates of the bounding boxes to be placed, where each box is defined in the clockwise order: top-left, top-right, bottom-right and bottom-left. The coordinates must be in x, y order.

  • 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) – mode for grid_generation. Default: True

  • validate_boxes (Optional[bool], optional) – deprecated since kornia 0.9.1 and ignored; passing True or False emits a DeprecationWarning, and the default None does not. The boxes are not validated, whatever its value: only the shapes of src_box and dst_box and the equal size of the dst_box boxes are checked. Default: None

Return type:

Tensor

Returns:

the patches, with shape (B, C, h, w) for the size (h, w) of dst_box.

Raises:

AssertionError – if the boxes of dst_box differ in size.

See also

Examples

>>> input = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
>>> src_box = torch.tensor([[
...     [1., 1.],
...     [2., 1.],
...     [2., 2.],
...     [1., 2.],
... ]])  # 1x4x2
>>> dst_box = torch.tensor([[
...     [0., 0.],
...     [1., 0.],
...     [1., 1.],
...     [0., 1.],
... ]])  # 1x4x2
>>> crop_by_boxes(input, src_box, dst_box, align_corners=True)
tensor([[[[ 5.0000,  6.0000],
          [ 9.0000, 10.0000]]]])
kornia.geometry.transform.crop_by_transform_mat(input_tensor, transform, out_size, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Crop images by a source→destination pixel matrix, affine or homography, into a given output size.

patches = crop_by_transform_mat(input_tensor, transform, out_size) takes images (B, C, H, W) and a source→destination pixel matrix per image, affine (B, 2, 3) or homography (B, 3, 3) (a batch of 1 serves every image), and returns the (B, C, h, w) destination window starting at pixel (0, 0) for out_size = (h, w). It calls warp_affine() for an affine matrix and warp_perspective() for a homography, after casting the matrix to the image dtype and expanding it to the batch: a float64 or integer matrix crops a float32 image, which those two reject, and a batch-1 homography serves a batch, which warp_perspective alone does not allow. To build the matrix from boxes, use crop_by_boxes() or crop_and_resize(); for volumes, crop_by_transform_mat3d().

Convention:
  • input: (B, C, H, W); out_size is (h, w)

  • transform is the source→destination pixel transform, accepted as either (B, 2, 3) affine or (B, 3, 3) homogeneous; dispatch is by shape — (B, 2, 3) takes the cheaper warp_affine() path, while (B, 3, 3) takes warp_perspective() and uses the full matrix, so a non-trivial third (projective) row changes the output; an out_size dimension of 1 is handled like any other size

Parameters:
  • input_tensor (Tensor) – the 2D image torch.Tensor with shape (B, C, H, W).

  • transform (Tensor) – a perspective transformation matrix with shape (B, 3, 3), or an affine matrix with shape (B, 2, 3) that takes the cheaper warp_affine path.

  • out_size (Tuple[int, int]) – size of the output image (height, width).

  • mode (str, optional) – interpolation mode to calculate output values 'bilinear' | 'nearest'. Default: "bilinear"

  • padding_mode (str) – padding mode for outside grid values 'zeros' | 'border' | 'reflection'. Default: "zeros"

  • align_corners (bool, optional) – mode for grid_generation. Default: True

Return type:

Tensor

Returns:

the patches, with shape (B, C, h, w).

See also

kornia.geometry.transform.center_crop(input_tensor, size, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Crop the central window of each image to a given size, in one call.

patches = center_crop(input_tensor, size) takes images (B, C, H, W) and returns their central (B, C, h, w) windows for size = (h, w): a sub-image of the input, with the extra pixel of an odd margin at the bottom/right. A size larger than the input pads by padding_mode (zeros by default), again with the extra pixel at the bottom/right. The crop is an integer translation sampled by warp_perspective(), so it is exact up to float rounding. For the module form, which slices by default, use CenterCrop2D; for volumes, center_crop3d().

Convention:
  • input: (B, C, H, W) (strictly 4D — no unbatched (C, H, W)/ (H, W) input is accepted); size is (h, w)

  • offset: the crop starts at the integer pixel int(H / 2 - h / 2) (likewise for the width), as in CenterCrop2D, so the output is a sub-image of the input. With an odd margin the extra pixel is left at the bottom/right; for a size larger than the input, the extra padding pixel goes there too.

Parameters:
  • input_tensor (Tensor) – the 2D image torch.Tensor with shape (B, C, H, W).

  • size (Tuple[int, int]) – a tuple with the expected height and width of the output patch.

  • 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) – mode for grid_generation. Default: True

Return type:

Tensor

Returns:

the central windows, with shape (B, C, h, w).

See also

  • CenterCrop2D: the module form; slices with integer indices by default instead of resampling.

  • center_crop3d(): the central window of each volume; keep its default align_corners=True.

  • crop_and_resize(): a window at any box, resampled to a fixed size.

  • CenterCrop: the same windows as an augmentation, for augmentation pipelines; it raises for a size larger than the input instead of padding.

Examples

>>> input = torch.tensor([[[
...     [1., 2., 3., 4.],
...     [5., 6., 7., 8.],
...     [9., 10., 11., 12.],
...     [13., 14., 15., 16.],
...  ]]])
>>> center_crop(input, (2, 4), mode='nearest', align_corners=True)
tensor([[[[ 5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.]]]])
kornia.geometry.transform.crop_and_resize(input_tensor, boxes, size, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Crop a four-corner box from each image and resample it to a fixed output size.

patches = crop_and_resize(input_tensor, boxes, size) takes images (B, C, H, W) and boxes (B, 4, 2), one per image or (1, 4, 2) for all of them, and returns the (B, C, h, w) patches for size = (h, w). The box corners land on the corner pixels of the patch: a rectangle is resized corner to corner, any other quadrilateral is rectified by the homography between the two, and the patch is differentiable with respect to the corners. A single image does not broadcast over a batch of boxes. For an exact integer slice without interpolation, use crop_by_indices(); to place the crop by a second box, crop_by_boxes(); for volumes, crop_and_resize3d().

Convention:
  • see Conventions & Pitfalls for the align_corners defaults and sampling rules

  • a float16 or bfloat16 image is cropped in float32, its homography solved and kept in float32, and the patches rounded once to the image dtype; float32 boxes keep their precision

  • input: (B, C, H, W); size is (h, w)

  • boxes: (B, 4, 2) corner points in (x, y) order top-left, top-right, bottom-right, bottom-left; coordinates are inclusive pixel positions (box (1, 1)..``(2, 2)`` selects a \(2 \times 2\) pixel block), origin at top-left

  • a box axis of one pixel is cropped exactly when size is one pixel on that axis too; one pixel in the box but not in size, or the reverse, has no invertible matrix and returns NaN (a meaningless finite value with mode='nearest'), and so does a box with no homography to the patch, such as a triangle (#4747)

Parameters:
  • input_tensor (Tensor) – the 2D image torch.Tensor with shape (B, C, H, W).

  • boxes (Tensor) – a torch.Tensor containing the coordinates of the bounding boxes to be extracted. The torch.Tensor must have the shape of (B, 4, 2), where each box is defined in the following (clockwise) order: top-left, top-right, bottom-right and bottom-left. The coordinates must be in the x, y order.

  • size (Tuple[int, int]) – a tuple with the height and width that will be used to resize the extracted patches.

  • 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) – mode for grid_generation. Default: True

Return type:

Tensor

Returns:

the patches, with shape (B, C, h, w) for size = (h, w).

See also

  • crop_by_indices(): integer slicing of axis-aligned boxes, without interpolation.

  • crop_by_boxes(): maps the box onto a second box, whose size sets the output size.

  • crop_and_resize3d(): the same for volumes and (B, 8, 3) boxes; pass align_corners=True there.

  • resize(): the whole image; for an image and a size of at least 2 pixels on each axis, bilinear crop_and_resize of the image’s corner box equals resize(input, size, align_corners=True).

  • RandomResizedCrop: random boxes resized to a fixed size, in an augmentation pipeline.

Example

>>> input = torch.tensor([[[
...     [1., 2., 3., 4.],
...     [5., 6., 7., 8.],
...     [9., 10., 11., 12.],
...     [13., 14., 15., 16.],
... ]]])
>>> boxes = torch.tensor([[
...     [1., 1.],
...     [2., 1.],
...     [2., 2.],
...     [1., 2.],
... ]])  # 1x4x2
>>> crop_and_resize(input, boxes, (2, 2), mode='nearest', align_corners=True)
tensor([[[[ 6.,  7.],
          [10., 11.]]]])

Crop operators (3D)#

Crop (B, C, D, H, W) volumes by (B, 8, 3) boxes, resampled to a fixed size (crop_and_resize3d()) or onto a second box (crop_by_boxes3d()), by a source→destination voxel matrix (crop_by_transform_mat3d()), or at the centre (center_crop3d()). Pass align_corners=True: at False the 3D crops sample off the box (#4503).

kornia.geometry.transform.crop_by_boxes3d(tensor, src_box, dst_box, interpolation='bilinear', align_corners=False)[source]#

Crop volumes by mapping a source box onto a destination box, whose size sets the output size.

patches = crop_by_boxes3d(tensor, src_box, dst_box) takes volumes (B, C, D, H, W) and two boxes per volume, (B, 8, 3) each (both (1, 8, 3) for all volumes), warps each volume by the affine map that takes the corners of src_box onto those of dst_box, which must exist, as it does for any two parallelepipeds or two translated copies of one box, and returns the (B, C, d, h, w) window that starts at voxel (0, 0, 0), where (d, h, w) is the inclusive size of dst_box; every dst_box in the batch must have that size. Pass align_corners=True: the default False samples off the box (#4503). When the output size is known, crop_and_resize3d() takes it instead of a second box; for images, use crop_by_boxes().

Convention:
  • input: (B, C, D, H, W)

  • src_box/dst_box: (B, 8, 3) corner points in (x, y, z) order, front face then back face, each face top-left, top-right, bottom-right, bottom-left — same convention as crop_and_resize3d(); dst_box determines the output resolution

  • align_corners: False by default

  • an empty batch has no dst_box to read a size from and returns (0, C, 0, 0, 0)

Parameters:
  • tensor (Tensor) – the 3D volume tensor with shape (B, C, D, H, W).

  • src_box (Tensor) – a tensor with shape (B, 8, 3) containing the coordinates of the bounding boxes to be extracted, where each box is defined in the clockwise order: front-top-left, front-top-right, front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left. The coordinates must be in x, y, z order.

  • dst_box (Tensor) – a tensor with shape (B, 8, 3) containing the coordinates of the bounding boxes to be placed, where each box is defined in the clockwise order: front-top-left, front-top-right, front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left. The coordinates must be in x, y, z order.

  • interpolation (str, optional) – Interpolation flag. Default: "bilinear"

  • align_corners (bool, optional) – mode for grid_generation. Default: False

Return type:

Tensor

Returns:

the patches, with shape (B, C, d, h, w) for the size (d, h, w) of dst_box.

Raises:

AssertionError – if the boxes of dst_box differ in size, a box has a non-finite coordinate or edges along one axis that span different extents on it, or no affine map takes a src_box onto its dst_box.

See also

Examples

>>> input = torch.tensor([[[
...         [[ 0.,  1.,  2.,  3.],
...          [ 4.,  5.,  6.,  7.],
...          [ 8.,  9., 10., 11.],
...          [12., 13., 14., 15.]],
...         [[16., 17., 18., 19.],
...          [20., 21., 22., 23.],
...          [24., 25., 26., 27.],
...          [28., 29., 30., 31.]],
...         [[32., 33., 34., 35.],
...          [36., 37., 38., 39.],
...          [40., 41., 42., 43.],
...          [44., 45., 46., 47.]]]]])
>>> src_box = torch.tensor([[
...     [1., 1., 1.],
...     [3., 1., 1.],
...     [3., 3., 1.],
...     [1., 3., 1.],
...     [1., 1., 2.],
...     [3., 1., 2.],
...     [3., 3., 2.],
...     [1., 3., 2.],
... ]])  # 1x8x3
>>> dst_box = torch.tensor([[
...     [0., 0., 0.],
...     [2., 0., 0.],
...     [2., 2., 0.],
...     [0., 2., 0.],
...     [0., 0., 1.],
...     [2., 0., 1.],
...     [2., 2., 1.],
...     [0., 2., 1.],
... ]])  # 1x8x3
>>> crop_by_boxes3d(input, src_box, dst_box, interpolation='nearest', align_corners=True)
tensor([[[[[21., 22., 23.],
           [25., 26., 27.],
           [29., 30., 31.]],

          [[37., 38., 39.],
           [41., 42., 43.],
           [45., 46., 47.]]]]])
kornia.geometry.transform.crop_by_transform_mat3d(tensor, transform, out_size, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Crop volumes by a source→destination voxel matrix into a given output size.

patches = crop_by_transform_mat3d(tensor, transform, out_size) takes volumes (B, C, D, H, W) and a source→destination voxel matrix per volume, (B, 3, 4) or (B, 4, 4) (a batch of 1 serves every volume, which warp_affine3d() alone does not allow), and returns the (B, C, d, h, w) window that starts at voxel (0, 0, 0) for out_size = (d, h, w). It warps with warp_affine3d() and uses only the top three rows, so a projective last row is ignored. Unlike crop_by_transform_mat(), it does not cast the matrix: its dtype must be the volume’s. For images, use crop_by_transform_mat(); to build the matrix from boxes, crop_by_boxes3d().

Convention:
  • input: (B, C, D, H, W); out_size is (d, h, w)

  • transform is the source→destination pixel transform, accepted as either (B, 3, 4) affine or (B, 4, 4) homogeneous; only the top three rows are used, so a projective last row is ignored (unlike the 2D crop_by_transform_mat())

  • align_corners: True by default; False warps by a matrix normalized for corner-aligned voxels (#4503)

Parameters:
  • tensor (Tensor) – the 3D volume tensor with shape (B, C, D, H, W).

  • transform (Tensor) – the source->destination pixel transform, either affine with shape (B, 3, 4) or homogeneous with shape (B, 4, 4).

  • out_size (Tuple[int, int, int]) – size of the output image (depth, height, width).

  • 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) – mode for grid_generation. Default: True

Return type:

Tensor

Returns:

the patches, with shape (B, C, d, h, w).

See also

kornia.geometry.transform.center_crop3d(tensor, size, interpolation='bilinear', align_corners=True)[source]#

Crop the central window of each volume to a given size.

patches = center_crop3d(tensor, size) takes volumes (B, C, D, H, W) and returns their central (B, C, d, h, w) windows for size = (d, h, w): with the default align_corners=True, a sub-volume of the input, with the extra voxel of an odd margin at the back/bottom/right. A size larger than the input pads with zeros. For images, use center_crop(); for a crop at any box, crop_and_resize3d().

Convention:
  • input: (B, C, D, H, W); size is (d, h, w)

  • align_corners: True by default

  • offset: the crop starts at the integer voxel int(D / 2 - d / 2) (likewise for the height and width), as in CenterCrop3D, so with the default align_corners=True the output is a sub-volume of the input. With an odd margin the extra voxel is left at the back/bottom/right. align_corners=False resamples off the voxel grid even for an even margin (see crop_and_resize3d(), #4503).

  • a size may have one-voxel axes (#4747)

Parameters:
  • tensor (Tensor) – the 3D volume tensor with shape (B, C, D, H, W).

  • size (Tuple[int, int, int]) – a tuple with the expected depth, height and width of the output patch.

  • interpolation (str, optional) – Interpolation flag. Default: "bilinear"

  • align_corners (bool, optional) – mode for grid_generation. Default: True

Return type:

Tensor

Returns:

the central windows, with shape (B, C, d, h, w).

See also

  • center_crop(): the central window of each image.

  • crop_and_resize3d(): a window at any box, resampled to a fixed size.

  • CenterCrop3D: the same windows as an augmentation, for augmentation pipelines; it raises for a size larger than the input instead of padding.

Examples

>>> input = torch.arange(64, dtype=torch.float32).view(1, 1, 4, 4, 4)
>>> input
tensor([[[[[ 0.,  1.,  2.,  3.],
           [ 4.,  5.,  6.,  7.],
           [ 8.,  9., 10., 11.],
           [12., 13., 14., 15.]],

          [[16., 17., 18., 19.],
           [20., 21., 22., 23.],
           [24., 25., 26., 27.],
           [28., 29., 30., 31.]],

          [[32., 33., 34., 35.],
           [36., 37., 38., 39.],
           [40., 41., 42., 43.],
           [44., 45., 46., 47.]],

          [[48., 49., 50., 51.],
           [52., 53., 54., 55.],
           [56., 57., 58., 59.],
           [60., 61., 62., 63.]]]]])
>>> center_crop3d(input, (2, 2, 2), align_corners=True)
tensor([[[[[21.0000, 22.0000],
           [25.0000, 26.0000]],

          [[37.0000, 38.0000],
           [41.0000, 42.0000]]]]])
kornia.geometry.transform.crop_and_resize3d(tensor, boxes, size, interpolation='bilinear', align_corners=False)[source]#

Crop an eight-corner box from each volume and resample it to a fixed output size.

patches = crop_and_resize3d(tensor, boxes, size) takes volumes (B, C, D, H, W) and boxes (B, 8, 3), one per volume or (1, 8, 3) for all of them, and returns the (B, C, d, h, w) patches for size = (d, h, w). Each box must be a parallelepiped, so that an affine map takes it onto the patch; with align_corners=True its corners land on the corner voxels of the patch. Pass align_corners=True, since the default False samples off the box (#4503). For images, use crop_and_resize(); to place the crop by a second box, crop_by_boxes3d().

Convention:
  • input: (B, C, D, H, W); size is (d, h, w)

  • boxes: (B, 8, 3) corner points in (x, y, z) order, front face then back face, each face top-left, top-right, bottom-right, bottom-left — same (x, y)/inclusive-pixel convention as crop_and_resize(), with z anchored at the top-left of the first depth slice (z = 0); reproducing the exact integer-voxel slice requires align_corners=True — the default False interpolates instead

  • align_corners: False by default

  • a single volume does not broadcast over a batch of boxes

  • a one-voxel axis of an axis-aligned box crops to a one-voxel axis of size; a one-voxel axis on only one of the two raises torch.linalg.LinAlgError (#4747)

Parameters:
  • tensor (Tensor) – the 3D volume tensor with shape (B, C, D, H, W).

  • boxes (Tensor) – a tensor with shape (B, 8, 3) containing the coordinates of the bounding boxes to be extracted, where each box is defined in the clockwise order: front-top-left, front-top-right, front-bottom-right, front-bottom-left, back-top-left, back-top-right, back-bottom-right, back-bottom-left. The coordinates must be in x, y, z order.

  • size (Tuple[int, int, int]) – a tuple with the depth, height and width that will be used to resize the extracted patches.

  • interpolation (str, optional) – Interpolation flag. Default: "bilinear"

  • align_corners (bool, optional) – mode for grid_generation. Default: False

Return type:

Tensor

Returns:

tensor containing the patches with shape (B, C, d, h, w).

Raises:

AssertionError – if a box has a non-finite coordinate, edges along one axis that span different extents on it, or is not a parallelepiped.

See also

  • crop_and_resize(): the same for images and (B, 4, 2) boxes, where align_corners changes only 'reflection' padding and, with mode='nearest', which pixel a sample exactly halfway takes.

  • crop_by_boxes3d(): maps the box onto a second box, whose size sets the output size.

  • center_crop3d(): the central window of each volume, with align_corners=True by default.

Example

>>> input = torch.arange(64, dtype=torch.float32).view(1, 1, 4, 4, 4)
>>> input
tensor([[[[[ 0.,  1.,  2.,  3.],
           [ 4.,  5.,  6.,  7.],
           [ 8.,  9., 10., 11.],
           [12., 13., 14., 15.]],

          [[16., 17., 18., 19.],
           [20., 21., 22., 23.],
           [24., 25., 26., 27.],
           [28., 29., 30., 31.]],

          [[32., 33., 34., 35.],
           [36., 37., 38., 39.],
           [40., 41., 42., 43.],
           [44., 45., 46., 47.]],

          [[48., 49., 50., 51.],
           [52., 53., 54., 55.],
           [56., 57., 58., 59.],
           [60., 61., 62., 63.]]]]])
>>> boxes = torch.tensor([[
...     [1., 1., 1.],
...     [3., 1., 1.],
...     [3., 3., 1.],
...     [1., 3., 1.],
...     [1., 1., 2.],
...     [3., 1., 2.],
...     [3., 3., 2.],
...     [1., 3., 2.],
... ]])  # 1x8x3
>>> crop_and_resize3d(input, boxes, (2, 2, 2), align_corners=True)
tensor([[[[[21.0000, 23.0000],
           [29.0000, 31.0000]],

          [[37.0000, 39.0000],
           [45.0000, 47.0000]]]]])

Modules#

The torch.nn.Module classes. Module forms that store their arguments: the 2D transforms (Rotate, Translate, Scale, Shear, Affine), the resizes (Resize, Rescale), the pyramid steps (PyrDown, PyrUp) and the centre crop (CenterCrop2D); module forms that take no arguments: the flips (Hflip, Vflip, Rot180). ScalePyramid builds scale-space octaves, HomographyWarper warps by a normalized homography, and BaseWarper is the interface for writing another warper.

class kornia.geometry.transform.Rotate(angle, center=None, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Rotate an image counter-clockwise by a stored angle in degrees (module form).

Build rotator = Rotate(angle), optionally with center, then out = rotator(input) rotates (C, H, W) or (B, C, H, W) images as rotate() does: counter-clockwise as displayed, about the image centre by default, at the input size. For volumes, use rotate3d(); to rotate, shift, scale and shear in one warp, Affine.

Convention:
Parameters:
  • angle (Tensor) – The angle through which to rotate. The tensor must have a shape of (B), where B is batch size.

  • center (Optional[Tensor], optional) – The center through which to rotate. The tensor must have a shape of (B, 2), where B is batch size and last dimension contains cx and cy. Default: None

  • 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

Returns:

The rotated tensor with the same shape as the input.

See also

  • rotate(): the one-call form.

  • Affine: a rotation with a translation, a scale and a shear in one warp.

  • Rot180: a half turn by flipping both axes, without interpolation.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> angle = torch.tensor([90.])
>>> out = Rotate(angle)(img)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
class kornia.geometry.transform.Translate(translation, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Shift an image by a stored translation in pixels (module form).

Build shifter = Translate(translation), then out = shifter(input) shifts (C, H, W) or (B, C, H, W) images by the (B, 2) translation (dx, dy) in pixels, as translate() does. To combine the shift with a rotation, a scale and a shear, use Affine.

Convention:
Parameters:
  • translation (Tensor) – tensor containing the amount of pixels to translate in the x and y direction. The tensor must have a shape of (B, 2), where B is batch size, last dimension contains dx dy.

  • 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

Returns:

The translated tensor with the same shape as the input, except that one image shifted by B > 1 translations returns (B, C, H, W).

See also

  • translate(): the one-call form.

  • Affine: a translation with a rotation, a scale and a shear in one warp.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> translation = torch.tensor([[1., 0.]])
>>> out = Translate(translation)(img)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
class kornia.geometry.transform.Scale(scale_factor, center=None, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Zoom an image about its centre by a stored scale factor, keeping its size (module form).

Build zoomer = Scale(scale_factor), optionally with center, then out = zoomer(input) scales the content of (C, H, W) or (B, C, H, W) images as scale() does, at the input size. To change the image size instead, use Rescale or Resize.

Convention:
  • See the convention block of scale().

Parameters:
  • scale_factor (Tensor) – The scale factor apply. The tensor must have a shape of (B) or (B, 2), where B is batch size. If (B), isotropic scaling will perform. If (B, 2), x-y-direction specific scaling will perform.

  • center (Optional[Tensor], optional) – The center through which to scale. The tensor must have a shape of (B, 2), where B is batch size and last dimension contains cx and cy. Default: None

  • 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

Returns:

The scaled tensor with the same shape as the input.

See also

  • scale(): the one-call form.

  • Rescale: change the image size by a factor instead.

  • Affine: a scale with a rotation, a translation and a shear in one warp.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> scale_factor = torch.tensor([[2., 2.]])
>>> out = Scale(scale_factor)(img)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
class kornia.geometry.transform.Shear(shear, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Shear an image by stored raw shear factors about pixel (0, 0) (module form).

Build shearer = Shear(shear), then out = shearer(input) shears (C, H, W) or (B, C, H, W) images by the (B, 2) raw factors (shx, shy), as shear() does, except that align_corners defaults to True here and to False in the function. For shear angles in radians about the image centre, use Affine, which shears by their negative tangent, so values below pi / 2 in magnitude shear the other way there.

Convention:
  • align_corners: True by default (differs from function shear(), whose default is False)

  • See the convention block of shear().

Parameters:
  • shear (Tensor) – tensor containing raw shear factors in the x and y direction about pixel (0, 0). The tensor must have a shape of (B, 2), where B is batch size, last dimension contains shx shy.

  • 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

Returns:

The skewed tensor with the same shape as the input, except that one image sheared by B > 1 pairs of factors returns (B, C, H, W).

See also

  • shear(): the one-call form, which defaults to align_corners=False.

  • Affine: shear angles in radians about the image centre, which shear the other way below pi / 2.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> shear_factor = torch.tensor([[0.5, 0.0]])
>>> out = Shear(shear_factor)(img)
>>> print(out.shape)
torch.Size([1, 3, 4, 4])
class kornia.geometry.transform.PyrDown(border_type='reflect', align_corners=False, factor=2.0)[source]#

Blur images with the 5x5 pyramid kernel and downsample them by a factor (module form).

Build down = PyrDown(), optionally with border_type, align_corners and factor, then out = down(input) blurs (B, C, H, W) images and resizes them to floor(H / factor) by floor(W / factor), as pyrdown() does. For the step up, use PyrUp; for every level at once, build_pyramid().

Convention:
Parameters:
  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

  • factor (float, optional) – the downsampling factor Default: 2.0

Returns:

the downsampled torch.Tensor.

Shape:
  • Input: (B, C, H, W)

  • Output: (B, C, H // 2, W // 2) at the default factor=2.0

See also

  • pyrdown(): the one-call form.

  • PyrUp: the module that goes one level up.

Examples

>>> input = torch.rand(1, 2, 4, 4)
>>> output = PyrDown()(input)  # 1x2x2x2
class kornia.geometry.transform.PyrUp(border_type='reflect', align_corners=False)[source]#

Upsample images to twice their size and blur them with the 5x5 pyramid kernel (module form).

Build up = PyrUp(), optionally with border_type and align_corners, then out = up(input) resizes (B, C, H, W) images to (B, C, H * 2, W * 2) and blurs them, as pyrup() does. For the step down, use PyrDown.

Convention:
  • See the convention block of pyrup().

Parameters:
  • border_type (str, optional) – the padding mode to be applied before convolving. The expected modes are: 'constant', 'reflect', 'replicate' or 'circular'. Default: "reflect"

  • align_corners (bool, optional) – interpolation flag. Default: False

Returns:

the upsampled torch.Tensor.

Shape:
  • Input: (B, C, H, W)

  • Output: (B, C, H * 2, W * 2)

See also

  • pyrup(): the one-call form.

  • PyrDown: the module that goes one level down.

Examples

>>> input = torch.rand(1, 2, 4, 4)
>>> output = PyrUp()(input)  # 1x2x8x8
class kornia.geometry.transform.ScalePyramid(n_levels=3, init_sigma=1.6, min_size=15, double_image=False, extra_levels=3)[source]#

Build octaves of progressively blurred images, with their sigmas, for scale-space detection.

Build sp = ScalePyramid(n_levels, init_sigma, min_size), then pyr, sigmas, pixel_dists = sp(input) takes (B, C, H, W) images and returns three lists with one entry per octave. pyr[o] stacks L = n_levels + extra_levels levels as (B, C, L, H_o, W_o), each blurred 2 ** (1 / n_levels) times more than the previous, and sigmas[o] and pixel_dists[o] are (B, L). Each octave after the first starts from level n_levels of the previous one, resized to half its size, and octaves are added while that halved size stays above min_size on its shorter side. It is the pyramid ScaleSpaceDetector searches; for a plain list of halved images, use build_pyramid().

Convention:
  • input: (B, C, H, W)

  • forward returns (pyr, sigmas, pixel_dists), one entry per octave: pyr[o] is (B, C, L, H_o, W_o) with L = n_levels + extra_levels, and sigmas[o] and pixel_dists[o] are (B, L) nominal values (the targeted blur, not a measurement)

  • sigmas is octave-relative: the blur in input pixels is sigmas[o] * pixel_dists[o]

  • an init_sigma below the assumed input blur (0.5, or 1.0 with double_image=True) leaves the first level at that blur, and the octave is built and labelled from it, as if init_sigma were the assumed input blur

  • the internal resizes use align_corners=True; there is no align_corners parameter. They keep the first and last pixel centres, so pixel \((u, v)\) of octave o is input pixel \((u (W - 1) / (W_o - 1), v (H - 1) / (H_o - 1))\); pixel_dists is the nominal spacing \(2^o\) (\(2^{o - 1}\) with double_image=True), not this map

Parameters:
  • n_levels (int, optional) – number of levels per octave over which the blur doubles, a positive integer (a NumPy integer or integer tensor is converted to int). Each level is blurred 2 ** (1 / n_levels) times more than the one before. Default: 3

  • init_sigma (float, optional) – initial blur level. Default: 1.6

  • min_size (int, optional) – the minimum size of the octave in pixels, a non-negative number: an octave after the first is built only when its shorter side is larger than min_size, so 0 halves the image down to one pixel. Default: 15

  • double_image (bool, optional) – add 2x upscaled image as 1st level of pyramid. OpenCV SIFT does this. Default: False

  • extra_levels (int, optional) – number of levels per octave beyond n_levels, a positive integer (a NumPy integer or integer tensor is converted to int); the default 3 is what DoG non-maximum suppression needs. Level n_levels, blurred to twice the first level’s sigma, seeds the next octave, so 1 is the least that works. Default: 3

Returns:

images, the levels of each octave. 2nd output: sigmas, the nominal blur of each level in the octave’s own pixels. 3rd output: pixel_dists, the nominal pixel spacing of each level relative to the input.

Return type:

1st output

Raises:

ValueCheckError – if n_levels or extra_levels is not a positive integer, or min_size is negative or NaN. Raised even when the KORNIA_CHECK helpers are disabled, because forward could not build the pyramid.

Shape:
  • Input: (B, C, H, W)

  • Output 1st: [(B, C, L, H, W), (B, C, L, H // 2, W // 2), ...], starting from (B, C, L, H * 2, W * 2) with double_image=True

  • Output 2nd: [(B, L), (B, L), (B, L), ...]

  • Output 3rd: [(B, L), (B, L), (B, L), ...]

See also

Examples

>>> input = torch.rand(2, 4, 100, 100)
>>> sp, sigmas, pds = ScalePyramid(3, 15)(input)
class kornia.geometry.transform.Hflip(*args, **kwargs)[source]#

Mirror images left to right by reversing the width axis (module form).

Build flipper = Hflip(), which takes no arguments, then out = flipper(input) reverses the columns of (*, W) tensors as hflip() does. To flip top to bottom, use Vflip; for a half turn, Rot180.

Convention:
  • See the convention block of hflip().

Returns:

The horizontally flipped image torch.Tensor, with the shape of the input.

See also

Examples

>>> hflip = Hflip()
>>> input = torch.tensor([[[
...    [0., 0., 0.],
...    [0., 0., 0.],
...    [0., 1., 1.]
... ]]])
>>> hflip(input)
tensor([[[[0., 0., 0.],
          [0., 0., 0.],
          [1., 1., 0.]]]])
class kornia.geometry.transform.Vflip(*args, **kwargs)[source]#

Flip images top to bottom by reversing the height axis (module form).

Build flipper = Vflip(), which takes no arguments, then out = flipper(input) reverses the rows of (*, H, W) tensors as vflip() does. To mirror left to right, use Hflip; for a half turn, Rot180.

Convention:
  • See the convention block of vflip().

Returns:

The vertically flipped image torch.Tensor, with the shape of the input.

See also

Examples

>>> vflip = Vflip()
>>> input = torch.tensor([[[
...    [0., 0., 0.],
...    [0., 0., 0.],
...    [0., 1., 1.]
... ]]])
>>> vflip(input)
tensor([[[[0., 1., 1.],
          [0., 0., 0.],
          [0., 0., 0.]]]])
class kornia.geometry.transform.Rot180(*args, **kwargs)[source]#

Turn images by 180 degrees by reversing the height and width axes (module form).

Build rotator = Rot180(), which takes no arguments, then out = rotator(input) reverses both the rows and the columns of (*, H, W) tensors as rot180() does, without interpolation. To rotate by a stored angle, use Rotate.

Convention:
Returns:

The rotated image torch.Tensor, with the shape of the input.

See also

  • rot180(): the one-call form.

  • Rotate: rotates by any stored angle, with interpolation.

Examples

>>> rot180 = Rot180()
>>> input = torch.tensor([[[
...    [0., 0., 0.],
...    [0., 0., 0.],
...    [0., 1., 1.]
... ]]])
>>> rot180(input)
tensor([[[[1., 1., 0.],
          [0., 0., 0.],
          [0., 0., 0.]]]])
class kornia.geometry.transform.Resize(size, interpolation='bilinear', align_corners=None, side='short', antialias=False)[source]#

Resize an image to a given size, or one side to a given length (module form).

Build resizer = Resize(size) with the arguments of resize(), then out = resizer(input) resizes (*, H, W) tensors exactly as resize(input, size, ...) does. For a factor instead of a size, use Rescale; inside an augmentation pipeline, use Resize.

Convention:

See Conventions & Pitfalls for sampling and align_corners conventions. When resizing camera images, see camera and world conventions for matching intrinsics scaling.

Parameters:
  • size (Union[int, Tuple[int, int]]) – Desired output size. If size is a sequence like (h, w), output size will be matched to this. If size is an int, the side that side names will be matched to this number; with the default side='short', if height > width, the image will be rescaled to (size * height / width, size)

  • interpolation (str, optional) – algorithm used for upsampling: 'nearest' | 'nearest-exact' | 'bilinear' | 'bicubic' | 'area'. Default: "bilinear"

  • align_corners (Optional[bool], optional) – interpolation flag. Default: None

  • side (str, optional) – Corresponding side if size is an integer. Can be one of 'short', 'long', 'vert', or 'horz'. Default: "short"

  • antialias (bool, optional) – if True, then image will be filtered with Gaussian before downscaling. No effect for upscaling. Default: False

Returns:

The resized tensor with the shape of the given size.

See also

  • resize(): the one-call form.

  • Rescale: the module form of rescale(), a factor instead of a size.

  • Resize: the augmentation of the same name, for augmentation pipelines.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> out = Resize((6, 8))(img)
>>> print(out.shape)
torch.Size([1, 3, 6, 8])
class kornia.geometry.transform.Rescale(factor, interpolation='bilinear', align_corners=True, antialias=False)[source]#

Resize an image by a stored scale factor per side, given height first (module form).

Build rescaler = Rescale(factor), then out = rescaler(input) resizes (*, H, W) tensors as rescale() does, except that align_corners defaults to True here and to None in the function. For a size instead of a factor, use Resize.

Convention:
  • align_corners: True by default (differs from function rescale(), whose default is None). It applies to the 'bilinear' and 'bicubic' modes only. 'nearest', 'nearest-exact' and 'area' ignore it, an explicit align_corners=True included, because torch.nn.functional.interpolate accepts no value but None for them; the function rescale() raises ValueError for such a call.

  • See the convention block of rescale().

Parameters:
  • factor (Union[float, Tuple[float, float]]) – Desired scaling factor as (factor_h, factor_w) — height first. If a single float, the value is used for both height and width (an int raises TypeError).

  • interpolation (str, optional) – algorithm used for upsampling: 'nearest' | 'nearest-exact' | 'bilinear' | 'bicubic' | 'area'. Default: "bilinear"

  • align_corners (bool, optional) – interpolation flag. Default: True

  • antialias (bool, optional) – if True, then image will be filtered with Gaussian before downscaling. No effect for upscaling. Default: False

Returns:

The rescaled tensor with the shape according to the given factor.

See also

  • rescale(): the one-call form, whose align_corners defaults to None.

  • Resize: the output size instead of a factor.

  • Scale: zoom the content by a factor and keep the size.

  • Rescale: multiplies the values by a factor instead of resizing.

Example

>>> img = torch.rand(1, 3, 4, 4)
>>> out = Rescale((2, 3))(img)
>>> print(out.shape)
torch.Size([1, 3, 8, 12])
class kornia.geometry.transform.Affine(angle=None, translation=None, scale_factor=None, shear=None, center=None, mode='bilinear', padding_mode='zeros', align_corners=True)[source]#

Warp an image by a rotation, a scale and a shear about a centre, then a translation (module form).

Build warper = Affine(angle, translation, scale_factor, shear, center) with at least one of the first four, then out = warper(input) warps (B, C, H, W) images, or one (C, H, W) image, by the matrix of get_affine_matrix2d(): a shear, a scale, a counter-clockwise rotation in degrees and a translation in pixels, the first three about center (by default the image centre). The parameters, and center when given, share one batch size P. P and the input batch must be equal, or one of them 1, a (C, H, W) input counting as 1: one parameter set warps every image, and P sets warp one image. For a matrix you already have, use affine(); for one kind of warp, Rotate, Translate, Scale or Shear.

Convention:
  • shear contains angles in radians, using the negative-tangent, x-then-y convention of get_shear_matrix2d() about center (by default ((W - 1) / 2, (H - 1) / 2)).

  • Known defect: shear() and Shear read their shear as raw factors about pixel (0, 0), without the negative tangent, so the same tensor shears the other way there while its values stay below pi / 2 in magnitude (#5661).

  • align_corners defaults to True. See the convention block of affine().

Parameters:
  • angle (Optional[Tensor], optional) – Angle in degrees for counter-clockwise rotation around the center. The tensor must have a shape of (B), where B is the batch size. Default: None

  • translation (Optional[Tensor], optional) – Amount of pixels for translation in x- and y-direction. The tensor must have a shape of (B, 2), where B is the batch size and the last dimension contains dx and dy. Default: None

  • scale_factor (Optional[Tensor], optional) – Factor for scaling. The tensor must have a shape of (B,2), where B is the batch size and the last dimension contains scale factors for x and y direction. Default: None

  • shear (Optional[Tensor], optional) – Angles in radians for shearing in x- and y-direction around the center. The tensor must have a shape of (B, 2), where B is the batch size and the last dimension contains sx and sy. Default: None

  • center (Optional[Tensor], optional) – Transformation center in pixels. The tensor must have a shape of (B, 2), where B is the batch size and the last dimension contains cx and cy. Defaults to the center of image to be transformed. Default: None

  • 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

Raises:
  • RuntimeError – At construction, if not one of angle, translation, scale_factor, or shear is set, or if their batch sizes differ.

  • DeviceError – If angle, translation, scale_factor and shear are not all on one device.

  • TypeCheckError – If they are on one device but do not all have one dtype. The ones not given are created on that device and in that dtype.

  • ValueError – At the call, if center and the parameters have different batch sizes (construction does not check center), or if the parameter batch and the input batch differ and neither is 1, a (C, H, W) input counting as 1.

Returns:

The transformed tensor with same shape as input, except that one image warped by P > 1 parameter sets returns (P, C, H, W).

See also

  • get_affine_matrix2d(): the (B, 3, 3) matrix this module warps by, whose own angle turns clockwise (#4408).

  • affine(): warp by an affine matrix you already have.

  • Rotate: a rotation alone.

  • Shear: raw shear factors about pixel (0, 0), which shear the other way below pi / 2.

Example

>>> img = torch.rand(1, 2, 3, 5)
>>> angle = 90. * torch.rand(1)
>>> out = Affine(angle)(img)
>>> print(out.shape)
torch.Size([1, 2, 3, 5])
class kornia.geometry.transform.BaseWarper(height, width, *args, **kwargs)[source]#

Declare the interface of a homography warper module that ImageRegistrator can call.

BaseWarper(height, width) only stores the destination height and width. A subclass implements warper(patch_src, src_homo_dst), which samples a (B, C, H, W) source on that destination grid by a (B, 3, 3) destination→source homography, and precompute_warp_grid(src_homo_dst), which caches the grid. ImageRegistrator takes such a class as warper and calls it as warper(height, width). Both methods are abstract: constructing BaseWarper itself, or a subclass that does not implement both, raises TypeError. To warp images, use HomographyWarper.

Convention:
  • subclasses receive src_homo_dst as the destination→source homography

See also

  • HomographyWarper: the implementation kornia ships, in normalized or pixel coordinates.

  • ImageRegistrator: registers two images by optimizing a transform, and warps with a warper class of this interface.

class kornia.geometry.transform.HomographyWarper(height, width, mode='bilinear', padding_mode='zeros', normalized_coordinates=True, align_corners=False)[source]#

Warp images to a fixed size by a normalized destination→source homography (module form).

Build warper = HomographyWarper(height, width), then out = warper(patch_src, src_homo_dst) warps (N, C, H, W) images by (N, 3, 3) destination→source homographies in normalized \([-1, 1]\) coordinates and returns (N, C, height, width), as homography_warp() with dsize=(height, width) does. To reuse one homography, call warper.precompute_warp_grid(src_homo_dst) once and then warper(patch_src); a homography passed to the call takes precedence over the cached grid, and a call with neither raises RuntimeError. For a source→destination homography in pixel coordinates, as RANSAC and find_homography_dlt() return it, use warp_perspective(). This class has no normalized_homography switch: normalized_coordinates=False still reads a destination→source homography, in pixels.

\[X_{src} = H_{src}^{\{dst\}} * X_{dst}\]
Convention:

See Conventions & Pitfalls for homography direction, normalized coordinates and sampling conventions.

  • See the convention block of homography_warp().

  • with normalized_coordinates=False a grid from precompute_warp_grid holds source pixel coordinates computed as in homography_warp() (in at least float32, unaffected by autocast), normalized at sampling time with the size of the patch passed to forward and then cast to the homography’s dtype

Parameters:
  • height (int) – The height of the destination torch.Tensor.

  • width (int) – The width of the destination torch.Tensor.

  • 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"

  • normalized_coordinates (bool, optional) – whether the homographies are in normalized \([-1, 1]\) coordinates (True) or in pixel coordinates (False), as in homography_warp(). Default: True

  • align_corners (bool, optional) – interpolation flag. Default: False

See also

class kornia.geometry.transform.CenterCrop2D(size, align_corners=True, resample=Resample.BILINEAR.name, cropping_mode='slice')[source]#

Crop the central window of each image to a given size, by slicing or resampling (module form).

Build cropper = CenterCrop2D(size) with an int or an (h, w) tuple, then out = cropper(input) returns the central (B, C, h, w) windows of (B, C, H, W) images, at the offsets of center_crop(). The default cropping_mode='slice' slices with integer indices, through crop_by_indices(), or after zero-padding when size exceeds the input on an axis; 'resample' samples the same windows, up to float rounding, by a translation through warp_affine() with the resample mode. For one call, use center_crop(); in an augmentation pipeline, CenterCrop.

Convention:
  • align_corners (and resample) only take effect when cropping_mode='resample'; the default cropping_mode='slice' performs integer-index slicing and ignores both

  • See the convention block of center_crop().

Parameters:
  • size (Union[int, Tuple[int, int]]) – Size (h, w) in pixels of the cropped region, or one int for both sides; a list raises TypeError.

  • align_corners (bool, optional) – interpolation flag. Default: True

  • resample (Union[str, int, Resample], optional) – Resampling mode. Default: Resample.BILINEAR.name

  • cropping_mode (str, optional) – Cropping mode, “resample” or “slice”. Default: "slice"

Note

torch.jit.script compiles neither cropping mode, and torch.jit.trace records the crop offsets of the traced input size.

See also

  • center_crop(): the one-call form, which always resamples.

  • crop_by_indices(): the integer slicing of the default mode, for any axis-aligned box.

  • CenterCrop: the same windows as an augmentation, for augmentation pipelines; it raises for a size larger than the input instead of padding.

Image registration#

Image registration with the ImageRegistrator module

See also the image registration application page.

Register two images by optimizing a homography or a similarity by gradient descent, coarse to fine.

ImageRegistrator takes a pair of (1, C, H, W) images, builds a Gaussian pyramid of each with build_pyramid() and, from the coarsest level to the finest, optimizes a transform model on the loss of each image warped onto the other. The built-in models return a (1, 3, 3) destination→source matrix in normalized \([-1, 1]\) coordinates (align_corners=False): the src_homo_dst of homography_warp() and HomographyWarper.

Which class to use:

  • Register two images: ImageRegistrator, with model_type 'homography', 'similarity', 'translation', 'rotation' or 'scale'.

  • The models it optimizes: Homography (a full homography) and Similarity (a rotation, a scale and a shift, each one optional). A custom model subclasses BaseModel and comes with a warper class, such as a subclass of BaseWarper.

  • To estimate a homography from matched keypoints rather than from pixel values, use RANSAC or find_homography_dlt().

class kornia.geometry.transform.image_registrator.BaseModel(*args, **kwargs)[source]#

Declare the interface of a transform model that ImageRegistrator optimizes.

A subclass holds its transform parameters as Parameter and implements reset_model(), which returns them to the identity, forward(), the matrix with which its warper warps the source image into the destination, and forward_inverse(), the matrix of the reverse warp. ImageRegistrator takes an instance as model_type, together with a warper class. The three methods are abstract: constructing BaseModel itself, or a subclass that does not implement all three, raises TypeError, as for BaseWarper. For the built-in models, use Homography or Similarity.

See also

abstractmethod forward()[source]#

Return the transform used to warp the source image into the destination image.

The built-in models map destination coordinates to source coordinates. A custom model’s coordinates must match its supplied warper; see ImageRegistrator.

Return type:

Tensor

Returns:

Transform tensor for the current model state, in the shape required by the warper.

abstractmethod forward_inverse()[source]#

Return the transform used to warp the destination image into the source image.

Return type:

Tensor

Returns:

Transform tensor for the inverse warp, in the coordinates expected by the warper.

abstractmethod reset_model()[source]#

Reset learnable registration parameters to the identity transform.

Return type:

None

class kornia.geometry.transform.image_registrator.Homography[source]#

Hold a learnable 3x3 homography for ImageRegistrator, starting from the identity.

model = Homography() holds one (3, 3) Parameter, initialized to the identity. model() returns it as a (1, 3, 3) matrix scaled so that its [2, 2] entry is 1, and model.forward_inverse() its inverse, up to scale. ImageRegistrator('homography') optimizes it as the destination→source homography in normalized coordinates. For a rotation, a scale and a shift only, use Similarity.

See also

  • Similarity: four degrees of freedom instead of eight, each of rotation, scale and shift optional.

  • ImageRegistrator: optimizes this model with model_type='homography'.

forward()[source]#

Single-batch homography, scaled so that its [2, 2] entry is 1.

Return type:

Tensor

Returns:

Homography matrix with shape (1, 3, 3).

forward_inverse()[source]#

Inverted single-batch homography.

Return type:

Tensor

Returns:

Homography matrix with shape (1, 3, 3).

reset_model()[source]#

Initialize the model with identity transform.

Return type:

None

class kornia.geometry.transform.image_registrator.ImageRegistrator(model_type='homography', optimizer=optim.Adam, loss_fn=F.l1_loss, pyramid_levels=5, lr=1e-3, num_iterations=100, tolerance=1e-4, warper=None, allow_shape_mismatch=False)[source]#

Register two images by optimizing a transform model on their Gaussian pyramids, coarse to fine.

Build registrator = ImageRegistrator(model_type), then M = registrator.register(src_img, dst_img) takes two (1, C, H, W) images (the built-in models hold one transform, and a larger batch raises). From the coarsest of pyramid_levels Gaussian levels to the finest, it runs up to num_iterations steps of optimizer on the masked loss of src_img warped onto dst_img plus dst_img warped back onto src_img, and returns the model’s matrix, (1, 3, 3) for the built-in models (with the matrix after each level as well, when output_intermediate_models=True); warp_src_into_dst() then warps an image by it. With more than one level, both sides need at least 2 ** (pyramid_levels - 1) pixels, 16 for the default 5. To align images from matched keypoints instead, use RANSAC.

Convention:
  • register() returns self.model() unchanged. For the built-in string model_type values, this maps destination coordinates to source coordinates, normalized to \([-1, 1]\) with align_corners=False: the src_homo_dst argument of homography_warp(). warp_src_into_dst() uses this model, and warp_dst_into_src() uses self.model.forward_inverse(). A custom model_type and warper determine their own coordinate system; their forward and inverse mappings must agree with that warper.

  • For the built-in models, denormalize_homography(M, (H, W), (H, W), align_corners=False) converts the returned M to pixels: content that moves by \((t_x, t_y)\) pixels from src_img to dst_img gives a shift of \((-t_x, -t_y)\).

  • register() always starts from the identity, so a loaded state_dict drives the warps but is not a warm start.

  • A float16/bfloat16 model or image is optimized in float32: during register() both images, also when allow_shape_mismatch resizes src_img, and the model’s half parameters and buffers are float32, and afterwards those tensors and their gradients return to their own dtype, also when register() raises. Adam’s second-moment estimate 0.001 * g**2 and its eps of 1e-8 are both 0 in float16 once |g| < 0.0055, so a float16 optimization divides by zero and ends in NaN, and bfloat16 steps round to the dtype’s coarse spacing. For a half model the intermediate models of output_intermediate_models are computed in float32 and rounded to the model’s dtype, so the last one can differ by an ulp from the returned self.model(), which is computed in the model’s dtype.

  • A float16, bfloat16 or float32 model therefore registers images of any of these dtypes. warp_src_into_dst() and warp_dst_into_src() sample a model and an image of two different ones of them in float32 too and return the image’s dtype; a model and an image of the same dtype go to the warper unchanged, as before.

Parameters:
  • model_type (Union[str, BaseModel], optional) – Geometrical model for registration: 'homography', 'similarity', or 'translation', 'rotation' or 'scale' (a Similarity that optimizes only that parameter), or a BaseModel instance together with warper. Default: "homography"

  • optimizer (Type[Optimizer], optional) – optimizer class used for the optimization. Default: optim.Adam

  • loss_fn (Callable[..., Tensor], optional) – torch loss function, called with reduction='none'. Default: F.l1_loss

  • pyramid_levels (int, optional) – number of scale pyramid levels. Default: 5

  • lr (float, optional) – learning rate for optimization. Default: 1e-3

  • num_iterations (int, optional) – maximum number of iterations at each pyramid level, from coarse to fine. Default: 100

  • tolerance (float, optional) – stop a pyramid level when successive losses at that level differ by less than this value. The first iteration at each level always runs. Default 1e-4. Default: 1e-4

  • warper (Optional[Type[BaseWarper]], optional) – the warper class, called as warper(height, width). Required when model_type is a module; a string model_type uses HomographyWarper. Default: None

  • allow_shape_mismatch (bool, optional) – if True, register() resizes src_img bilinearly to the height and width of dst_img, and a different batch or channel size still raises ValueError; if False, images of different shapes raise ValueError. Default: False

See also

  • Homography: the model of model_type='homography'.

  • Similarity: the model of the other string model_type values.

  • HomographyWarper: the warper of the built-in models.

  • RANSAC: a homography from matched keypoints, robust to outliers.

Example

>>> from kornia.geometry import ImageRegistrator
>>> img_src = torch.rand(1, 1, 32, 32)
>>> img_dst = torch.rand(1, 1, 32, 32)
>>> registrator = ImageRegistrator('similarity')
>>> homo = registrator.register(img_src, img_dst)
get_single_level_loss(img_src, img_dst, transform_model)[source]#

Warp img_src into img_dst with transform_model and returns loss.

Return type:

Tensor

register(src_img, dst_img, verbose=False, output_intermediate_models=False)[source]#

Estimate the transformation which warps src_img into dst_img by gradient descent.

Parameters:
  • src_img (Tensor) – Input image torch.Tensor.

  • dst_img (Tensor) – Input image torch.Tensor.

  • verbose (bool, optional) – if True, outputs loss every 10 iterations. Default: False

  • output_intermediate_models (bool, optional) – if True with intermediate models Default: False

Return type:

Union[Tensor, Tuple[Tensor, List[Tensor]]]

Returns:

the transformation between two images, shape depends on the model, typically [1x3x3] torch.Tensor for string model_types.

reset_model()[source]#

Call model reset function.

Return type:

None

warp_dst_inro_src(dst_img)[source]#

Deprecated alias for warp_dst_into_src().

Return type:

Tensor

warp_dst_into_src(dst_img)[source]#

Warp dst_img with inverted estimated model.

Return type:

Tensor

warp_src_into_dst(src_img)[source]#

Warp src_img with estimated model.

Return type:

Tensor

class kornia.geometry.transform.image_registrator.Similarity(rotation=True, scale=True, shift=True)[source]#

Hold a learnable rotation, scale and shift for ImageRegistrator, each one optional.

model = Similarity(rotation, scale, shift) holds an angle rot in degrees, a scale and a (1, 2, 1) shift in normalized units, each a Parameter when its flag is True and otherwise a constant buffer (0, 1 and 0). model() returns the (1, 3, 3) matrix described below and model.forward_inverse() its inverse. ImageRegistrator uses it for 'similarity' (all three), 'translation' (the shift), 'rotation' and 'scale'. For a full homography, use Homography.

Convention:
  • forward() is [[scale * R, shift], [0, 0, 1]] in the normalized \([-1, 1]\) coordinates of ImageRegistrator (align_corners=False), where R comes from angle_to_rotation_matrix() of rot in degrees.

  • After set_image_shape() with the image height H and width W, R is diag(H / W, 1) @ angle_to_rotation_matrix(rot) @ diag(W / H, 1). The normalized frame scales x by 2 / W and y by 2 / H, so in pixels the linear part is then scale * angle_to_rotation_matrix(rot) about the image centre, for any aspect ratio. ImageRegistrator.register() sets the shape of dst_img. shift stays in normalized units.

  • Without an image shape, R is angle_to_rotation_matrix(rot), which rotates the pixels only on a square image. The shape is not part of state_dict(): after load_state_dict, call set_image_shape() again before using the model on a non-square image.

Parameters:
  • rotation (bool, optional) – if True, the rotation is optimizable, else constant zero. Default: True

  • scale (bool, optional) – if True, the scale is optimizable, else constant one. Default: True

  • shift (bool, optional) – if True, the shift is optimizable, else constant zero. Default: True

See also

  • Homography: a full homography, eight degrees of freedom.

  • ImageRegistrator: optimizes this model for every model_type but 'homography'.

forward()[source]#

Single-batch similarity transform.

Return type:

Tensor

Returns:

Similarity with shape (1, 3, 3)

forward_inverse()[source]#

Single-batch inverse similarity transform.

Return type:

Tensor

Returns:

Similarity with shape (1, 3, 3)

reset_model()[source]#

Initialize the model with identity transform.

Return type:

None

set_image_shape(height, width)[source]#

Set the image size in pixels, which makes rot and scale a rotation and scaling of the pixels.

Parameters:
  • height (int) – image height H.

  • width (int) – image width W.

Return type:

None