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

Совместимость шаблонов OpenCV и прозрачность

Как OpenCV обрабатывает прозрачность изображения во время сопоставления с шаблоном?

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

Я пробовал все методы, и ни один из них не дал положительных результатов (например, положение шаблона в исходном изображении не было обнаружено правильно).

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

Исходное изображение

Изображение шаблона

Как вы можете видеть, почти невозможно сопоставить такой шаблон с таким изображением. "Фон" вокруг объекта может иметь любой цвет (например, белый или коричневый...)

Собель на изображении в сером и шаблоне + cvConvertScaleAbs

Дополнительное исходное изображение

Изменить 2: Решение misha работает даже с небольшим количеством препятствий (работает "прозрачность" ). Пример:

Соответствие шаблону

Изменить 3 - множественные вхождения:

Я сделал быстрое и грязное решение для поиска нескольких вхождений шаблона, однако, когда шаблон не найден, я получаю "много" ложных срабатываний. Главным образом из-за моей реализации:

  • итерация по данным изображения
  • if (imageData [y, x, 0] >= maxValue * 0.95f), то он считает [x, y] как совпадение (maxValue от cvMinMaxLoc)

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

4b9b3361

Ответ 1

Кажется, что OpenCV не обрабатывает альфа, как вы хотите.

У вас есть два варианта:

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

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

Другим вариантом является выполнение обнаружения края (например, Sobel) на изображении и шаблоне, а затем выполнить взаимную корреляцию. Вот обнаруженные края изображения (я использовал детектор края Sobel на канале Luma в GIMP, а затем некоторое растяжение интенсивности).

map

building

Как вы можете видеть, альфа-канал здесь стал неактуальным, так как большая часть местности стала нулевой интенсивностью и не будет способствовать вычислению кросс-корреляции. Таким образом, теперь кросс-корреляция может быть непосредственно применена, давая желаемый результат:

[email protected]:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png 
(163, 244)

Наконец, здесь другой связанный вопрос.

PS. Что это за игра?

Ответ 2

У меня есть немного более разумное решение для этой проблемы, которое, по-видимому, работает достаточно хорошо: замените альфа-канал шаблона изображения шумом, который более или менее делает прозрачные области статистически несущественными во время процесса сопоставления.

Например, мой пример использования заключался в поиске символов emoji при захвате экрана из iOS. Фон клавиатуры iOS меняет цвета в зависимости от контекста, что делает процесс сопоставления проблематичным, если вы фиксируете определенный цвет фона в изображении шаблона.

Здесь изображение необработанного шаблона на альфа:
raw template image on alpha

Здесь обработанный шаблон с заполнением шумом для альфа-канала:
enter image description here

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

Поиск на темном фоне:

matched on dark

Поиск на светлых фонах:

matched on light

По сравнению с тем, что прозрачный альфа-канал шаблона - или переход на темный или светлый фон - не возвратил приемлемых совпадений.

Ответ 3

OpenCV 3.0 предлагает встроенную поддержку сопоставления шаблонов с замаскированными шаблонами. Обратитесь к новой документации:

Параметры:

image...

templ...

результат...

метод...

Маска

Маска найденного шаблона. Он должен иметь одинаковый тип данных и размер с templ. Он не установлен по умолчанию.

[Незначительное отступление]

Обратите внимание, что сопоставление шаблонов с замаскированными ссылочными изображениями (большее изображение) невозможно. И это имеет смысл, учитывая, что OpenCV использует сопоставление шаблонов на основе FFT.

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

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

Ответ 4

Опция SQDIFF/SQDIFF_N будет решением, если вы попытаетесь заменить альфа-канал черным цветом RGB. По крайней мере, это было мое решение той же проблемы. Из моего результата очевидно, что этот метод чувствителен к более ярким значениям пикселей, и я воспользовался возможностью этого.

Ответ 5

Я думаю, вы пытаетесь сделать то, что в OpenCV называется шаблоном, соответствующим маскам. Я думаю, вы могли бы попытаться установить ROI (область интересов) в шаблоне. Этот вопрос SO показывает, как это сделать. (обратите внимание, что в этом вопросе ROI устанавливается на целевом изображении, а не в шаблоне, но процедура такая же).

Ответ 6

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

Ответ 7

Я столкнулся с той же проблемой, и я подумал о решении. Предполагая, что referenceImageMask и templateMask имеют 1s в хороших пикселях и 0s в плохих. И этот referenceImage и templateImage уже замаскированы и имеют 0s в плохих пикселях.

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

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

Затем нормализация корреляции на это число должна дать значение, которое вам (и I) нужно. Средний продукт для пикселей, которые не замаскированы на обоих изображениях.

Image<Gray, float> imCorr = referenceImage.MatchTemplate(templateImage,      Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
Image<Gray, float> imCorrMask = referenceImageMask.MatchTemplate(templateMask, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
_imCorr = _imCorr.Mul(_imCorrMask.Pow(-1));

UPDATE: на самом деле это решение не работает. Поскольку реализация перекрестной корреляции в opencv использует DFT, будут возникать числовые проблемы, и вы не можете использовать вторую кросскорреляцию для исправления первой.