Tuesday, 7 November 2023

What is convolution in image processing?

Convolution is a mathematical operation that is used to combine two images to produce a third image.

 

The two images used as input in the convolution process are called as input image and kernel matrix.

 


 

Kernel Matrix

Kernel matrix is a small 2D matrix of numbers that define the type of operation that is performed on the input image.

 

Example 1: Kernel matrix with all the values as 1 will blur the image.

 

Example 2: Kernel matrix with all the values as -1 will sharpen the image.

 

How the Convolution operation is performed?

At each pixel of the input image, the kernel matrix elements are multiplied by the corresponding pixel values in the input image, and then sum of the products is assigned to the output image pixel.

 

In simple terms, convolution is an element wise multiplication of two matrices followed by a sum.

 

While performing convolution operation, you need to be aware of valid and invalid positions.

 

Valid position

A position is valid, where the position in the input image and the kernel fully overlaps.

 

The valid positions are the positions in the input matrix where the kernel matrix can be placed without any of the pixels in the kernel matrix falling outside of the input matrix.

 

Invalid position

These are the positions in the input image where the kernel partially or doesn't overlap.

 

For example,



In the above example, following are the valid positions.

 

(0, 0)

(0, 1)

(0, 2)

(1, 0)

(1, 1)

(1, 2)

 

Following are the invalid position.

 

(0, 3)

(0, 4)

(1, 3)

(1, 4)

(2, 0)

(2, 1)

(2, 2)

(2, 3)

(2, 4)

(3, 0)

(3, 1)

(3, 2)

(3, 3)

(3, 4)

 

How to compute convolution at invalid positions?

Computing convolution value at invalid positon can be customized using mode parameter.

 

Mode

Description

valid

Calculate mode only at the valid positions, it leads to a smaller output image. Invalid positions are ignored in the calculation.

full

convolution is calculated at all positions, including the invalid ones, by zero-padding the input image

same

This mode calculates convolution for as many positions as possible without extending beyond the input image boundaries. It results in an output image with the same size as the input image but might still include some invalid positions.

 

Example with mode=valid

 

# Define the input matrix (as a NumPy array)

input_matrix = np.array([

    [1, 2, 3, 4, 5],

    [6, 7, 8, 9, 1],

    [2, 3, 4, 5, 6],

    [7, 8, 9, 1, 2]

])

 

# Define the kernel matrix (as a NumPy array)

kernel_matrix = np.array([

    [1, 0, 1],

    [1, 0, 1],

    [1, 0, 1]

])

 

a[0, 0] = 1*1 + 2*0 + 3*1 + 6*1 + 7*0 + 8*1 + 2*1 + 3*0 + 4*1

                  = 1 + 0 + 3 + 6 + 0 + 8 + 2 + 0 + 4

                  = 24

 

a[0, 1] = 2*1 + 3*0 + 4*1 + 7*1 + 8*0 + 9*1 + 3*1 + 4*0 + 5*1

                  = 2 + 0 + 4 + 7 + 0 + 9 + 3 + 0 + 5

                  = 30

 

a[0, 2] = 3*1 + 4*0 + 5*1 + 8*1 + 9*0 + 1*1 + 4*1 + 5*0 + 6*1

                  = 3 + 0 + 5 + 8 + 0 + 1 + 4 + 0 + 6

                  = 27

 

a[1, 0] = 6*1 + 7*0 +8*1 + 2*1 + 3*0 + 4*1 + 7*1 + 8*0 + 9*1

                  = 6 + 0 + 8 + 2 + 4 + 7 + 0 + 9

                  = 36

 

a[1, 1] = 7*1 + 8*0 + 9*1 + 3*1 + 4*0 + 5*1 + 8*1 + 9*0 + 1*1

                  = 7 + 0 + 9 + 3 + 0 + 5 + 8 + 0+ 1

                  = 33

 

a[1, 2] = 8*1 + 9*0 + 1*1 + 4*1 + 5*0 + 6*1 + 9*1 + 1*0 + 2*1

                  = 8 + 0 + 1 + 4 + 0 + 6 + 9 + 0 + 2

                  = 30

 

Final convolution matrix is

 

[

         24, 30, 27

         36, 33, 30

]

 

Find the below working application.

 

convolution.py

import numpy as np
from scipy.signal import convolve2d

# Define the input matrix (as a NumPy array)
input_matrix = np.array([
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 1],
    [2, 3, 4, 5, 6],
    [7, 8, 9, 1, 2]
])

# Define the kernel matrix (as a NumPy array)
kernel_matrix = np.array([
    [1, 0, 1],
    [1, 0, 1],
    [1, 0, 1]
])

# Perform 2D convolution with different modes
convolution_valid = convolve2d(input_matrix, kernel_matrix, mode='valid')
convolution_full = convolve2d(input_matrix, kernel_matrix, mode='full')
convolution_same = convolve2d(input_matrix, kernel_matrix, mode='same')

# Print the convolution results for each mode
print(f'input_matrix : \n{input_matrix}')
print("\nConvolution (Valid Mode):\n", convolution_valid)
print("\nConvolution (Full Mode):\n", convolution_full)
print("\nConvolution (Same Mode):\n", convolution_same)

 

Output

input_matrix : 
[[1 2 3 4 5]
 [6 7 8 9 1]
 [2 3 4 5 6]
 [7 8 9 1 2]]

Convolution (Valid Mode):
 [[24 30 27]
 [36 33 30]]

Convolution (Full Mode):
 [[ 1  2  4  6  8  4  5]
 [ 7  9 18 22 17 13  6]
 [ 9 12 24 30 27 18 12]
 [15 18 36 33 30 15  9]
 [ 9 11 22 17 21  6  8]
 [ 7  8 16  9 11  1  2]]

Convolution (Same Mode):
 [[ 9 18 22 17 13]
 [12 24 30 27 18]
 [18 36 33 30 15]
 [11 22 17 21  6]]

 

Following program applies the above logic to get the convoluted version of the image.

 

convolution_of_image.py

 

import cv2
import numpy as np

# Read an image using OpenCV
image = cv2.imread('gateway_of_india.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('Original Image', image)

# Define a custom kernel (as a NumPy array)
kernel = np.array([
    [1, 0, 1],
    [1, 0, 1],
    [1, 0, 1]
])

# Perform 2D convolution on the image
convolution_result = cv2.filter2D(image, -1, kernel)
cv2.imshow('convolution_result', convolution_result)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

Output

 


Convoluted image


 

 

 

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment