-1

I am implementing my convolution logic for image filtering in Python, but it is only rendering a black image every time for different input images and kernels. Need help. Below is the code

def convolution_filter(gray_img,kernel):
 img_ht,img_wt = gray_img.shape;
 kernel_ht, kernel_wt = kernel.shape;
 out_img = np.zeros(shape=gray_img.shape)
 k =int((kernel_ht-1)/2);

fl_kernel = kernel;
flip_code = -1;

bdr = int((kernel_wt-1)/2)
v_anchor = (kernel_ht-1)/2
gray_img = cv2.copyMakeBorder(gray_img, bdr, bdr, bdr, bdr,cv2.BORDER_REPLICATE)

for i in range(bdr,img_ht+bdr):
    for j in range(bdr,img_wt+bdr):
        center=gray_img[i-bdr:i+bdr+1, j-bdr:j-bdr+1]
        convolve = (center*kernel).sum()
        
        out_img[i-bdr,j-bdr] = convolve
        out_img = (out_img * 255).astype("uint8")

        
        return out_img;

'''

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
mohanaroy
  • 31
  • 2
  • 5

1 Answers1

0

Problems:


  • kernel_ht, kernel_wt = kernel.shape;


    • Assume, my filter [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]] you can't use kernel.shape.
    • Since, the filter is 3 x 3 sized, height = len(kernel), width = len(kernel[0])
    • Possible Question: Wait, why the width is len(kernel[0]) what happens is if len(kernel[1]) != len(kernel[0]) is True?
    • Possible Answer Mostly, the kernel's height and width are the same. But you can add:
      kernel_wt = [len(i) for i in kernel if len(i) > len(kernel[0])]
  • convolve = (center * kernel).sum()


  • The code selects only 3 variables for kernels' 9 values by default the other kernel values are multiplied with 0.

  • For instance: For the first iteration the [114, 114, 144] pixel values are selected but we have 9 kernel values. 114 * (-1) + 114 * (0) + 114 * (-1) + 0 * -2 * 0 + 0 * 0 + 2 * 0.... therefore the result is 0 and blank image

  • How convolution works?


  • enter image description here

  • source

  • As we can see from the above gif, pseudocode will be:

  • for each iteration: 
        Select 3 x 3 area
        Multiply with the kernel
        image(current_coordinates) = multiplication.
    
  • Left input image, Right filtered image for kernel [[0, -1, 0], [-1, 4, -1], [0, -1, 0]]


  • enter image description here enter image description here

  • Code:


import cv2
import numpy as np


def convolution_filter(gray_img, kernel):
    # temporary operation
    # gray_img = cv2.resize(gray_img, (10, 10))

    kernel_size = len(kernel)

    row = gray_img.shape[0] - kernel_size + 1
    col = gray_img.shape[1] - kernel_size + 1

    result = np.zeros(shape=(row, col))

    for i in range(row):
        for j in range(col):
            current = gray_img[i:i+kernel_size, j:j+kernel_size]
            multiplication = np.abs(sum(sum(current * kernel)))
            result[i, j] = multiplication

    return result


img = cv2.imread("input.jpeg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
k = [[0, -1, 0], [-1, 4, -1], [0, -1, 0]]

filtered = convolution_filter(gray, k)
cv2.imwrite("filtered.jpg", filtered)  
Ahmet
  • 7,527
  • 3
  • 23
  • 47