Equalization and histograms#

image_histogram2d() preserves leading batch and channel axes and reduces the final two spatial axes. The KDE helpers histogram() and histogram2d() share one bin-center grid across the batch.

Equalization#

kornia.enhance.equalize(input)[source]#

Apply equalize on the input torch.Tensor.

Convention:

Equalizes each channel of each image independently over [0, 1]. equalize3d() applies the corresponding operation to volumes. Empty leading dimensions are supported; channels and spatial dimensions must be non-empty.

_images/equalize.png

Implements Equalize function from PIL using PyTorch ops based on uint8 format: tensorflow/tpu

Parameters:

input (Tensor) – image torch.Tensor to equalize with shape \((*, C, H, W)\).

Return type:

Tensor

Returns:

Equalized image torch.Tensor with shape \((*, C, H, W)\).

Note

The input is expected in \([0, 1]\), and each channel is equalized from a 256-bin histogram. Values the 256-bin lookup cannot index (outside roughly \([0, 1]\)) raise a RuntimeError naming the range. The check is torch._assert_async, which has an MPS kernel from torch 2.13; on an older MPS release the condition is read on the host instead, one device sync per call, and is skipped there under torch.compile.

Example

>>> x = torch.rand(1, 2, 3, 3)
>>> equalize(x).shape
torch.Size([1, 2, 3, 3])
kornia.enhance.equalize_clahe(input, clip_limit=40.0, grid_size=(8, 8), slow_and_differentiable=False)[source]#

Apply clahe equalization on the input tensor.

Convention:

Expects values in [0, 1], splits the final two axes into grid_size[0] tiles along H and grid_size[1] tiles along W, and returns the input shape. See equalize() for global equalization.

_images/equalize_clahe.png

NOTE: The fast path uses OpenCV-style LUT calculation and round-to-nearest quantization. Tiles are ceil(H / grid_size[0]) by ceil(W / grid_size[1]) pixels, odd or even, and the image is reflect-padded at its end only along an axis the grid does not divide. OpenCV uses the same tiles when the grid divides both axes or neither. When it divides only one, OpenCV pads that axis too, by one pixel per tile; Kornia tiles each axis on its own and does not. Both paths blend LUTs with weight steps of 1 / tile_size, anchored at each tile’s actual centre, with border LUTs clamped. This is half a pixel before OpenCV/scikit-image’s historical phase: Kornia intentionally uses (p + 0.5) / tile_size - 0.5 to preserve flip symmetry on unpadded grids. For the same tiles and LUTs, the phase difference is at most half an interpolation step per axis; exact cv2.createCLAHE parity is not the contract, and output values are not rounded to 8-bit integers.

Parameters:
  • input (Tensor) – images tensor to equalize with values in the range [0, 1] and shape \((*, C, H, W)\).

  • clip_limit (float, optional) – threshold value for contrast limiting. If 0 clipping is disabled. Default: 40.0

  • grid_size (Tuple[int, int], optional) – number of tiles to be cropped in each direction (GH, GW). Each image axis must be larger than its grid size; otherwise a ValueError names the smallest image the grid admits. Default: (8, 8)

  • slow_and_differentiable (bool, optional) – flag to select implementation Default: False

Return type:

Tensor

Returns:

Equalized image or images with shape as the input.

Examples

>>> img = torch.rand(1, 10, 20)
>>> res = equalize_clahe(img)
>>> res.shape
torch.Size([1, 10, 20])
>>> img = torch.rand(2, 3, 10, 20)
>>> res = equalize_clahe(img)
>>> res.shape
torch.Size([2, 3, 10, 20])

Note

The input is expected in \([0, 1]\); each tile is equalized from a 256-bin lookup table. Values the lookup cannot index (outside roughly \([0, 1]\)) raise a RuntimeError naming the range. The check is torch._assert_async, which has an MPS kernel from torch 2.13; on an older MPS release the condition is read on the host instead, one device sync per call, and is skipped there under torch.compile, as for kornia.enhance.equalize().

kornia.enhance.equalize3d(input)[source]#

Equalize the values for a 3D volumetric torch.Tensor.

Convention:

Equalizes each channel of each volume independently over [0, 1]; see equalize() for the image variant and equalize_clahe() for local tiling. Empty leading dimensions are supported; channels and spatial dimensions must be non-empty.

Implements Equalize function for a sequence of images using PyTorch ops based on uint8 format: tensorflow/tpu

Parameters:

input (Tensor) – image torch.Tensor with shape \((*, C, D, H, W)\) to equalize.

Return type:

Tensor

Returns:

Equalized volume with the same shape as the input.

Note

The input is expected in \([0, 1]\), and each channel’s whole \((D, H, W)\) volume is equalized from one 256-bin histogram. The lookup step is an integer division by 255, so a volume with no more than 255 voxels per channel is returned unchanged up to floating-point roundoff; just above that, whether it changes depends on the values. Values the 256-bin lookup cannot index (outside roughly \([0, 1]\)) raise a RuntimeError naming the range. The check is torch._assert_async, which has an MPS kernel from torch 2.13; on an older MPS release the condition is read on the host instead, one device sync per call, and is skipped there under torch.compile.

