학습한 prewitt, sobel, canny에 대해 python으로 구현을 해봅시다.
Code
import cv2
import time
import numpy as np
import math
from matplotlib import pyplot as plt
def padding(img, n):
x, y = img.shape # original image size
padding_img = np.zeros((x+2*n, y+2*n)) # consider up,down,left,right
padding_img[n:x+n, n:y+n] = img # zero padding
return padding_img
def edge_detection(img, mask1, mask2, threshold):
img = padding(img,1)
result1 = np.zeros(np.array(img.shape))
result2 = np.zeros(np.array(img.shape))
for h in range(1, img.shape[0] - 1):
for w in range(1, img.shape[1] - 1):
tmp = img[h-1:h+2, w-1:w+2]
result1[h,w] = np.abs(np.sum(tmp*mask1)) # axis of x
result2[h,w] = np.abs(np.sum(tmp*mask2)) # axis of y
result = result1 + result2 # sum of x and y
thr_result = np.zeros(img.shape)
thr_result[result > threshold] = 1 # edge
return thr_result[1:img.shape[0] - 1, 1:img.shape[1] - 1] # return original size
gray_img = cv2.imread('../lena.bmp', cv2.IMREAD_GRAYSCALE)
threshold1 = 100
threshold2 = 200
edge_img = cv2.Canny(gray_img, threshold1, threshold2)
prewitt_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])
prewitt_x = np.array([[1, 0, -1], [1, 0, -1], [1, 0, -1]])
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
sobel_x = np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]])
p = edge_detection(gray_img, prewitt_x, prewitt_y, 100)
s = edge_detection(gray_img, sobel_x, sobel_y, 140)
plt.subplot(1,3,1)
plt.imshow(p, cmap='gray')
plt.title('prewit')
plt.subplot(1,3,2)
plt.imshow(s, cmap='gray')
plt.title('sobel')
plt.subplot(1,3,3)
plt.imshow(edge_img, cmap='gray')
plt.title('canny')
print(p.shape)
print(s.shape)
print(edge_img.shape)
plt.show()
prewitt과 sobel은 행렬을 만든뒤 인풋영상에 각각 x축과 y축에 대해서 edge_detection 함수를 적용한뒤 합한 영상이 아웃풋이 됩니다. canny는 라이브러리를 사용했고 threshold를 지정했습니다. edge_detection 함수에서 컨볼루션 연산을 하기전에 먼저 패딩을해야 영상이 밀리지 않고 원래 자리를 고정할수 있습니다. 그리고 반환할때 원래 영상크기로 패딩을 다시 복원해주면 됩니다.
Result
![]() |
![]() |
![]() |
prewitt과 sobel은 x축 edge와 y축 edge를 겹치면서 중복된 부분으로 인해 edge가 굵게 나타난 반면 canny는 더 얇게 edge를 검출한 모습입니다. canny는 두가지로 threshold를 지정할수 있어 더 정밀한 edge 검출에서 용이하겠습니다.
감사합니다.
'컴퓨터 비전 > 실습' 카테고리의 다른 글
mean shift 직접 구현하기(python) (0) | 2023.01.31 |
---|---|
kmeans 직접 구현하기(python) (1) | 2023.01.25 |
SIFT 직접 구현하기(python) (0) | 2023.01.25 |
Bilateral Filter 직접 구현하기(python) (0) | 2023.01.18 |