이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html 입니다.
이미지의 특징점인 귀퉁이(Corner) 지점을 추출하는 알고리즘 중 하나인 Harris Corner Detection에 대한 예제를 살펴 봅니다.
import cv2 import numpy as np filename = './data/blox.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) img[dst>0.01*dst.max()]=[0,0,255] cv2.imshow('dst',img) cv2.waitKey(0) cv2.destroyAllWindows()
결과는 아래와 같습니다. 입력 이미지에 대해 Corner로 인식되는 부분에 빨간색 점 표시가 되어 있습니다.
cv2.cornerHarris() 함수의 인자를 살펴보면, 첫번째는 입력 이미지로써 단일 채널 이미지(Grayscale)여야 하며 데이터 타입은 float32입니다. 두번째는 Corner 검출을 위한 알고리즘 수행 중 검사할 이웃 픽셀의 크기입니다. 세번째는 내부적으로 적용할 Sobel 필터링에 대한 인자(Apeture Parameter)입니다. 끝으로 네번째는 방적식의 Harris Detector의 자유변수입니다. cv2.corenrHarris() 함수의 결과로 입력 이미지와 동일한 크기의 2차원 배열이 생성되는데, Corner 지점은 이 배열의 값들 중 최대값의 0.01 배 이상인 지점만을 표시하기 위해 11번 코드가 사용됩니다.
Corner를 cv2.corenrHarris 함수를 통해 추출한 뒤, 이 추출 결과를 이용해 다시 좀더 정밀한 귀퉁이를 추출할 수 있습니다. 이를 SubPixel Accuraacy를 가지는 Corner이라고 합니다. 예제는 다음과 같습니다.
import cv2 import numpy as np filename = './data/blox.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) # Now draw them res = np.hstack((centroids,corners)) res = np.int0(res) img[res[:,1],res[:,0]] = [0,0,255] img[res[:,3],res[:,2]] = [0,255,0] cv2.imshow('dst',img) cv2.waitKey(0) cv2.destroyAllWindows()
결과는 다음과 같습니다.
픽셀이 작아 눈에 보기 힘들 수 있지만, 빨간색의 픽셀이 앞서 언급한 cv2.cornerHarris 함수를 통해 추출한 Corner이고 초록색의 픽셀이 cv2.cornerHarris 함수를 통해 얻은 결과를 활용해 cv2.cornerSubPix 함수를 적용해 좀더 정확한 Corenr의 위치를 추출한 결과입니다.