Как найти несколько ключевых точек на изображении с помощью Python? - PullRequest
0 голосов
/ 28 июня 2018

Я знаю, что функция matchtemplate в Opencv-python может соответствовать изображению 2 из рисунка 1.

import cv2


template = cv2.imread("1.bmp")
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)


edged = cv2.imread("2.bmp")
edged = cv2.cvtColor(edged, cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(edged, 50, 200)


result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF_NORMED)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)

Но если у меня есть только пиксели, подобные изображению 3, как мне соответствовать изображению 1?

рисунок 3. Некоторые пиксели на рисунке два выделены, а остальные заполнены красным.

Я не нашел opencv-python или PIL-решения. Я думаю, что это можно решить путем обхода пикселей, но это не гарантирует производительность. Так есть ли лучший способ?

1 Ответ

0 голосов
/ 29 июня 2018

Согласно ответу Нираджа Комуравалли на этот вопрос , matchTemplate поддерживает аргумент mask как способ исключения определенных пикселей в шаблоне из рассмотрения в соответствующих ( документах). ).

Чтобы сгенерировать маску на основе красных пикселей, простое решение состоит в том, чтобы использовать логическое выражение для выбора тех пикселей, которые 0 синим и зеленым, но 255 красным:

mask = (template[:,:,0]==0) & (template[:,:,1]==0) & (template[:,:,2]==255)
mask = ~mask
mask = mask.astype(np.uint8)

Обратите внимание, что преобразование в uint8 необходимо, поскольку маска должна иметь тот же тип данных, что и шаблон.

Редактировать: ~mask инвертирует маску (0 становится 1 и наоборот), что необходимо, поскольку 0 указывает пиксели, которые должны быть маскированы, по крайней мере, при использовании метода cv2.TM_CCORR_NORMED.


Хотя это в принципе решает ваш вопрос, в этом случае оно не даст рабочего решения.

Это из-за фильтра Канни Край, который применяется к изображениям. Поскольку при применении Canny невозможно замаскировать красные пиксели в шаблоне, границы областей красных пикселов будут влиять на результат обнаружения краев и, таким образом, изменять шаблон так, чтобы он выглядел совершенно иначе, чем оригинал.

В этом примере сопоставление завершается ошибкой, возвращая позицию, которая является полностью неправильной.

Удаление шагов Canny решает эту проблему ... но также делает подход менее надежным / точным. В этом случае сопоставление фактически заканчивается в нескольких пикселях от 100% правильного соответствия. К сожалению, я не могу придумать какие-либо способы улучшить это.


Вот полный код, который работает для меня (с вышеупомянутой оговоркой с точки зрения точности):

import cv2
import numpy as np

template = cv2.imread("masked_template.png")

mask = (template[:,:,0]==0) & (template[:,:,1]==0) & (template[:,:,2]==255)
mask = mask.astype(np.uint8)

template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
#template = cv2.Canny(template, 50, 200)

edged = cv2.imread("edged.png")
edged = cv2.cvtColor(edged, cv2.COLOR_BGR2GRAY)
#edged = cv2.Canny(edged, 50, 200)

result = cv2.matchTemplate(edged, template, cv2.TM_CCORR_NORMED, mask=mask)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...