2
votes

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

1
When you increase sigma, the curve gets flatter. If the sum of the matrix is less than 1, applying it will make the picture darker.Mark Ransom
That's correct. But the aim is to blur the image. What changes do you suguest?Mrcreamio
Normalizations ensures the area remains constant. So the amplitude must decrease. See pages.stat.wisc.edu/~mchung/teaching/MIA/reading/…. I think you want to remove your normalization by aa so that the center of the kernel will be unity. If for some reason it is not unity, then normalize by dividing by the center value.fmw42
@fmw42: the center of the kernel shouldn’t be unity, but the sum of kernel values should be 1.Cris Luengo
@Cris Luengo Yes, you are correct. My error.fmw42

1 Answers

6
votes

The problem is that you sample only a 5x5 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.