#python-3.x #opencv #template-matching
#python-3.x #opencv #сопоставление шаблонов
Вопрос:
Я пытаюсь выполнить некоторое динамическое сопоставление шаблонов cv2.matchTemplate
. Шаблон:
и изображение, с которым я его сопоставляю, является:
Я настраиваю размер и угол шаблона, а затем беру maxVal
и maxLoc
из cv2.matchTemplate
и сохраняю их в dict
maxVal
качестве ключей. Затем я max(data.keys())
выбираю «лучшее» совпадение result = cv2.matchTemplate(image, resized_template, cv2.TM_CCORR_NORMED)
. Когда я перебираю все ключи и отображаю их на изображении, есть некоторые, которые находят голову Микки намного лучше, чем max(data.keys())
.
Это область для «наилучшего» соответствия:
#Find best match from scores
best_match = max(scores.keys())
#Output image
image_copy = color_image.copy()
#Create rectangle around best match
cv2.rectangle(image_copy, (data[best_match][1][0], data[best_match][1][1]), (data[best_match][1][0] data[best_match][0][0], data[best_match][1][1] data[best_match][0][1]), (255, 255, 255), 2)
plt.imshow(image_copy)
Но эта область, похоже, определяет ее местоположение гораздо точнее:
image_copy = color_image.copy()
for n in list(data.keys())[69:70:1]:
#Create rectangle around best match
cv2.rectangle(image_copy, (data[n][1][0], data[n][1][1]), (data[n][1][0] data[n][0][0], data[n][1][1] data[n][0][1]), (255, 255, 255), 2)
cv2.imwrite('output_1.jpg', image_copy)
plt.imshow(image_copy)
Я не понимаю, что maxVal
cv2.matchTemplate
на самом деле представляет собой from? Если да, то как я могу выбрать фактический «лучший» регион на основе некоторого значения или критериев? Вот полный код:
#Import packages
import numpy as np
import matplotlib.pyplot as plt
import cv2
import imutils
import os
#Import template
template = cv2.imread(templates_dir '\' os.listdir(templates_dir)[3])
gray_template = cv2.cvtColor(template, cv2.COLOR_RGB2GRAY)
#Import image
image = cv2.imread(images_dir '\' os.listdir(images_dir)[5])
color_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
#Image dims
image_h = image.shape[1]
image_w = image.shape[0]
#Processing loop scaling the template
#Scores dict
scores = {}
#Data dict of structure (maxVal: (template dims, locs, angle))
data = {}
#Edge images
template = cv2.Canny(gray_template, 80, 200)
image = cv2.Canny(gray_image, 80, 200)
#Loop through different template scales
for scale in np.linspace(0.2, 1.5, 15):
#Loop through different template rotations
for angle in np.linspace(0, 360, 25)[:-1]:
#Rotate template
template_rotated = imutils.rotate(template, angle)
#Resize template
resized_template = imutils.resize(template_rotated, width = int(template_rotated.shape[0] * scale))
#Dims of resized template
template_h = resized_template.shape[1]
template_w = resized_template.shape[0]
#Break from loop if the template becomes bigger than the image
if template_h > image_h or template_w > image_w:
break
#Run template through image
result = cv2.matchTemplate(image, resized_template, cv2.TM_CCORR_NORMED)
#Get matching score and location
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
#Add correlation value and result to scores
scores[str(maxVal)] = result
#Add info to data
data[str(maxVal)] = ((template_h, template_w), (maxLoc[0], maxLoc[1]), angle)
#Find best match from scores
best_match = max(scores.keys())
#Output image
image_copy = color_image.copy()
#Create rectangle around best match
cv2.rectangle(image_copy, (data[best_match][1][0], data[best_match][1][1]), (data[best_match][1][0] data[best_match][0][0], data[best_match][1][1] data[best_match][0][1]), (0, 0, 255), 2)
plt.imshow(image_copy)