Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import cv2 | |
| import matplotlib.pyplot as plt | |
| from scipy import ndimage | |
| from scipy.ndimage.filters import convolve | |
| import numpy as np | |
| def hysteresis(img, weak = 75, strong=255): | |
| M, N = img.shape | |
| for i in range(1, M-1): | |
| for j in range(1, N-1): | |
| if (img[i,j] == weak): | |
| try: | |
| if ((img[i+1, j-1] == strong) or (img[i+1, j] == strong) or (img[i+1, j+1] == strong) | |
| or (img[i, j-1] == strong) or (img[i, j+1] == strong) | |
| or (img[i-1, j-1] == strong) or (img[i-1, j] == strong) or (img[i-1, j+1] == strong)): | |
| img[i, j] = strong | |
| else: | |
| img[i, j] = 0 | |
| except IndexError as e: | |
| pass | |
| return img | |
| def threshold(img, lowThresholdRatio=0.05, highThresholdRatio=0.09): | |
| highThreshold = img.max() * highThresholdRatio; | |
| lowThreshold = highThreshold * lowThresholdRatio; | |
| M, N = img.shape | |
| res = np.zeros((M,N), dtype=np.int32) | |
| weak = np.int32(25) | |
| strong = np.int32(255) | |
| strong_i, strong_j = np.where(img >= highThreshold) | |
| zeros_i, zeros_j = np.where(img < lowThreshold) | |
| weak_i, weak_j = np.where((img <= highThreshold) & (img >= lowThreshold)) | |
| res[strong_i, strong_j] = strong | |
| res[weak_i, weak_j] = weak | |
| return (res) | |
| def non_max_suppression(img, D): | |
| M, N = img.shape | |
| Z = np.zeros((M,N), dtype=np.int32) | |
| angle = D * 180. / np.pi | |
| angle[angle < 0] += 180 | |
| for i in range(1,M-1): | |
| for j in range(1,N-1): | |
| try: | |
| q = 255 | |
| r = 255 | |
| #angle 0 | |
| if (0 <= angle[i,j] < 22.5) or (157.5 <= angle[i,j] <= 180): | |
| q = img[i, j+1] | |
| r = img[i, j-1] | |
| #angle 45 | |
| elif (22.5 <= angle[i,j] < 67.5): | |
| q = img[i+1, j-1] | |
| r = img[i-1, j+1] | |
| #angle 90 | |
| elif (67.5 <= angle[i,j] < 112.5): | |
| q = img[i+1, j] | |
| r = img[i-1, j] | |
| #angle 135 | |
| elif (112.5 <= angle[i,j] < 157.5): | |
| q = img[i-1, j-1] | |
| r = img[i+1, j+1] | |
| if (img[i,j] >= q) and (img[i,j] >= r): | |
| Z[i,j] = img[i,j] | |
| else: | |
| Z[i,j] = 0 | |
| except IndexError as e: | |
| pass | |
| return Z | |
| def gaussian_kernel(size, sigma=1): | |
| size = int(size) // 2 | |
| x, y = np.mgrid[-size:size+1, -size:size+1] | |
| normal = 1 / (2.0 * np.pi * sigma**2) | |
| g = np.exp(-((x**2 + y**2) / (2.0*sigma**2))) * normal | |
| return g | |
| def sobel_filters(img): | |
| Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], np.float32) | |
| Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], np.float32) | |
| Ix = ndimage.filters.convolve(img, Kx) | |
| Iy = ndimage.filters.convolve(img, Ky) | |
| G = np.hypot(Ix, Iy) | |
| G = G / G.max() * 255 | |
| theta = np.arctan2(Iy, Ix) | |
| return (G, theta) | |
| def canny(img, kernel, sigma): | |
| img_color = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | |
| img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | |
| img_gaussian = convolve(img_gray, gaussian_kernel(kernel, sigma)) | |
| G, theta = sobel_filters(img_gaussian) | |
| img_nonmax = non_max_suppression(G, theta) | |
| img_threshold = threshold(img_nonmax) | |
| img_final = hysteresis(img_threshold) | |
| return img_final | |
| interface = gr.Interface( | |
| title = "Canny Edge Detector π€", | |
| description = "<h3>The Canny edge detector is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images.</h3> <br> <b>Select an image πΌ</b>", | |
| article='Step-by-step on GitHub <a href="https://github.com/Ivanrs297/machine-learning-projects/blob/main/computer-vision/edge_detection/main.ipynb"> notebook </a> <br> ~ Ivanrs', | |
| allow_flagging = "never", | |
| fn = canny, | |
| inputs = [ | |
| gr.Image(), | |
| gr.Slider(1, 9, step = 1, value=3, label = "Kernel Size"), | |
| gr.Slider(1, 20, step = 5, value=10, label = "Sigma"), | |
| ], | |
| outputs = "image" | |
| ) | |
| interface.launch(share = False) |