Swift/Metal Image Processing

Yuya Horita
3 min readMar 13, 2019

--

2. Smoothing

Smoothing is a technique for reducing noise on the basis of spatial filter.

Same as edge detection, determining kernel K is our interest.

Gaussian Filter

Gaussian filter is one of smoothing filter. Each kernel matrix element is determined by gauss function.

This distribution has the following characteristics

  • give more weight at the central pixels
  • the farther away the neighbors, the smaller the weight
  • the smaller sigma, the larger the central pixels’ effect on output pixel and vice versa.

as the following figure shows.

gaussian 2-dimensions distribution

There are commonly used kernel matrix for gaussian filter.

3x3 gaussian kernel
5x5 gaussian kernel

Generally,

where,

Try this filter in SwiftImageProcessor/Shader/Smoothing/gauss.metal .

landscape_gaussian_three_dim.jpg

Could get this blurred image.

Let’s apply general gaussian filter with

self.kernel = .gaussian(sigma: 3.0)
landscape_gaussian.jpg with sigma=3.0

The magnitude of blurring became larger because farther pixel’s effect is larger with larger sigma.

Bilateral Filter

Similarly to the Gaussian filter, the bilateral filter is also defined as a weighted average of neighboring pixels. The difference is this filter takes into account the variation of luminance as showed below.

where

The weight value W is constant in Gaussian filter, but it depends on the target pixel position, gid in Metal, in Bilateral.

Let’s see this factor. This is a gauss function receiving the argument, delta of luminance of central pixel and each neighboring pixel.

“The delta is large” means “the neighboring pixel’s color, or luminance, differs largely from central pixel’s”. And if the delta is large, gauss function returns nearly 0, which means the pixel almost never affect on output pixel.

Gaussian filter doesn’t take into account the luminance information, so edges are lost.

Bilateral uses the information of neighboring pixels whose luminance is near the target pixel’s, so edges are kept.

Try bilateral filter with SwiftImageProcessor/Shader/Smoothing/bilateral.metal .

Then, use these parameters

self.kernel = .bilateral(sigma: 3.0, luminanceSigma: 0.2)

The first sigma is for space (same as Gaussian), the second is for luminance. We chose same value for space sigma and small value for luminance sigma.

landscape_bilateral.jpg sigma=3.0, luminanceSigma=0.2

It seems that edges become shaper than gaussian filter.

Other Articles

--

--

Yuya Horita

Master of Nuclear Physics, CyberAgent, Inc. FRESH LIVE. M3. Software Engineer. Twitter: https://twitter.com/horita_yuya ,GitHub: https://github.com/horita-yuya