Histograms#

kornia.enhance.histogram(x, bins, bandwidth, epsilon=1e-10)[source]#

Estimate the histogram of the input torch.Tensor.

Convention:

Rows are independent samples: x has shape (B, D), bins is the shared one-dimensional center grid, and the result has shape (B, N_bins). histogram2d uses the same batch convention for a joint density. bandwidth must be finite and positive; the check runs on CPU and CUDA via torch._assert_async and raises RuntimeError. kornia skips it on MPS by design, so invalid values do not raise there.

The calculation uses kernel density estimation which requires a bandwidth (smoothing) parameter.

Parameters:
  • x (Tensor) – Input torch.Tensor to compute the histogram with shape \((B, D)\).

  • bins (Tensor) – The bin centers, with shape \((N_{bins})\).

  • bandwidth (Tensor) – Gaussian smoothing factor with shape shape [1].

  • epsilon (float, optional) – A scalar, for numerical stability. Default: 1e-10

Return type:

Tensor

Returns:

Computed histogram of shape \((B, N_{bins})\).

Examples

>>> x = torch.rand(1, 10)
>>> bins = torch.torch.linspace(0, 255, 128)
>>> hist = histogram(x, bins, bandwidth=torch.tensor(0.9))
>>> hist.shape
torch.Size([1, 128])
kornia.enhance.histogram2d(x1, x2, bins, bandwidth, epsilon=1e-10)[source]#

Estimate the 2d histogram of the input torch.Tensor.

Convention:

x1 and x2 supply one sample row per batch element and return (B, N_bins, N_bins), where the first bin axis belongs to x1.

The calculation uses kernel density estimation which requires a bandwidth (smoothing) parameter.

Parameters:
  • x1 (Tensor) – Input torch.Tensor to compute the histogram with shape \((B, D)\).

  • x2 (Tensor) – Input torch.Tensor to compute the histogram with shape \((B, D)\).

  • bins (Tensor) – The bin centers, with shape \((N_{bins})\).

  • bandwidth (Tensor) – Gaussian smoothing factor with shape shape [1].

  • epsilon (float, optional) – A scalar, for numerical stability. Default: 1e-10.

Return type:

Tensor

Returns:

Computed histogram of shape \((B, N_{bins}), N_{bins})\).

Examples

>>> x1 = torch.rand(2, 32)
>>> x2 = torch.rand(2, 32)
>>> bins = torch.torch.linspace(0, 255, 128)
>>> hist = histogram2d(x1, x2, bins, bandwidth=torch.tensor(0.9))
>>> hist.shape
torch.Size([2, 128, 128])
kornia.enhance.image_histogram2d(image, min=0.0, max=255.0, n_bins=256, bandwidth=None, centers=None, return_pdf=False, kernel='triangular', eps=1e-10)[source]#

Estimate the histogram of the input image(s).

Convention:

Spatial axes are the final two axes; input (H, W), (C, H, W), and (B, C, H, W) return matching leading axes followed by bins; other ranks raise. Automatic centers lie at min + (i + 0.5) * bandwidth; values outside the supplied range contribute according to the selected kernel rather than being clipped into an endpoint bin.

The calculation uses triangular kernel density estimation.

Parameters:
  • image (Tensor) – Input torch.Tensor to compute the histogram with shape \((H, W)\), \((C, H, W)\) or \((B, C, H, W)\).

  • min (float, optional) – Lower end of the interval (inclusive). Default: 0.0

  • max (float, optional) – Upper end of the interval (inclusive). Ignored when centers is specified. Default: 255.0

  • n_bins (int, optional) – The number of histogram bins. Ignored when centers is specified. Default: 256

  • bandwidth (Optional[float], optional) – Positive finite smoothing factor. If not specified or equal to -1, it is calculated as \((max - min) / n_bins\). Default: None

  • centers (Optional[Tensor], optional) – Centers of the bins with shape \((n_bins,)\). If not specified or empty, it is calculated as centers of equal-width bins over the non-empty finite [min, max] range. Default: None

  • return_pdf (bool, optional) – If True, also return probability densities for each bin. Default: False

  • kernel (str, optional) – kernel to perform kernel density estimation (`triangular`, `gaussian`, `uniform`, `epanechnikov`). Default: "triangular"

  • eps (float, optional) – epsilon for numerical stability. Default: 1e-10

Return type:

Tuple[Tensor, Tensor]

Returns:

Computed histogram of shape \((bins)\), \((C, bins)\),

\((B, C, bins)\).

Computed probability densities of shape \((bins)\), \((C, bins)\),

\((B, C, bins)\), if return_pdf is True. torch.Tensor of torch.zeros with shape of the histogram otherwise.