When applying Gaussian filter the image becomes dark

Issue

When I run the following code the output result is blurred but the image gets darker as I increase the value of sigma.

Imports

import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
import math
import copy

Gaussian filter code

e = 2.71828182845904
pi = 3.1415926535897

def gaus(mat_l,sigma):
    Matrix = [[0.0 for x in range(mat_l)] for y in range(mat_l)] 
    for x in range(-(int(mat_l/2)),(int(mat_l/2))+1):
        for y in range(-(int(mat_l/2)),(int(mat_l/2))+1):
            ee = pow(e,(-(((pow(x,2)+pow(y,2))/(2*(pow(sigma,2)))))))
            aa = (1/(2*pi*pow(sigma,2)))
            result = ee*aa
            Matrix[x+int(mat_l/2)][y+int(mat_l/2)] = round(result,6)
    return Matrix

Convolution code

def matrix_convolve(image,kernel,a,b,mul=1):
    print(kernel)
    img_x, img_y = image.shape
    kernl_x, kernl_y = kernel.shape

    result = copy.deepcopy(image)
    for i in range(img_x-int(len(kernel)/2)):
        for j in range(img_y-int(len(kernel)/2)):
            result[i][j] = 0
            summ = 0
            for s in range(-a,a+1):
                for t in range(-b,b+1):
                    summ += kernel[s,t] * image[i+s,j+t]
            result[i][j] = math.ceil(mul*summ)
    return result

Driver

image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

kernal = gaus(5,5)
kernal = np.array([kernal[0],kernal[1],kernal[2],kernal[3],kernal[4]])

result3 = matrix_convolve(image,kernal,2,2)
plt.imshow(result3.astype(np.uint8),cmap='gray')
plt.show()

When sigma is 5, the output image is
output_with_sigma_5

when sigma is 2, the output image is
output_with_sigma_2

result3=cv2.GaussianBlur(image,(5,5),5)
plt.imshow(result3.astype(np.uint8),cmap='gray')
plt.show()

When blurred using OpenCV the following is the output for sigma 5
opencv

Solution

The problem is that you sample only a 5×5 grid of the Gaussian kernel. The larger the sigma, the more of the kernel you cut off, and the more power you lose.

A blurring kernel should always sum up to 1. If it adds up to 0.5, for example, the average intensity of the output image will be half of that of the input.

The solution is twofold:

  1. Sample a larger fraction of your kernel. At least 1+2*ceil(2*sigma), but preferably 3 times instead of 2.

  2. Normalize your kernel. Even if you sample up to 3*sigma out from the center, you still lose a bit of power in the sampling, especially for small sigma. Normalizing the kernel is as simple as adding up all the kernel values and then dividing each kernel value by that sum.

Answered By – Cris Luengo

Answer Checked By – Mildred Charles (AngularFixing Admin)

Leave a Reply

Your email address will not be published.