OpenCV: Filters & Arithmetic Operations

Ali Almutawakel
5 min readMar 20, 2017

This is the 2nd introduction for OpenCV. This is a code-along tutorial to learn OpenCV in Python. We will be looking at arithmetic operations, and filters (blurring, and sharpening).

Arithmetic Operations

Addition and subtraction of color intensity in an image is done by simple OpenCV functions add() & subtract(). This results in either brightening or darkening the image. Both functions take in two parameters:

1- The input image
2- Matrix of numbers to add to or subtract from

The main condition is to have the matrix has to be the same size as the input image. We can achieve that by using NumPy function ones().

The following example illustrates how it can be used:

# It is always a good habit to 
import cv2
import numpy as np
# Reading in the input image
image = cv2.imread('images/input.jpg')
# Create a matrix of ones of type int in the same size as the image
# then multiply it by a scaler of 75
# This gives a matrix with same dimesions of our image with all values being 75
matrix = np.ones(image.shape, dtype = "uint8") * 75
# We use the matrix to add to our image
added = cv2.add(image, ones)
cv2.imshow("Added", matrix)
# Likewise we can also subtract
subtracted = cv2.subtract(image, matrix)
cv2.imshow("Subtracted", subtracted)
# Wait & terminate
cv2.waitKey(0)
cv2.destroyAllWindows()

To demonstrate better what the matrix is in this case; it is an array of ones that are in the same size as the input image multiplied by 75.

Matrix of ones multiplied by 75
Matrix size is the same as the image size

Results of running the code block above:

Filters — Blurring and Sharpening

Filters are essential for many OpenCV functions (hint: edge detections) because you can either reduce noise or increase it. Filters normalize and average out a block of pixels in an image to have low values difference. The result is

Blurring effect on pixel values
A typical blurred image result

How blurring works? When processing an image, each pixel value changes according to its neighbouring pixels. To demonstrate, refer to the diagrams below; it shows an overly simplified algorithm to blurring.
Say you are processing pixel[1,1]. You decided to take into account the nearest neighbours only. You set the value of the pixel as the total average of all pixels.

Left (1) Right (2)
Left (3) Right (4)
Left (5) Right (6)

The size of the pixels which we run our manipulation function on is called the kernel. In the example below, we used 3x3 kernel to process our image. The image below shows how an example of 3x3 kernel array to average out (blur) and image in Python. It is important that the number sums up to 1 so we maintain the same brightness of the image. Otherwise, the image will either brighten or darken.

Unlike blurring, sharpening does the opposite and tries to pop out the details in the image. Thus, making pixel value different than its neighbours.

Typical kernel for blurring (averaging)
Typical kernel for sharpening

The function for filtering in OpenCV is filter2D(). It takes in three parameters:

1- Input image
2- Desired depth (more advanced topic)
3- Kernel

And would something like this:

# Putting a negative value for depth to indicate to use the 
# the same depth of the source image src.depth().
cv2.filter2D(image, -1, kernel)

Now to apply a more comprehensive example of filters. Follow & code along.

import cv2
import numpy as np
# Reading our image and displaying it
image = cv2.imread('images/elephant.jpg')
cv2.imshow('Original Image', image)
cv2.waitKey(0)
# Creating our 3 x 3 kernel that would look like this:
# [[ 0.11111111 0.11111111 0.11111111]
# [ 0.11111111 0.11111111 0.11111111]
# [ 0.11111111 0.11111111 0.11111111]]
kernel_3x3 = np.ones((3, 3), np.float32) / 9
# We apply the filter and display the image
blurred = cv2.filter2D(image, -1, kernel_3x3)
cv2.imshow('3x3 Kernel Blurring', blurred)
cv2.waitKey(0)
# Let's try with 7 x 7 kernel to get a more blurred image
kernel_7x7 = np.ones((7, 7), np.float32) / 49
blurred2 = cv2.filter2D(image, -1, kernel_7x7)
cv2.imshow('7x7 Kernel Blurring', blurred2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Original (Left) — 3x3 Kernel (middle) — 7x7 Kernel (Right)

As for sharpening:

import cv2
import numpy as np
# Reading in and displaying our image
image = cv2.imread('images/input.jpg')
cv2.imshow('Original', image)
# Create our shapening kernel, it must equal to one eventually
kernel_sharpening = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
# applying the sharpening kernel to the input image & displaying it.
sharpened = cv2.filter2D(image, -1, kernel_sharpening)
cv2.imshow('Image Sharpening', sharpened)cv2.waitKey(0)
cv2.destroyAllWindows()

Results:

Original (left) — Sharpened (right)

What’s Next?

On my next blog, we will be discussing edge detection functions by OpenCV. Stay tuned!

--

--