Подтвердить что ты не робот

Как найти шаблон в изображении с помощью маски (или прозрачности) с помощью OpenCV и Python?

Предположим, мы ищем этот шаблон:

Stop

Углы нашего шаблона прозрачны, поэтому фон будет разным, например:

Stop on moon

Stop on everest

Stop on leaves

Предполагая, что мы можем использовать следующую маску с нашим шаблоном:

Stop Stop mask

Это было бы очень легко найти.

Что я пробовал:

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

Я также изучил "область интересов", которая, как я думал, будет решением, но с ее помощью вы можете указать только прямоangularьную область. Я даже не уверен, работает ли он на шаблоне или нет.

Я уверен, что это возможно сделать, написав свой собственный алгоритм, но я надеялся, что это возможно через. стандартный OpenCV, чтобы не изобретать велосипед. Не говоря уже о том, что он, скорее всего, будет более оптимизирован, чем мой.

Итак, как я могу сделать что-то подобное с OpenCV + Python?

4b9b3361

Ответ 1

Этого можно достичь, используя только функцию matchTemplate, но требуется небольшой обходной путь.

Давайте проанализируем показатели по умолчанию (CV_TM_SQDIFF_NORMED). Согласно документации matchTemplate показатели по умолчанию выглядят следующим образом

R(x, y) = sum (I(x+x', y+y') - T(x', y'))^2

Где I - матрица изображения, T - шаблон, R - матрица результатов. Суммирование выполняется по координатам шаблона x' и y',

Итак, давайте изменим эту метрику, вставив весовую матрицу W, которая имеет те же размеры, что и T.

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2

В этом случае, установив W(x', y') = 0, вы можете фактически игнорировать пиксель. Итак, как сделать такие метрики? С простой математикой:

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2
        = sum W(x', y')*(I(x+x', y+y')^2 - 2*I(x+x', y+y')*T(x', y') + T(x', y')^2)
        = sum {W(x', y')*I(x+x', y+y')^2} - sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} + sum{W(x', y')*T(x', y')^2)}

Итак, мы разделили метрики Q на отдельные суммы деревьев. И все эти суммы могут быть рассчитаны с функцией matchTemplate (используя метод CV_TM_CCORR). А именно

sum {W(x', y')*I(x+x', y+y')^2} = matchTemplate(I^2, W, method=2)
sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} = matchTemplate(I, 2*W*T, method=2)
sum{W(x', y')*T(x', y')^2)} = matchTemplate(T^2, W, method=2) = sum(W*T^2)

Последний элемент является константой, поэтому для минимизации он не имеет никакого эффекта. С другой стороны, мне все еще может быть полезно посмотреть, есть ли у нашего шаблона идеальное совпадение (если Q приближается к нулю). Тем не менее, для последнего элемента нам фактически не нужна функция matchTemplate, поскольку она может быть вычислена напрямую.

Последний псевдокод выглядит следующим образом:

result = matchTemplate(I^2, W, method=2) - matchTemplate(I, 2*W*T, method=2) + as.scalar(sum(W*T^2))

Это действительно так, как определено? Математически да. Практически, есть небольшая ошибка округления, потому что функция matchTemplate работает с 32-битной плавающей точкой, но я считаю, что это не большая проблема.

Обратите внимание, что вы можете расширить анализ и иметь взвешенные эквиваленты для любых показателей, предлагаемых matchTemplate.

Это на самом деле работает для меня. Извините, я не даю фактический код. Я работаю в R, так У меня нет кода на Python. Но идея довольно проста.

Я надеюсь, это поможет.

Ответ 2

Один ответ на ваш вопрос - convolution. Используйте шаблон в качестве ядра и фильтруйте изображение.

Матрица назначения будет иметь плотные яркие области, где может быть ваш шаблон. Вам придется сгруппировать результаты (например, среднее смещение).

Таким образом, у вас будет очень упрощенная реализация Обобщенного преобразования Хафа или сопоставление сверток на основе шаблонов.

Ответ 3

Что работало для меня однажды, когда мне это нужно, это заполнить области "маска" белым шумом. Затем он становится эффективно вымытым из корреляции при поиске совпадений. В противном случае я получил, как я полагаю, сделал, ложные совпадения в замаскированных областях.

Ответ 4

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

compare -verbose -dissimilarity-threshold 0.1 -subimage-search subimage bigimage

Я использовал его для поиска и размывания водяных знаков с некоторых продуктов. Не спрашивайте.

(Иногда вам нужно делать то, что вам нужно делать.)

Ответ 5

Imagemagick 7.0.3.9 теперь имеет маскированную возможность сравнения, поэтому вы можете ограничить область соответствия шаблонов. См. http://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=31053

Кроме того, я вижу, что OpenCV 3.0 теперь маскирует соответствие шаблонов. См. http://docs.opencv.org/3.0.0/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be

Однако, это только для метода == CV_TM_SQDIFF и метода == CV_TM_CCORR_NORMED. см. python opencv matchTemplate реализована функция маски?