Сопоставление нескольких шаблонов
В реальном бою из предыдущей статьи мы выяснили, где он появлялся на изображении через суб-изображение глаз персонажа. Однако в некоторых случаях это происходит не один раз, например, когда мы объясняли преобразование Фурье, мы представили изображение льва на пастбище. Если найдена определенная трава, на одном изображении их может быть много. В настоящее время необходимо найти несколько результатов совпадения.
Функция cv2.minMaxLoc() может найти только максимальное значение и не может предоставить информацию о местоположении всех соответствующих областей. Таким образом, чтобы сопоставить несколько результатов, необходимо выполнить следующие 4 шага:
Получите коллекцию совпадающих местоположений
Во-первых, функция where() в библиотеке Numpy может получить набор местоположений, соответствующих шаблону. Для разных входных данных его возвращаемое значение отличается.
- Когда вход представляет собой одномерный массив, возвращаемое значение представляет собой одномерный индекс, просто массив индексов.
- Когда вход представляет собой двумерный массив, возвращается индекс позиции соответствующего значения, поэтому будет два набора массивов индексов, представляющих позицию возвращаемого значения.
Например, наши изображения в градациях серого обычно представляют собой двумерные массивы. Далее найдем индекс элемента, значение которого больше 8 в двумерном массиве:
import numpy as np
img = np.array([[2, 4, 6, 8, 10], [9, 60, 10, 30, 4], [55, 21, 11, 7, 5]])
result = np.where(img > 5)
print(result)
После запуска консоль выдаст следующее:
Если вы не очень хорошо знаете Numpy. Следующие блоггеры могут в основном понять после преобразования данных. После преобразования формат выглядит следующим образом:
Первая строка — координата X для значений больше 5, а вторая строка — координата Y для значений больше 5. Тогда вышеуказанные индексы массива больше 5: [0,2], [0,3], [0,4], [1,0], [1,1], [1,2], [1,3 ] , [2,0], [2,1], [2,2], [2,3]. Вы можете вернуться назад и сравнить, чтобы увидеть, соответствуют ли они друг другу.
Функцию np.where() можно использовать, чтобы узнать, какие позиции в возвращаемом значении функции cv2.matchTemplate() превышают пороговое значение. Конкретный код операции выглядит следующим образом:
loc=np.where(res>threshold)
цикл
Поскольку мы нашли более одного изображения шаблона, соответствующего исходному изображению, для обработки нескольких значений обязательно будет использоваться цикл. Следовательно, после получения индекса совпадающего значения вы можете использовать следующий оператор для обхода всех совпадающих позиций и пометки этих позиций:
for i in 匹配位置集合:
标记匹配位置
Использование zip() в цикле
Функция zip() принимает в качестве параметра итерируемый объект, упаковывает соответствующие элементы объекта в кортежи и возвращает список этих кортежей.
Например, мы получаем индексы как x, y, z. Ниже мы используем zip() для упаковки их в кортежи. код показывает, как показано ниже:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = np.array([[2, 4, 6, 8, 10], [9, 60, 10, 30, 4], [55, 21, 11, 7, 5]])
result = np.where(img > 5)
for i in zip(*result):
print(i)
Здесь мы по-прежнему используем вышеуказанные значения, и вывод выглядит следующим образом:
Здесь индекс, для которого мы только что выполнили условие, автоматически упаковывается в формат элемента. Является ли он более интуитивным, чем вывод консоли прямо сейчас?
заменить координаты
Результат, который мы получили выше, — это индекс, который соответствует условию: (номер строки, номер столбца), но нам нужно нарисовать прямоугольник в соответствующей позиции, что и нужно (номер столбца, номер строки).
Следовательно, прежде чем использовать cv2.rectangle() для рисования прямоугольника, необходимо поменять местами строку и столбец индекса позиции, полученного функцией numpy.where(), Обмен строки и столбца может быть достигнут с помощью следующего кода:
import numpy as np
img = np.array([[2, 4, 6, 8, 10], [9, 60, 10, 30, 4], [55, 21, 11, 7, 5]])
result = np.where(img > 5)
for i in zip(*result[::-1]):
print(i)
После запуска вывод следующий:
Фактическое сопоставление нескольких шаблонов
Теперь, когда мы рассмотрели 4 шага для маркировки нескольких мест трафарета. Ниже мы непосредственно организуем приведенный выше код для завершения сопоставления нескольких шаблонов. Конкретный код выглядит следующим образом:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("34.jpg", 0)
template = cv2.imread("4_1.jpg", 0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.9
loc = np.where(res >= 0.9)
for i in zip(*loc[::-1]):
cv2.rectangle(img, i, (i[0] + w, i[1] + h), 255, 1)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.show()
Код здесь точно такой же, как и в предыдущих 4 шагах, поэтому я не буду слишком много объяснять. После запуска несколько шаблонов сопоставляются.
приложение:
Диаграмма шаблона
исходное изображение