-
Harris Corner DetectionRobotics/Open CV python 2019. 7. 19. 14:30
Harris Corner Detection
이 글에서 우리는 Harris Corner Detection 에 대한 개념을 이해합니다.
우리는 cv2.cornerHarris(),cv2.cornerSubPix() 함수에 대해서 살펴볼 예정입니다.
Theory
이전 단원에서 우리는 모서리가 모든 방향의 Variation 의 강도가 큰 이미지의 영역이라는 것을 알았습니다. 이 모서리를 찾는 초기 시도 중 하나는 Chris Harris & Mike Stephensin이 1988 년 Combined Corner and Edge Detector에서 작성한 해리스 코너 탐지기입니다. 그는 이 간단한 생각을 수학적 형식으로 가져갔습니다. 기본적으로(u,v) 변위(위치변화)에 대한 강도의 변화를 찾습니다.
모든방향에 대해서 이는 아래와 같이 표현될 수 있습니다.
Window function 은 rectangular window 나 gaussian window 모두 쓸수 있으며 이는 픽셀 아래에서 weight 을 주는 역할을 합니다. 우리는 아래 function E 를 maximize 해야합니다.
코너에 대해서(주변에 비해서 varation 이 큰 지역) 이것이 의미하기를 우리는 두번째 term (shifted intensity - intensity 의 square) 을 maximize 해야합니다. Taylor Expansion을 위의 방정식에 적용하고 몇가지 수학적 스텝을 가지면 (모든 유도는 텍스트북을 참고하라네요), 우리는 마지막 방정식을 아래와 같이 얻습니다.
여기서 M 은
와 같습니다. I_x 와 I_y 는 이미지의 각 x, y 방향에 대한 derivation 입니다. (cv2.Sobel() 를 이용해서 쉽게 구할수 있다고 합니다.).
이제, 메인 파트에 왔습니다. 이후에 이들은 score 를 생성합니다. 아래의 R 방정식으로 윈도우가 코너를 포함하고 있는지 아닌지에 대해서 결정할 것입니다.
아래와 같을 때
- $\lambda_1$ 와 $\lambda_2$는 M 의 eigen values 입니다.
따라서 이 eigen values 는 이것이 코너인지, 엣지(가장자리)인지 FLAT(평평한지역) 인지 결정하게 합니다.
경우 1) $|R|$ 이 작고, $\lambda_1$과 $\lambda_2$ 가 작을 때, 이 지역은 flat 하다.
경우 2) $R<0$ , $\lambda_1 >> \lambda_2$ 경우, 이 지역은 edge 이다.
경우 3) $R$ 이 매우크고 , $\lambda_1$, $\lambda_2$ 가 매우 큰 클때, $\lambda_1 ~\lambda_2$라면 이 지역은 edge 이다.
이는 아래의 그림에서 전체적으로 설명되어 있습니다.
Harris Corner Detection 의 결과는 이 점수에 기반한 grayscale image 입니다. 적당한 thresholding 은 이미지에서 코너부분을 찾게 해줄 것입니다. 우리는 이것을 간단한 이미지에 대해서 적용 해볼 것입니다.
Harris Corner Detector in OpenCV
OpenCV 에서는 harris corner detector 를 할 수 있는cv2.cornerHarris() 함수를 가지고 있습니다. .
arguments :
- img 인풋이미지, 이는 grayscale 이거나 float32 type 이어야합니다.
- blockSize 코너가 디텍트 되었을 때 그 주변부의 사이즈를 나타낸다.
- ksize Sobel derivative 에서 사용되는Aperture parameter 이다..
- k_Harris detector 의 방정식에서 free parameter 이다.
아래의 예제를 한번 봅시다.
<코드>
import cv2 import numpy as np filename = 'chessboard.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) #result is dilated for marking the corners, not important dst = cv2.dilate(dst,None) # Threshold for an optimal value, it may vary depending on the image. img[dst>0.01*dst.max()]=[0,0,255] cv2.imshow('dst',img) if cv2.waitKey(0) & 0xff == 27: cv2.destroyAllWindows()
이 코드는 아래 3가지 결과를 보여주고 있습니다.
Corner with SubPixel Accuracy
때때로 최대의 정확도로 코너를 찾아야할 경우가 있습니다. OpenCV 는 cv2.cornerSubPix() 함수로부터 코너를 보다 정제하고 sub pixel 정확도로 코너를 감지합니다. 아래에는 한가지 예가 나와있습니다. 일반적으로 우리는 harris corners 를 먼저 찾습니다. 그리고 나서 우리는 이 코너들의 중심점만을 통과시키고 (코너에 있는 모든 픽셀을 사용하면 양이 너무 많기때문에 중심점만을 사용합니다.) 그들의 정재합니다. Harris corners 는 붉은 색 픽셀로 마크 되어있습니다. 또한 refined 된 픽셀은 초록색으로 표현되어 있습니다. 이 함수에 대해서, 우리는 언제 반복루프를 중단해야하는지 조건을 정의해야합니다. 지정된 반복 횟수 또는 특정 정확도가 달성 된 후 (둘 중 먼저 발생하는 시점)에 중지합니다. 또한, 우리는 모서리를 검색 할 중심점 주변부의 크기를 정의해야합니다.
import cv2 import numpy as np filename = 'chessboard2.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.imwrite('subpixel5.png',img)
아래가 코드 실행 결과입니다, 몇가지 중요한 위치가 zoomed window 에서 보여지고 있습니다.
'Robotics > Open CV python' 카테고리의 다른 글
FAST Algorithm for Corner Detection (0) 2019.07.23 SURF (0) 2019.07.22 SIFT (0) 2019.07.19 Shi-Tomasi Corner Detector & Good Features to Track (0) 2019.07.19 Understanding Features (0) 2019.07.19