Filters

September 05, 2022
Computer Vision

Low Pass Filter

As in one-dimensional signals, images also can be filtered with various low-pass filters(LPF), high-pass filters(HPF) etc. LPF helps in removing noises, blurring the images etc.

OpenCV provides a function cv2.filter2D() to convolve a kernel with an image. As an example, we will try an averaging filter on an image. A 5x5 averaging filter kernel will look like below:

K = 1/25  ⎡1 1 1 1 1⎤
                 ⎢1 1 1 1 1 ⎢
                 ⎢1 1 1 1 1 ⎢
                 ⎢1 1 1 1 1 ⎢
                 ⎣1 1 1 1 1⎦

Operation is like this: keep this kernel above a pixel, add all the 25 pixels below this kernel, take its average and replace the central pixel with the new average value. It continues this operation for all the pixels in the image.

Try this code and check the result:

# Import Necessary library
import cv2
import numpy as np

# Read MyPic.jpg from system as grayscale
img = cv2.imread("MyPic.jpg", 0)
# Create a 5x5 Kernel
kernel = np.ones((5,5), np.float32)/25
# Apply convolution between image and 5x5 Kernel
dst = cv2.filter2D(img,-1, kernel)
# Store LPF image as lpf.jpg
cv2.imwrite("lpf.jpg", dst)

Our input Image :

Output Image for LPF will be :

Image Blurring

Image blurring is achieved by convolving the image with a low-pass filter kernel. It is useful for removing noises. It actually removes high frequency content (eg: noise, edges) from the image. So edges are blurred a little bit in this operation. (Well, there are blurring techniques which doesn't blur the edges too).

OpenCV provides mainly four types of blurring techniques :

  1. Averaging :

This is done by convolving image with a normalized box filter. It simply takes the average of all the pixels under kernel area and replace the central element. This is done by the function cv2.blur() or cv2.boxFilter(). Check the docs for more details about the kernel. We should specify the width and height of kernel. A 3x3 normalized box filter would look like below:

K = 1/9  ⎡1 1 1 1 1⎤
               ⎢1 1 1 1 1 ⎢
               ⎢1 1 1 1 1 ⎢
               ⎢1 1 1 1 1 ⎢
               ⎣1 1 1 1 1⎦

# Import Necessary library
import cv2
import numpy as np

# Read MyPic.jpg from system as grayscale
img = cv2.imread("MyPic.jpg", 0)
# Apply Averaging blur
blur = cv2.blur(img,(5,5))
# Store LPF image as lpf.jpg
cv2.imwrite("AvgBlur.jpg", blur)

Our input Image :

Output Image for Averaging blur will be :

  1. Gaussian Blurring :

In this, instead of box filter, gaussian kernel is used. It is done with the function, cv2.GaussianBlur(). We should specify the width and height of kernel which should be positive and odd. We also should specify the standard deviation in X and Y direction, sigmaX and sigmaY respectively. If only sigmaX is specified, sigmaY is taken as same as sigmaX. If both are given as zeros, they are calculated from kernel size. Gaussian blurring is highly effective in removing gaussian noise from the image.

If you want, you can create a Gaussian kernel with the function, cv2.getGaussianKernel().

The above code can be modified for Gaussian blurring:

blur = cv2.GaussianBlur(img,(5,5),0)

2.Median Blurring :

Here, the function cv2.medianBlur() takes median of all the pixels under kernel area and central element is replaced with this median value. This is highly effective against salt-and-pepper noise in the images. Interesting thing is that, in the above filters, central element is a newly calculated value which may be a pixel value in the image or a new value. But in median blurring, central element is always replaced by some pixel value in the image. It reduces the noise effectively. Its kernel size should be a positive odd integer.

In this demo, I added a 50% noise to our original image and applied median blur.

The code can be modified for Median Blurring :

median = cv2.medianBlur(img,5)

3.Bilateral Filtering :

cv2.bilateralFilter() is highly effective in noise removal while keeping edges sharp. But the operation is slower compared to other filters. We already saw that gaussian filter takes the a neighbourhood around the pixel and find its gaussian weighted average. This gaussian filter is a function of space alone, that is, nearby pixels are considered while filtering. It doesn't consider whether pixels have almost same intensity. It doesn't consider whether pixel is an edge pixel or not. So it blurs the edges also, which we don't want to do.

Bilateral filter also takes a gaussian filter in space, but one more gaussian filter which is a function of pixel difference. Gaussian function of space make sure only nearby pixels are considered for blurring while gaussian function of intensity difference make sure only those pixels with similar intensity to central pixel is considered for blurring. So it preserves the edges since pixels at edges will have large intensity variation.

The code can be modified for Bilateral Filtering :

blur = cv2.bilateralFilter(img,9,75,75)

High pass filter

A high pass filter (HPF) is a filter that examines a region of an image and boosts the intensity of certain pixels based on the difference in the intensity with the surrounding pixels. HPF filters helps in finding edges in the images.

Take, for example, the following kernel:
[[0, -0.25, 0],
[-0.25, 1, -0.25],
[0, -0.25, 0]]

A kernel is a set of weights that are applied to a region in a source image to generate a single pixel in the destination image. For example, a ksize of 7 implies that 49 (7 x 7) source pixels are considered in generating each destination pixel. We can think of a kernel as a piece of frosted glass moving over the source image and letting through a diffused blend of the source’s light.

After calculating the sum of differences of the intensities of the central pixel compared to all the immediate neighbors, the intensity of the central pixel will be boosted (or not) if a high level of changes are found. In other words, if a pixel stands out from the surrounding pixels, it will get boosted.

This is particularly effective in edge detection, where a common form of HPF called high boost filter is used

Both high pass and low pass filters use a property called radius, which extends the area of the neighbors involved in the filter calculation.

Example :

# Import Necessary library
import cv2
import numpy as np
from scipy import ndimage

# Create a 3x3 Kernel
kernel_3x3 = np.array(
[[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]])
# Create a 5x5 Kernel
kernel_5x5 = np.array(
[[-1, -1, -1, -1, -1],
[-1, 1, 2, 1, -1],
[-1, 2, 4, 2, -1],
[-1, 1, 2, 1, -1],
[-1, -1, -1, -1, -1]])
# Read MyPic.jpg from system as grayscale
img = cv2.imread("MyPic.jpg", 0)
# Apply convolution between image and kernel_3x3
k3 = ndimage.convolve(img, kernel_3x3)
# Apply convolution between image and kernel_5x5
k5 = ndimage.convolve(img, kernel_5x5)
# Apply GaussianBlur
blurred = cv2.GaussianBlur(img, (11,11), 0)
# Create Gaussian HPF
g_hpf = img - blurred
# Store all the image
cv2.imwrite("3x3.jpg", k3)
cv2.imwrite("5x5.jpg", k5)
cv2.imwrite("g_hpf.jpg", g_hpf)

Output Image for kernel_3x3,kernel_5x5 and g_hpf respectively :

After the initial imports, we define a 3x3 kernel and a 5x5 kernel, and then we load the image in grayscale. Normally, the majority of image processing is done with NumPy; however, in this particular case, we want to “convolve” an image with a given kernel and NumPy happens to only accept one-dimensional arrays.

VIkas Donta

My name is VIkas Donta and I first discovered Web Designingin 2018. Since then, It has impact on my web design projects development career, and  improve my understanding of HTML/CSS tremendously!

Related Posts

Stay in Touch

Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form

Stay in Touch

Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form