학습한 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 |