VPI - Vision Programming Interface

0.2.0 Release

Bilateral Image Filter

Overview

A Bilateral Image Filter is a non-linear, edge-preserving smoothing filter that is commonly used in Computer Vision as a simple noise-reduction stage in a pipeline. It calculates the intensity of each output pixel as a weighted average of intensity values from nearby pixels in the input image. Crucially, the weights depend not only on the Euclidean distance between current and neighbor pixels, but also on the radiometric differences (e.g., color intensity differences) between them. The outcome is that edges are preserved while regions with similar intensities are smoothed out.

Input Parameters Output

\begin{align*} \mathit{kernelSize} &= 7x7 \\ \sigma_s &= 1.7 \\ \sigma_r &= 50 \end{align*}

Implementation

The bilateral image filter is defined as:

\[ I'(p) = \frac{1}{W_p} \sum_{q\in\Omega}I(p)k_r(\|I(q) - I(p)\|)k_s(\|p-q\|) \]

and the normalization term, W, is defined as:

\[ W_p = \sum_{q\in\Omega}k_r(\|I(p)-I(q)\|)k_s(\|p-q\|) \]

where

  • \(I\) and \(I'\) are the input and output images, respectively.
  • \(k_r\) and \(k_s\) are the range and space kernels, respectively, defined as the following non-normalized Gaussian functions:

    \begin{align*} k_r(p) &= e^{-\frac{\|p\|^2}{2\sigma_r^2}} \\ k_s(p) &= e^{-\frac{\|p\|^2}{2\sigma_s^2}} \end{align*}

  • \(\sigma_r\) controls the intensity range that is smoothed out. Higher values will lead to larger regions being smoothed out. The \(\sigma_r\) value should be selected with the dynamic range of the image pixel values in mind.
  • \(\sigma_s\) controls smoothing factor. Higher values will lead to more smoothing.

Usage

  1. Initialization phase
    1. Include the header that defines the Gaussian filter function.
    2. Define the stream on which the algorithm will be executed, the input and output images.
      VPIStream stream = /*...*/;
      VPIImage input = /*...*/;
    3. Create the output image.
      uint32_t w, h;
      vpiImageGetSize(input, &w, &h);
      vpiImageGetType(input, &type);
      VPIImage output;
      vpiImageCreate(w, h, type, 0, &output);
  2. Processing phase
    1. Submit the algorithm to the stream, along with all parameters. Here we're using a 7x7 kernel with \(\sigma_r=50\) and \(\sigma_s=1.7\).
      vpiSubmitBilateralImageFilter(stream, input, output, 7, 50, 1.7, VPI_BOUNDARY_COND_ZERO);
    2. Optionally, wait until the processing is done.
      vpiStreamSync(stream);

Limitations and Constraints

Constraints for specific backends supersede the ones specified for all backends.

All Backends

PVA

  • Not implemented

Performance

For further information on how performance was benchmarked, see Performance Measurement.

Jetson AGX Xavier
sizetypekernelCPUCUDAPVA
1920x1080u83x3 1.51 ms0.1820 msn/a
1920x1080u85x5 3.57 ms0.2598 msn/a
1920x1080u87x7 9.8 ms0.5482 msn/a
1920x1080u811x11 24.53 ms1.3467 msn/a
1920x1080u163x3 1.87 ms0.1907 msn/a
1920x1080u165x5 4.05 ms0.2644 msn/a
1920x1080u167x7 11.0 ms0.5485 msn/a
1920x1080u1611x11 27.35 ms1.3463 msn/a
Jetson TX2
sizetypekernelCPUCUDAPVA
1920x1080u83x3 5.5 ms0.644 msn/a
1920x1080u85x5 13.4 ms0.905 msn/a
1920x1080u87x7 38.3 ms1.9385 msn/a
1920x1080u811x11 65.0 ms4.4045 msn/a
1920x1080u163x3 5.53 ms0.683 msn/a
1920x1080u165x5 17.08 ms0.928 msn/a
1920x1080u167x7 39 ms1.9158 msn/a
1920x1080u1611x11 82.2 ms4.3486 msn/a
Jetson Nano
sizetypekernelCPUCUDAPVA
1920x1080u83x3 13.63 ms1.674 msn/a
1920x1080u85x5 34.68 ms2.456 msn/a
1920x1080u87x7 80.8 ms5.5499 msn/a
1920x1080u811x11 179.7 ms12.561 msn/a
1920x1080u163x3 17.54 ms1.709 msn/a
1920x1080u165x5 44.9 ms2.485 msn/a
1920x1080u167x7 90.5 ms5.4695 msn/a
1920x1080u1611x11 203.5 ms12.428 msn/a
VPIImageType
VPIImageType
Image formats.
Definition: Types.h:190
vpiSubmitBilateralImageFilter
VPIStatus vpiSubmitBilateralImageFilter(VPIStream stream, VPIImage input, VPIImage output, uint32_t kernelSize, float sigmaRange, float sigmaSpace, VPIBoundaryCond boundary)
Runs a 2D bilateral filter over an image.
vpiStreamSync
VPIStatus vpiStreamSync(VPIStream stream)
Blocks the calling thread until all submitted commands in this stream queue are done (queue is empty)...
VPIImage
struct VPIImageImpl * VPIImage
Definition: Types.h:170
vpiImageGetSize
VPIStatus vpiImageGetSize(VPIImage img, uint32_t *width, uint32_t *height)
Get the image size in pixels.
vpiImageGetType
VPIStatus vpiImageGetType(VPIImage img, VPIImageType *type)
Get the image type.
vpiImageCreate
VPIStatus vpiImageCreate(uint32_t width, uint32_t height, VPIImageType type, uint32_t flags, VPIImage *img)
Create an empty image instance with the specified flags.
VPI_BOUNDARY_COND_ZERO
@ VPI_BOUNDARY_COND_ZERO
All pixels outside the image are considered to be zero.
Definition: Types.h:251
BilateralImageFilter.h
VPIStream
struct VPIStreamImpl * VPIStream
Definition: Types.h:164