forked from AhmedGehad1/Computer_Vision
-
Notifications
You must be signed in to change notification settings - Fork 0
/
edge_detection_with_parameters.py
100 lines (91 loc) · 4.07 KB
/
edge_detection_with_parameters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import numpy as np
import cv2
import matplotlib.pyplot as plt
def canny_edge_detection( image_path,g_kernel_size,g_sigma ,lower=-1, upper=-1):
img = cv2.imread(image_path)
img = preprocess_image(img, g_kernel_size, g_sigma)
magnitude, angle = gradient_magnitude_angle(img)
edges = non_maxima_suppression(magnitude, angle)
if lower==-1 and upper==-1:
edges = double_thresholding(edges, 0.2*np.max(edges), 0.7*np.max(edges))
else:
edges = double_thresholding(edges, lower, upper)
edges = check_neighbors(edges)
new_path=save_image(edges)
return new_path
def gaussian_kernel(size, sigma=1):
kernel = np.fromfunction(lambda x, y: (1 / (2 * np.pi * sigma ** 2)) * np.exp(-((x - (size - 1) ** 2 + (y - (size - 1) ** 2)) / (2 * sigma ** 2))), (size, size))
return kernel / np.sum(kernel)
def preprocess_image(img, size, sigma):
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
rows = img.shape[0]
cols = img.shape[1]
gaussian_filter = gaussian_kernel(size, sigma)
img = np.pad(img, (size-1, size-1), mode='constant')
gaussian_img = np.zeros((rows, cols))
for i in range(rows-size):
for j in range(cols-size):
gaussian_img[i, j] = np.sum(img[i:i+size, j:j+size] * gaussian_filter)
return gaussian_img
def gradient_magnitude_angle(img):
sobel_kernel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
sobel_kernel_y = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
rows = img.shape[0]
cols = img.shape[1]
size = 3
img = np.pad(img, (size-1, size-1), mode='constant')
gx = np.zeros((rows, cols))
gy = np.zeros((rows, cols))
for i in range(rows-size):
for j in range(cols-size):
gx[i, j] = np.sum(img[i:i+size, j:j+size] * sobel_kernel_x)
gy[i, j] = np.sum(img[i:i+size, j:j+size] * sobel_kernel_y)
magnitude = np.sqrt(gx**2 + gy**2)
angle = np.arctan2(gy, gx) * 180 / np.pi
angle = np.round((angle%360) / 45) * 45
return magnitude, angle
def non_maxima_suppression(magnitude, angle):
suppressed = np.zeros(magnitude.shape)
for i in range(1, magnitude.shape[0] - 1):
for j in range(1, magnitude.shape[1] - 1):
if angle[i, j] == 0 or angle[i, j] == 180 :
if magnitude[i, j] == max(magnitude[i, j], magnitude[i, j+1], magnitude[i, j-1]):
suppressed[i, j] = magnitude[i, j]
elif angle[i, j] == 45 or angle[i, j] == 225:
if magnitude[i, j] == max(magnitude[i, j], magnitude[i+1, j-1], magnitude[i-1, j+1]):
suppressed[i, j] = magnitude[i, j]
elif angle[i, j] == 90 or angle[i, j] == 270:
if magnitude[i, j] == max(magnitude[i, j], magnitude[i+1, j], magnitude[i-1, j]):
suppressed[i, j] = magnitude[i, j]
elif angle[i, j] == 135 or angle[i, j] == 315:
if magnitude[i, j] == max(magnitude[i, j], magnitude[i+1, j+1], magnitude[i-1, j-1]):
suppressed[i, j] = magnitude[i, j]
return suppressed
def double_thresholding(img:np.ndarray, lower_threshold:float, upper_threshold:float):
n,m = img.shape
marking = np.zeros(img.shape)
for x in range(n):
for y in range(m):
if img[x,y] > upper_threshold:
marking[x,y] = 255
elif img[x,y] < lower_threshold:
marking[x,y] = 0
else:
marking[x,y] = 25
return marking
def check_neighbors(edges):
[rows, cols] = edges.shape
for x in range(rows-1):
for y in range(cols-1):
if edges[x,y] == 25:
if ((edges[x+1,y] == 255) or (edges[x-1,y] == 255) or (edges[x+1,y+1] == 255) or (edges[x+1,y-1] == 255) or
(edges[x-1,y+1] == 255) or (edges[x-1,y-1] == 255) or (edges[x,y+1] == 255) or (edges[x,y-1] == 255)):
edges[x,y] = 255
else:
edges[x,y] = 0
return edges
def save_image(img : np.ndarray ):
img_newname="edge_detected.jpg"
path = "/images/"+img_newname
cv2.imwrite(path, img)
return path