일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Web Programming
- Tkinter
- FLASK
- 컴퓨터 비전
- Django
- 장고
- Deep Learning
- Docker
- 데이터베이스
- kubernetes
- 그래픽 유저 인터페이스
- vue.js
- yaml
- POD
- 파이썬
- k8s
- pytorch
- 논문 리뷰
- GUI
- tensorflow
- MariaDB
- OpenCV
- paper review
- Computer Vision
- numpy
- 딥러닝
- 텐서플로우
- 웹 프로그래밍
- Python
- 파이토치
- Today
- Total
Maxima's Lab
[Python, Opencv] Template matching (템플릿 매칭) 본문
Template matching (템플릿 매칭)
오늘은 Template matching을 통해 Original Image 내 Template Image와 유사(일치)한 영역을 찾는 알고리즘입니다.
위의 알고리즘을 적용하기 위해 필요한 사항들은 다음과 같습니다.
※ opencv의 cv2.matchTemplate(), cv2.minMaxLoc() 함수 사용
- Original Image (원본 이미지)
- Template Image (템플릿 이미지)
- Template matching 방법
위의 3가지 사항을 적용하기 이전, cv2.minMaxLoc() 함수에 대해서 알아보겠습니다.
- cv2.minMaxLoc() : array에서 global minimum(전역 최소값)과 global maximum(전역 최대값)을 구하는 함수
import numpy as np
import cv2
arr = np.array([1, -2, 0, 7])
cv2.minMaxLoc(arr)
Output : (-2.0, 7.0, (0, 1), (0, 3))
결과값을 Tuple의 형태로 반환하며, 이는 (최소값, 최대값, 최소값의 위치, 최대값의 위치)를 의미합니다.
1-D array의 경우임에도 불구하고 (x, y)의 형태로 위치값을 반환합니다. (단, x=0)
2-D array의 경우는 다음과 같습니다.
import numpy as np
import cv2
arr = np.array([[-5, 2, 3, 10],
[6, 11, -2, 5]])
cv2.minMaxLoc(arr)
Output : (-5.0, 11.0, (0, 0), (1, 1))
※cv2.minMaxLoc() 함수는 단일 채널(single channel)인 경우에만 적용 가능합니다.
- cv2.matchTemplate() 을 적용하기 위해 6가지 방법들에 대해서 알아보겠습니다.
print(eval('cv2.TM_SQDIFF')) # 0
print(eval('cv2.TM_SQDIFF_NORMED')) # 1
print(eval('cv2.TM_CCORR')) # 2
print(eval('cv2.TM_CCORR_NORMED')) # 3
print(eval('cv2.TM_CCOEFF')) # 4
print(eval('cv2.TM_CCOEFF_NORMED')) # 5
총 6가지 방법들에 대해 순서대로 0, 1, 2, ... , 5 의 정수형을 반환합니다.
- Original Image --> (H, W, C) or (H, w)
- Template Image --> (H_t, W_t, C_t) or (H_t, W_t)
- cv2.matchTemplate(Original Image, Template Image, method_value) --> (H - H_t + 1, W - W_t + 1)
1. Grayscale Image를 이용한 Template matching
import matplotlib.pyplot as plt
import cv2
original_img = cv2.imread("...") # (H, W, C)
template_img = cv2.imread("...") # (H_t, W_t, C_t)
H_t, W_t, _ = template_img.shape
method_index_list = list(range(0, 6)) # [0, 1, 2, 3, 4, 5, 6]
method_list = ['cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED']
for method_index in method_index_list:
original_img_temp = original_img.copy()
####### Convert BGR Image to Grayscale Image #######
original_gray = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY).copy()
template_gray = cv2.cvtColor(template_img, cv2.COLOR_BGR2GRAY).copy()
result_img = cv2.matchTemplate(original_gray, template_gray, method_index)
min_value, max_value, min_location, max_location = cv2.minMaxLoc(result_img)
if method_index in [0, 1]: # 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED'
Top_L = min_location
else:
Top_L = max_location
Bottom_R = (Top_L[0] + W_t-1, Top_L[1] + H_t-1)
cv2.rectangle(original_img_temp, Top_L, Bottom_R, (255, 255, 255), 5)
plt.title("Result Of Template Matching ({})".format(method_list[method_index]))
plt.imshow(original_img_temp)
plt.show()
Template matching 알고리즘 적용을 위해 Original Image와 Template Image를 Grayscale로 변환 후 cv2.matchTemplate() 함수를 적용하였습니다. 이어서 Blue-channel Image를 활용하여 Template matching을 적용해보겠습니다.
2. Blue-channel Image를 이용한 Template matching
import matplotlib.pyplot as plt
import cv2
original_img = cv2.imread("...") # (H, W, C)
template_img = cv2.imread("...") # (H_t, W_t, C_t)
H_t, W_t, _ = template_img.shape
method_index_list = list(range(0, 6)) # [0, 1, 2, 3, 4, 5, 6]
method_list = ['cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED']
for method_index in method_index_list:
original_img_temp = original_img.copy()
####### Blue-Channel Image #######
original_blue = original_img.copy()[:,:,0]
template_blue = template_img.copy()[:,:,0]
result_img = cv2.matchTemplate(original_blue, template_blue, method_index)
min_value, max_value, min_location, max_location = cv2.minMaxLoc(result_img)
if method_index in [0, 1]: # 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED'
Top_L = min_location
else:
Top_L = max_location
Bottom_R = (Top_L[0] + W_t-1, Top_L[1] + H_t-1)
cv2.rectangle(original_img_temp, Top_L, Bottom_R, (255, 255, 255), 5)
plt.title("Result Of Template Matching ({})".format(method_list[method_index]))
plt.imshow(original_img_temp)
plt.show()
기존 Grayscale 변환하였던 위치에서 Blue-channel Image로 수정해주시면 됩니다. 위의 방법과 마찬가지로 Green, Red-channel 및 다른 색상 공간에 대해서도 적용해보시기 바랍니다.
'Python > Opencv' 카테고리의 다른 글
[Python, Opencv] Binary Objects을 포함하는 가장 작은 사각형 찾기 (0) | 2024.03.16 |
---|---|
[Python, Opencv] Mouse Event (마우스 이벤트) (0) | 2022.07.06 |
[Python, Opencv] Edge Detection (엣지 검출) - Sobel Filter (소벨 필터) (1) | 2022.06.29 |
[Python, Opencv] Kmeans Clustering (Image Segmentation) & 3-D Scatter Plot (0) | 2022.06.02 |