일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 프로그래머스
- object detection
- Python
- reinforcement learning
- 백준
- coding test
- computer vision
- 내용추가
- 모두를 위한 딥러닝
- 논문
- 알고리즘
- Today
- Total
NISSO
[OpenCV] Template Matching 본문
Template Matching (템플릿 매칭)
object detection의 가장 단순하고 기본적인 형태로, 이미지 내에서 탐지하려는 객체가 포함된 '템플릿' 이미지를 찾는 것이다.
템플릿 이미지를 입력 이미지에서 슬라이딩시켜 전체 이미지에 대해 매칭하면서 두 이미지의 유사도를 계산한다.
이 때 openCV의 cv2.matchTemplate() 함수를 사용한다.
cv2.matchTemplate(image, templ, method, result=None, mask=None)
image : 입력 이미지
templ : 템플릿 이미지
method : 매칭 방법. 이에 따라 유사도 계산 방법이 달라진다.
result : 매칭 결과 행렬. (W - w + 1) * (H - h + 1) 크기의 2차원 array (W,H : image 너비와 높이 / w,h : templ 너비와 높이)
mask : 매칭을 입력 이미지 전체에서 할지, 일부분에서만 할지 결정하는 인자
Template Matching Method
cv2.TM_SQDIFF / cv2.TM_SQDIFF_NORMED
cv2.TM_CCORR / cv2.TM_CCORR_NORMED
cv2.TM_CCOEFF / cv2.TM_CCOEFF_NORMED
총 6개의 매칭 방법이 있다.
TM은 Template Matching의 약자, NORMED가 붙은 방법은 앞의 방법으로 계산한 결과를 [0,1]로 정규화한 것이다.
cv2.TM_SQDIFF
SQDIFF : Sum of Squared Difference
cv2.TM_SQDIFF와 cv2.TM_SQDIFF_NORMED는 가장 어두운 곳이 매칭된다. ( 나머지 4개는 가장 밝은 곳이 매칭된다. )
R = { (템플릿 이미지의 픽셀값) - (부분 이미지의 픽셀값) } 의 제곱을 모두 더한 것으로,
완전 일치하면 R = 0(검은색), 유사하지 않으면 R = 255
* 부분 이미지 : 입력 이미지에서 템플릿 이미지와 매칭시킬 위치의 일부분. 템플릿 크기와 같다.
cv2.TM_CCORR
CCORR : Cross Correlation
가장 어두운 곳으로 매칭하는 방법으로, 템플릿 이미지와 부분 이미지의 상관관계를 계산한다.
R = { (템플릿 이미지의 픽셀값) * (입력의 부분 이미지의 픽셀값) } 을 모두 더한 것으로,
완전 일치하면 R = 255, 유사하지 않으면 R = 0
cv2.TM_CCOEFF
CCOEFF : Correlation Coefficient
가장 어두운 곳으로 매칭하는 방법으로, 밝기를 보정한 cv2.TM_CCORR 방법이다.
R = Σ(T' * I') = { (템플릿 이미지 - 템플릿 이미지의 평균값) } * { (부분 이미지 - 부분 이미지의 평균값) } 을 더한 것으로,
각 이미지에서 이미지의 평균값을 빼줌으로써 밝기 보정을 할 수 있다.
완전 일치하면 R = 255, 유사하지 않으면 R = 0
cv2.TM_CCOEFF_NORMED : 완전 일치하면 1, 역일치하면 -1, 상호 연관성이 없으면 0
Bounding Box
cv2.minMaxLoc(result)
매칭된 유사도의 최소 / 최대값과, 위치의 좌측 상단 꼭지점 좌표를 반환한다.
이 좌표에서 템플릿 이미지의 너비와 높이만큼 box를 치면 매칭된 bounding box가 된다.
min_val, max_val, min_loc, max_loc 로 반환되는데,
cv2.TM_SQDIFF(_NORMED) 방법은 값이 낮을수록 좋은 매칭이므로, min_val과 min_loc을 사용한다.
Sample Code
import cv2
import numpy as np
img = cv2.imread('image.jpg')
template = cv2.imread('template.jpg')
h, w = template.shape[:2]
# 모든 매칭 방법 사용
methods = ['cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_CCORR_NORMED',
'cv2.TM_CCORR', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_SQDIFF']
for method_name in methods:
img2 = img.copy()
method = eval(method_name)
res = cv2.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# TM_SQDIFF : 최소값이 good matching
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
match_val = min_val
else:
top_left = max_loc
match_val = max_val
# bounding box 표시
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img_draw, top_left, bottom_right, (0,0,255),2)
# matching value 표시
cv2.putText(img2, str(match_val), top_left, cv2.FONT_HERSHEY_PLAIN,2,(0,255,0),1,cv2.LINE_AA)
cv2.imshow(method_name, img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Template Matching의 단점
- scale(크기)에 민감 : 같은 크기의 sliding window로 템플릿을 매칭시켜가며 찾기 때문에 크기에 민감하다. 템플릿이나 원본 이미지의 크기를 변형시키며 매칭하는 방법으로 해결해야 한다. --> multi scale template matching
- rotation(회전)에 민감 : 위와 같은 이유로 회전에 민감하다. 이 또한 회전시켜가며 매칭할 수 있지만, 각도가 조금만 다르면 성능이 떨어진다.
이와 같은 문제점으로, SIFT 알고리즘을 사용해봤다.
SIFT : Scale Invariant Feature Transform
크기에 불변하는 성질을 가진 특징점 매칭 방법이며, 회전에도 성능이 비교적 잘 나온다.
SIFT에 대해선 다음에 포스팅하도록 하겠다.
참고자료
- https://www.pyimagesearch.com/2021/03/22/opencv-template-matching-cv2-matchtemplate/
- https://deep-learning-study.tistory.com/242
- https://dsbook.tistory.com/134
- https://bkshin.tistory.com/entry/OpenCV-25-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A7%A4%EC%B9%AD-%ED%8F%89%EA%B7%A0-%ED%95%B4%EC%8B%9C-%EB%A7%A4%EC%B9%AD-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A7%A4%EC%B9%AD
'Computer Vision' 카테고리의 다른 글
[Object Detection] Sliding Windows Detection (0) | 2021.10.13 |
---|---|
[개념정리] IOU (Intersection Over Union)와 mAP (mean Average Precision) (1) | 2021.10.12 |
[용어] ML/DL에서 Ground-truth와 label의 차이 (0) | 2021.09.07 |
[CBIR] Content-based Image Retrieval (2) | 2021.09.07 |