1. Введение

В этой статье мы сделаем простое сопоставление функций, чтобы разогреться, прежде чем приступить к обнаружению объектов с помощью видеоанализа. Сначала мы сделаем некоторое обнаружение со статическими изображениями.

«Где Уолли» - это популярная британская серия сборников-головоломок, которая вызвала интерес как у детей, так и у взрослых. Найти Уолдо никогда не бывает легко, и у OpenCV есть способ, который может позволить нам быстро найти Уолдо :)

2. Концепции, используемые для сопоставления шаблонов

OpenCV имеет функцию cv2.MatchTemplate (), которая поддерживает сопоставление шаблонов для идентификации целевого изображения.

Сопоставление с шаблоном - это идея перемещения целевого изображения (шаблона) по исходному изображению (входному). Шаблон сравнивается с вводом. Соответствие определяется тем, насколько пиксели соседства во входных данных совпадают с шаблоном.

Существуют различные методы определения сходства. В этом примере мы будем использовать TM.CCOEFF_NORMED

Патч шаблона накладывается на вход с этой матрицей, и он определяет оценку, которая укажет, есть ли совпадение. TM_CCOEFF_NORMED находит среднее значение шаблона и сопоставляет его со средним значением ввода. Оценка 1 - идеальное совпадение, -1 - плохое совпадение, а 0 - нейтральное.

3. В поисках Уолдо

Ниже приведено изображение, которое мы будем использовать для формирования наших входных данных!

Теперь нам понадобится шаблонное изображение, которое, конечно же, будет изображением самого Уолдо.

import cv2
import numpy as np

Две священные библиотеки, необходимые для OpenCV

img_rgb = cv2.imread('find_waldo.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('waldo.png',0)
#saves the width and height of the template into 'w' and 'h'
w, h = template.shape[::-1]

cv2.imread считывает изображение, а cv2.cvtColor преобразует цветное изображение в оттенки серого. Именно так мы обычно выполняем любые операции в OpenCV, поскольку мы уменьшаем размерность и сложность изображения.

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.6
# finding the values where it exceeds the threshold

cv2.matchTemplate () - это функция, в которую мы вводим ввод, шаблон и используемый метод (объяснено выше). Порог - это значение, которое мы используем для определения соответствия, обычно выбирается значение 0,8. Я выбрал 0.6 из-за того, что большинство людей в образе find_waldo сгруппированы и похожи.

loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    #draw rectangle on places where it exceeds threshold
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,0), 2)
cv2.imwrite('found_waldo.png',img_rgb)

Для тех, кто не знаком, zip () - это функция в Python, которая объединяет 2 переменные в 1 кортеж.

Таким образом, мы пытаемся объединить ширину и высоту в один кортеж, известный как «pt». Следовательно, мы добавляем «w» к pt [0], который представляет собой ширину, и «h» к pt [1], который представляет собой высоту.

cv2.Rectangle позволяет рисовать прямоугольник, задавая нижнюю левую и верхнюю правую координаты.

Мы записываем этот результат в файл PNG, известный как found_waldo.png (:

И с этим мы нашли Уолли / Уолли и опознали его по обведенному зеленым прямоугольником!

Полный код, как показано ниже, очень короткий и приятный.

import cv2
import numpy as np
from matplotlib import pyplot as plt
img_rgb = cv2.imread('find_waldo.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('waldo.png',0)
# saves the width and height of the template into 'w' and 'h'
w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.6
# finding the values where it exceeds the threshold
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    #draw rectangle on places where it exceeds threshold
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,0), 2)
cv2.imwrite('found_waldo.png',img_rgb)

4. Дополнительные комментарии

Сопоставление шаблонов интересно выполнять, но у него есть и недостатки.

Простое сопоставление шаблонов не может работать с повернутыми изображениями, перевернутыми изображениями или изображениями в любой другой ориентации.

Чтобы учесть такие эффекты, нам нужно выполнить многоуровневое масштабирование.

И хотя это было весело, обнаружение объектов в динамических ситуациях (например, видео) оказалось бы более полезным. Я очень скоро хочу рассказать о сложном сопоставлении шаблонов и даже обнаружении объектов в видео.

А пока вы можете использовать свои собственные изображения и сначала поиграть с этим простым сопоставлением.

Вы можете получить полный код с фотографиями по моей ссылке на github:

Https://github.com/k-choonkiat/TemplateMatching/tree/master

использованная литература

  1. Https://docs.opencv.org/trunk/dc/dc3/tutorial_py_matcher.html

2. https://pdfs.semanticscholar.org/8ffd/b8a1f629a3bbbd1426206e09c7d9115b8f4b.pdf

3. https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/template_matching/template_matching.html