Edge๋ ๊ฐ(๋ฐ๊ธฐ, color, โฆ)์ด ์ฐจ์ด๊ฐ ๋๋ ๊ฒฝ๊ณ๋ฅผ ์๋ฏธํ๋ค. ์ธ๊ฐ์ ์ด๋ ํ ์ด๋ฏธ์ง๋ก๋ถํฐ๋ ์ด edge๋ฅผ ์ฝ๊ฒ ์ธ์งํ ์ ์๋ค. ๊ทธ๋ฌ๋ ์ปดํจํฐ๋ ์ด ์์ ์ ํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด๋ฌํ edge detection์ ์ ํ์ํ ๊น? ์ต๊ทผ ์ฌ๋ฌ ์๋์ฐจ ํ์ฌ์์ ์ ๋ณด์ด๊ณ ์๋ ์์จ ์ฃผํ ์๋น์ค๋ฅผ ์๋ก ๋ค์๋ฉด, ์ฐจ์ ์ธ์๋ ์ด๋ฐ edge detection์ ์ผ์ข ์ผ๋ก ๋ณผ ์ ์๋ค. ๋ฟ๋ง ์๋๋ผ ์๋ฃ์ฉ์ด๋ ๋ค์ํ ๊ณณ์ edge detection์ด ์ฌ์ฉ๋๋ค.
์ด๋ฌํ edge๋ฅผ detectํ๊ธฐ ์ํด์๋ ํฝ์
์ ๊ฐ์ด ๊ธ๊ฒฉํ ๋ณํ๋ ๋ถ๋ถ์ ์ฐพ๋๋ค. ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก๋ 1์ฐจ ๋ฏธ๋ถ์ ํตํด ๊ทธ ๊ฐ์ด ํฐ ๋ถ๋ถ์ ์ฐพ๋ ๊ฒ์ด๋ค. ์ฆ, 1์ฐจ ๋ฏธ๋ถ์ ๋ณํ์จ์ด ํฐ ๊ณณ์ ์ฐพ๋๋ค. ๊ทธ ํ threshold๋ฅผ ์ ํด ๊ทธ ์์ ํด๋นํ๋ ๋ถ๋ถ๋ง edge๋ผ๊ณ ๊ฒ์ถํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
Sobel Filter๋ฅผ ์ฌ์ฉํด Edge Detection์ ์ํํ์๊ณ , Python์ผ๋ก ๊ตฌํํ์๋ค. ์ฒซ๋ฒ์งธ๋ก, ๊ตฌํ์ ์ํด ํ์ํ ๋ผ์ด ๋ธ๋ฌ๋ฆฌ ๋ฐ ๋ชจ๋์ importํ๋ค.
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
๊ทธ ํ, x์ y๋ฐฉํฅ์ผ๋ก ์ ์ฉํ sobel ํํฐ array๋ฅผ ๋ง๋ ๋ค.
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
sobel_y = np.array([[ 1, 2, 1], [ 0, 0, 0], [-1,-2,-1]])
์ด๋ ๊ฒ ๋ง๋ ํํฐ๋ฅผ ์ด๋ฏธ์ง์ ๊ฐ๊ฐ ์ ์ฉ์ํค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
def edge_detection(img, filter_x, filter_y, threshold, show_img=True):
img_shape = img.shape
filter_size = filter_x.shape
# Edge Detection์ ์ ์ฅํ array
result_arr = tuple(np.array(img_shape)-np.array(filter_size)+1)
# ๊ฒฐ๊ณผ ํ๋ ฌ ์ด๊ธฐํ
x_result = np.zeros(result_arr)
y_result = np.zeros(result_arr)
# edge detetion ์ํ
for h in range(0, result_arr[0]):
for w in range(0, result_arr[1]):
# ํํฐ ์ ์ฉ
tmp = img[h:h+filter_size[0],w:w+filter_size[1]]
# x์ถ ์ ์ฉ
x_result[h,w] = np.abs(np.sum(tmp*filter_x))
# y์ถ ์ ์ฉ
y_result[h,w] = np.abs(np.sum(tmp*filter_y))
๋ ๋ฐฉํฅ์ ์ด๋ฏธ์ง๋ฅผ ํฉ์น ํ threshold๋ฅผ ์ ์ฉํ ๋ชจ์ต์ด๋ค. Threshold๋ฅผ ๋๊ฒ ์ค์ ํ ์๋ก ๋ค์ ์ด๊ธฐ๊ตฌ๋ฅผ ๊ฐ์งํ ๋ถ๋ถ์ด ์ฌ๋ผ์ง๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๊ทธ๋ฌ๋ threshold๊ฐ 300์ผ๋์ 500์ผ ๋๋ฅผ ๋น๊ตํด๋ณด๋ฉด 500์ผ๋ ์ฌ์ฑ์ ์ด๊นจ์ ๋ฑ์ชฝ์ ํด๋นํ๋ ๋ถ๋ถ๋ ์ฌ๋ผ์ง๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
# ๋ ๊ฒฐ๊ณผ๋ฅผ ํฉ์น๋ค.
result = x_result + y_result
thr_result = np.zeros(result_arr)
thr_result[result>threshold] = 1
ํด๋น ์ด๋ฏธ์ง์ ๋ท๋ฐฐ๊ฒฝ์ ํด๋นํ๋ ์ด๊ธฐ๊ตฌ ๊ทผ์ฒ๋ฅผ ๋ณด๋ฉด ์ ์ฒ๋ผ ์ธ์๋๋ ๋ถ๋ถ๋ค์ด ์๋ค. ์ด๋ฏธ์ง๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ธ์ด์ฆ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ ๋ฏธ๋ถ์ ํ๊ฒ ๋๋ฉด ๋ ์ฌํด์ง๋ค. ๊ทธ๋ฌ๋ Sobel Filter๋ฅผ ์ ์ฉํ ๋๋ ๋ฏธ๋ถ์ ํ์์์๋ ๋ ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๋ ๊ณผ์ ์ด ์์๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํ ๋ ธ์ด์ฆ๊ฐ ์ปค์ ธ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์์์ ๊ฒ์ด๋ผ ์์ํ ์ ์๋ค. ๋ฐ๋ผ์ ๋ ๋งค๋๋ฝ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด noise๋ฅผ ๊ฐ์์ํค๋ smoothing filter๋ฅผ ์ ์ฉํด noise๋ฅผ ํด๊ฒฐํ๊ณ ์ ํ๋ค.
Gaussian smoothing์ gaussian distribution์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ์ค์ฌ์ ์๋ ํฝ์ ์์๋ถํฐ ๋ฉ์ด์ง ์๋ก ๊ฐ์ค์น๊ฐ ์์์ง๋๋ก ์ค์ ์ด ๋๋ค. ์ฆ, ๊ตฌํ๊ณ ์ํ๋ target pixel์ด ๊ฐ์ฅ ํฐ ๊ฐ์ค์น๋ฅผ ๊ฐ๊ณ ์ค์ฌ์์ ๋ฉ์ด์ง์๋ก ํฝ์ ์ด ์ ์ weight๋ฅผ ๊ฐ๋๋ค.
์ด๋ฐ 2์ฐจ์ ๊ฐ์ฐ์์ ์ปค๋์ ๊ตฌํ๋ ํจ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ์๋ค
def gaussianKernel(size, sigma):
# ์ค์ฌ์ผ๋ก๋ถํฐ ๊ฑฐ๋ฆฌ ๋ฐฐ์ด ์์ฑ
arr_dis = np.arange((size//2)*(-1), (size//2)+1)
# array ์ด๊ธฐํ
arr = np.zeros((size, size))
# ์ค์ฌ์์๋ถํฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ์ ๊ณฑํฉ์ผ๋ก ๊ณ์ฐ
for x in range(size):
for y in range(size):
arr[x,y] = arr_dis[x]**2+arr_dis[y]**2
# ์ปค๋์ ๊ฐ์ ์ ์ฅํ ๋งคํธ๋ฆญ์ค ์์ฑ
kernel = np.zeros((size, size))
# ๊ฐ์ฐ์์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฐ์์ ์ปค๋ ์์ฑ
for x in range(size):
for y in range(size):
kernel[x,y] = np.exp(-arr[x,y]/(2*sigma**2))
# ์ปค๋์ ํฉ์ด 1์ด ๋๋๋ก ์ ๊ทํ
kernel /= kernel.sum()
return kernel
ํด๋น ํจ์๋ฅผ ์ด์ฉํด ์๋ณธ ์ด๋ฏธ์ง์ ์ค๋ฌด๋ฉ์ ์ ์ฉํ ๊ฒฐ๊ณผ๋ ์๋ ์ฌ์ง๊ณผ ๊ฐ๋ค.
์ด์ ๋จ๊ณ์์ ๊ตฌํํ โgaussianKernel()โ์ ์ํํ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง๋ฅผ ๋ค์ Sobel filter๋ฅผ ์ ์ฉํ์ฌ Edge Detection์ ์ํํด๋ณด์๋ค. ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
๊ธฐ์กด์ Sobel Filter๋ง ์ ์ฉํ์ ๋์ ๋น๊ตํ๋ฉด ์ด๊ธฐ๊ตฌ๊ฐ ์๋ ์ชฝ์ ์ ์ฒ๋ผ ์ธ์๋ ๋ถ๋ถ์ด ์ ๊ฑฐ๋์ด ๋ ๊น๋ํด์ง ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์๋ค.
๋ค๋ฅธ ์ด๋ฏธ์ง๋ค์ ์ ์ฉํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.