plenoptic.process.circular_gaussian2d#

plenoptic.process.circular_gaussian2d(kernel_size, std, out_channels=None)[source]#

Create normalized, centered circular 2D gaussian tensor with which to convolve.

The filter is normalized by total pixel-sum (not by 2*pi*std) and has shape (out_channels, 1, height, width). For 2d convolutions in torch, the first dimensions of the filter tensor corresponds to out_channels and the second to in_channels, see torch.nn.Conv2d for more details.

Parameters:
  • kernel_size (int | tuple[int, int]) – Filter kernel size. Recommended to be odd so that kernel is properly centered. If you use same-padding, convolution with an odd-length kernel will be faster, see torch.nn.functional.conv2d.

  • std (int | list[int] | float | list[float] | Tensor) – Standard deviation of 2D circular Gaussian. If a scalar and out_channels is not None, all out channels will have the same value. If not a scalar and out_channels is not None, len(std) must equal out_channels.

  • out_channels (int | None (default: None)) – Number of output channels. If None, inferred from shape of std.

Return type:

Tensor

Returns:

filt – Circular gaussian kernel.

Raises:
  • ValueError – If out_channels is not a positive integer.

  • ValueError – If kernel_size is not one or two positive integers.

  • ValueError – If std is not positive.

  • ValueError – If std is non-scalar and len(std) != out_channels

See also

Gaussian

Torch Module to perform this convolution.

Examples

Single output channel.

>>> import plenoptic as po
>>> from torch.nn.functional import conv2d
>>> import torch
>>> import matplotlib.pyplot as plt
>>> kernel_size = 32
>>> filt_2d = po.process.circular_gaussian2d(kernel_size=kernel_size, std=2)
>>> filt_2d.shape
torch.Size([1, 1, 32, 32])
>>> einstein_img = po.data.einstein()
>>> blurred_einstein = conv2d(einstein_img, filt_2d, padding="same")
>>> po.plot.imshow(
...     [einstein_img, filt_2d, blurred_einstein],
...     title=["Einstein", "2D Gaussian Filter", "Blurred Einstein"],
... )
<PyrFigure ...>

(png, hires.png, pdf)

../../_images/plenoptic-process-circular_gaussian2d-1.png

Multiple output channels with different standard deviations.

>>> kernel_size = 32
>>> filt_2d = po.process.circular_gaussian2d(
...     kernel_size=kernel_size, std=[2, 5.5], out_channels=2
... )
>>> filt_2d.shape
torch.Size([2, 1, 32, 32])
>>> einstein_img = po.data.einstein()
>>> blurred_einstein = conv2d(einstein_img, filt_2d, padding="same")
>>> titles = [
...     "Einstein",
...     "2D Gaussian Filter",
...     "Larger 2D Gaussian Filter",
...     "Blurred Einstein",
...     "Blurrier Einstein",
... ]
>>> po.plot.imshow([einstein_img, filt_2d, blurred_einstein], title=titles)
<PyrFigure ...>

(png, hires.png, pdf)

../../_images/plenoptic-process-circular_gaussian2d-2.png

Multiple input and output channels, convolved independently. See torch.nn.functional.conv2d to understand the behavior below:

>>> kernel_size = 32
>>> filt_2d = po.process.circular_gaussian2d(
...     kernel_size=kernel_size, std=[2, 5.5], out_channels=2
... ).repeat(3, 1, 1, 1)
>>> filt_2d.shape
torch.Size([6, 1, 32, 32])
>>> wheel = po.data.color_wheel(as_gray=False)
>>> blurred_wheel = conv2d(wheel, filt_2d, groups=3, padding="same")
>>> titles = ["Wheel", "Blurred Wheel", "Blurrier Wheel"]
>>> # note that the order of channels: the first two correspond to the first
>>> # channel of the input image, convolved with the each of the two gaussians,
>>> # and so on.
>>> po.plot.imshow(
...     [wheel, blurred_wheel[:, ::2], blurred_wheel[:, 1::2]],
...     title=titles,
...     as_rgb=True,
... )
<PyrFigure ...>

(png, hires.png, pdf)

../../_images/plenoptic-process-circular_gaussian2d-3.png