rueki

Opencv tutorial(python) Template matching 본문

python

Opencv tutorial(python) Template matching

륵기 2020. 7. 1. 21:33
728x90
반응형

Object Detection을 향한 첫 걸음인 템플릿 매칭에 대해서 이번에 알아보도록 하겠다.

템플릿 매칭은 입력영상에서 작은 크기의 부분 영상 위치를 찾아내고 싶은 경우에 사용하며,

템플릿은 찾고자하는 작은크기의 영상이다.

 

찾아내는 과정으로는 템플릿을 입력 영상과의 유사도 혹은 비 유사도를 계산하게 되는데, 

유사도를 계산하는 경우에는  비슷한 부분에서 값이 크게 나올 것이다.

 

opencv 에서는 6가지 method를 소개한다.

 

SQDIFF : 제곱차 매칭 방법 , 유사할 수록 작은 값을 가진다.

CCORR : 상관 관계 매칭방법,  유사할 수록 큰 양수값을 가진다.

CCOEFF : 상관 계수 매칭방법, 비교할 두 영상을 평균밝기로 보정 후에 상관관계 매칭 방법

 

위의 세가지 method에서 각각 정규화 수식이 추가된 SQDIFF_NORMED, CCORR_NORMED, CCOEFF_NORMED 방법이

추가로 제공된다.

 

 

 

 

이 중에서 CCOEFF_NORMED가 좋은 결과를 제공하는 것으로 알려져있으나, 단점으로는 실제 동작시에 계산 량이 많을 수가 있다.

SQDIFF에서는 최솟값 위치를 매칭이 잘 된 위치로 선택해야하며, CCORR,CCOEFF에서는 결과행렬에서 최댓값 위치가 가장 매칭이 잘 된 위치이다.

 

이제 파이썬 코드를 통해 알아보자.

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

#전체 사진, 즉 입력영상 불러오기
full = cv2.imread('파일경로')
full = cv2.cvtColor(full, cv2.COLOR_BGR2RGB)

#이미지 시각화
plt.imshow(full)

 

이제 템플릿으로 사용할 강아지 얼굴을 불러와보자.

#얼굴부분만 인식할 사진 불러오기   
face = cv2.imread('/content/drive/My Drive/vision/DATA/sammy_face.jpg')

#이미지 시각화하기
face = cv2.cvtColor(face,cv2.COLOR_BGR2RGB)
plt.imshow(face)

 

이제 각각의 method들을 적용해보자.

methods = ['cv2.TM_CCOEFF','cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR','cv2.TM_CCORR_NORMED','cv2.TM_SQDIFF','cv2.TM_SQDIFF']

for m in methods:
	full_copy = full.copy()
    method = eval(m)
    
    #template matching , 그레이 스케일로 반환하며, 템플릿과 얼마나 일치하는지 나타낸다.
    res = cv2.matchTemplate(full_copy, face, method)
    min_val,max_val, min_loc, max_loc
    
    
    if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
    	top_left = min_loc
    else:
    	#ccoeff, ccorr에서는 최대값 위치가 가장 매칭이 잘 된 위치이다.
    	top_left = max_loc
        
	height, width, channels = face.shape
    
    #사각형을 그리기위한 오른쪽 밑 지점 잡기
    bottom_right = (top_left[0] + width , top_left[1]+height)
    
    cv2.rectangle(full_copy, top_left, bottom_right, (255,0,0),10)
    
    plt.subplot(121)
    #템플릿 매칭 결과 출력
    plt.imshow(res)
    plt.title('heatmap of template matching)
    
    plt.subplot(122)
    #직사각형 boundary 그린 것 출력
    plt.imshow(full_copy)
    plt.subtitle(m)
    
    plt.show()
    print('\n')

 

 

 

상관계수를 통해서 가장 높게 발견되는 지점을 찾는 것과, 제곱계산법을 이용해서 낮은지점 찾는 것이 제일 매칭이

잘 된것으로 보인다.

728x90
반응형
Comments