|
| 1 | +import numpy as np |
| 2 | +import cv2 |
| 3 | +from google.colab.patches import cv2_imshow |
| 4 | +from math import sqrt, atan |
| 5 | + |
| 6 | +#This script can be used for edge-detection without the use of any inbuilt openCV libraries |
| 7 | +#Here the sobel filter is applied after blurring the image. |
| 8 | + |
| 9 | +kernelblur = np.array([1/16, 1/8, 1/16, 1/8, 1/4, 1/8, 1/16, 1/8, 1/16]).reshape(3, 3) |
| 10 | +kernelsobelX = np.array([-1, -2, -1, 0, 0, 0, 1, 2, 1]).reshape(3, 3) |
| 11 | +kernelsobelY = kernelsobelX.transpose() |
| 12 | + |
| 13 | +def convolute(img, kernel, height, width): |
| 14 | + pixels = [] |
| 15 | + |
| 16 | + #pixels are extracted from the image converted to grayscale |
| 17 | + for i in range(height): |
| 18 | + for j in range(width): |
| 19 | + pixels.append(img[i, j]) |
| 20 | + |
| 21 | + #The pixels array is resized in accordance with the size of the image |
| 22 | + pixels = np.array(pixels).reshape(height, width) |
| 23 | + |
| 24 | + #To handle the edge cases, sentinel values are used |
| 25 | + #The pixels array is bound by zeros on all edges |
| 26 | + |
| 27 | + # 00000000 |
| 28 | + # 0PIXELS0 |
| 29 | + # 00000000 |
| 30 | + #This is done to ensure that the kernel is applied to all the pixels |
| 31 | + #Sentinel values to ensure the edges arent missed out |
| 32 | + #Along the rows and columns |
| 33 | + pixels = np.insert(pixels, [0, height], np.zeros(len(pixels[0])), axis = 0) |
| 34 | + pixels = np.insert(pixels, [0, width], np.zeros((len(pixels[:, 0]), 1)), axis = 1) |
| 35 | + |
| 36 | + #Convolution is applied here |
| 37 | + apply_filter = [] |
| 38 | + for i in range(1, height): |
| 39 | + for j in range(1, width): |
| 40 | + temp = pixels[i:i+3, j:j+3] |
| 41 | + product = np.multiply(temp, kernel) |
| 42 | + apply_filter.append(sum(sum(product))) |
| 43 | + |
| 44 | + #The pixels are converted back to the image |
| 45 | + apply_filter = np.array(apply_filter).reshape(height-1, width-1) |
| 46 | + return(apply_filter) |
| 47 | + |
| 48 | +def sobel(img): |
| 49 | + height = img.shape[0] |
| 50 | + width = img.shape[1] |
| 51 | + |
| 52 | + #The image is blurred, so the noise is removed |
| 53 | + blur = convolute(img, kernelblur, height, width) |
| 54 | + |
| 55 | + height = height - 1 |
| 56 | + width = width - 1 |
| 57 | + |
| 58 | + #The sobel filter is applied in the X and Y direction separately |
| 59 | + convoluted_Y = convolute(blur, kernelsobelX, height, width) |
| 60 | + convoluted_X = convolute(blur, kernelsobelY, height, width) |
| 61 | + |
| 62 | + #Every pixel in convoluted_X can be called gx, in convoluted_Y can be called gy, |
| 63 | + #The resultant will be sqrt(pow(gx**2) + pow(gy**2)) |
| 64 | + resultant = [] |
| 65 | + for i in range(height - 1): |
| 66 | + for j in range(width - 1): |
| 67 | + in_x = pow(convoluted_X[i, j], 2) |
| 68 | + in_y = pow(convoluted_Y[i, j], 2) |
| 69 | + gradient = sqrt(in_x + in_y) |
| 70 | + reusultant.append(grad) |
| 71 | + resultant = np.array(resultant).reshape(height-1, width-1) |
| 72 | + cv2_imshow(resultant) |
| 73 | + |
| 74 | +if __name__ == "__main__": |
| 75 | + img = cv2.imread("/path to image", 0) |
| 76 | + sobel(img) |
0 commit comments