I have written my own 2D Convolution function as follows
def TwoD_convolution(img, kernel):
# Flipping the kernel by 180 degrees
kernel = kernel[::-1]
for i in range(len(kernel)):
kernel[i] = kernel[i][::-1]
# Filling the new image with zeroes
convolve = np.zeros((img.shape[0]+len(kernel)-1, img.shape[1]+len(kernel[0])-1, 3), np.uint8)
midx = len(kernel)//2
midy = len(kernel[0])//2
# Trying to fill each cell one by one, and RGB values
for i in range(convolve.shape[0]):
for j in range(convolve.shape[1]):
for k in range(3):
cur = 0 #current sum
for x in range(-midx,midx+1):
for y in range(-midy,midy+1):
if i+x >= 0 and i+x < img.shape[0] and j+y >= 0 and j+y < img.shape[1]:
# going through every neighbour of the middle cell
cur += ((img[i+x][j+y][k])*(kernel[midx+x][midy+y]))
convolve[i][j][k] = cur
return convolve
To get a sharpened image, I am calling the function as follows:
display_image(TwoD_convolution(img,[[-0.5,-1,-0.5],[-1,7,-1],[-0.5,-1,-0.5]]))
Where display_image is defined as follows:
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.show()
It is displaying this image:
I am sure it is getting sharpened on some pixels.. but why are the colors at the edges so random ? Where am I going wrong ?
Thanks
In the code for the TwoD_convolution I have made the following modifications:
I have tried normalizing the kernel, ensuring that the overall intensity of the image remains relatively stable across different regions.
I have clipped the values ensuring that no overflow occurs, thus minimizing artifacts like green dots.
I have run this on google colab and it works (I have used a different kernel but yours works fine too, it's just a bit more sharp)
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import requests
def TwoD_convolution(img, kernel):
kernel = kernel[::-1]
for i in range(len(kernel)):
kernel[i] = kernel[i][::-1]
convolve = np.zeros((img.shape[0]+len(kernel)-1, img.shape[1]+len(kernel[0])-1, 3), np.uint8)
midx = len(kernel) // 2
midy = len(kernel[0]) // 2
# HERE I NORMALIZE THE KERNEL
kernel_sum = np.sum(kernel)
if kernel_sum == 0:
kernel_sum = 1
normalized_kernel = kernel / kernel_sum
for i in range(convolve.shape[0]):
for j in range(convolve.shape[1]):
for k in range(3):
cur = 0
for x in range(-midx, midx+1):
for y in range(-midy, midy+1):
if i+x >= 0 and i+x < img.shape[0] and j+y >= 0 and j+y < img.shape[1]:
cur += ((img[i+x][j+y][k]) * (normalized_kernel[midx+x][midy+y]))
convolve[i][j][k] = np.clip(cur, 0, 255) # RANGE CHECKING
return convolve
url = 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png'
image = Image.open(requests.get(url, stream=True).raw)
img_array = np.array(image)
# you can try yours too [-0.5,-1,-0.5],[-1,7,-1],[-0.5,-1,-0.5]
kernel = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
convolved_img = TwoD_convolution(img_array, kernel)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(img_array)
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(convolved_img)
plt.title('Convolved Image')
plt.axis('off')
plt.show()
I'm sorry If I have putted all of this code here but it's to get the example clear