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

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

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

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

Edit: хорошо, я вижу, что необходимо предоставить образцы.

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

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

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

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

дополнительные оригинальные изображение

Edit 2: решение Миши работает даже с некоторыми препятствиями вокруг (работает" прозрачность"). Пример:

шаблон матча успешно

редактировать 3-несколько случаев:

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

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

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

7 ответов


Не похоже, что OpenCV обрабатывает alpha так, как вы этого хотите.

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

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

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

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

map

building

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

misha@misha-desktop:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png 
(163, 244)

наконец, вот!--28-->другой вопрос.

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


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

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

вот изображение шаблона raw на alpha:
raw template image on alpha

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

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

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

matched on dark

поиск на светлом фоне:

matched on light

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


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

параметры:

изображения ...

templ ...

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

метод ...

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

[небольшой Отступление]

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

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

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


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


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


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


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

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

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

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

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, будут числовые проблемы, и вы не можете использовать вторая перекрестная корреляция для исправления первой.