Как узнать включает или нет изображение №1 объект с изображения №2 с помощью OpenCV?

Встала срочная задача определить присутствует ли объект с изображения на другом изображении. Если другими словами, есть картинка с объектом, на этой картинке кроме объекта ничего нет. На другой картинке данный объект (может быть слегка модифицированный поворот\сжатие\изменение цвета) может присутствовать, а может и нет. И нужно ответить есть ли этот объект на картинке-сцене.


Был наслышан про OpenCV и вот решил его и использовать. Нашел пример SURF Homography. Что получил:


1) Если искомый объект без искажений есть на сцене, то количество «good_matches» невелико (5 ± 2);

max_dist = 0.51 min_dist = 0.03


2) Если искомый объект повернут на 90 градусов на сцене, то количество «good_matches» тож невелико (5 ± 2);

max_dist = 0.55 min_dist = 0.04


3) Если на сцене есть объект условно похожий на искомый, то количество «good_matches» уже больше (15 ± 5);

max_dist = 0.59 min_dist = 0.11


4) Нет объекта или похожего объекта на сцене, количество «good_matches» > 30.

max_dist = 0.79 min_dist = 0.4


Для нахождения max_dist и min_dist использовался FLANN.


Можно ли на основании только max_dist и min_dist делать выводы, какие пограничные их значения рассматривать?

Может есть другой способ определить присутствие объекта на изображении?


Прошу строго не судить, второй день за OpenCV.
  • Вопрос задан
  • 14533 просмотра
Пригласить эксперта
Ответы на вопрос 2
Zenker
@Zenker
Я правильно понимаю, что вы рассчитываете расстояния между дескрипторами и ищите наиболее похожие точки на образце и текущем изображении? Если так, то при таком подходе не учитывается взаимное расположение точек, поэтому едва ли можно судить о наличии объекта на изображении. Я сам с OpenCV знаком мало, поэтому постараюсь в общих чертах описать возможный способ решения:

1) С помощью детекторов локальных особенностей (SIFT/SURF/ORB итд.) находите особые точки на образце и изображении

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

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

4) Самый важный этап. Ложные соответствия обычно хорошо фильтруются алгоритмом RANSAC. Суть тут вот в чем: алгоритм пытается по вышенайденным точкам найти преобразование, которое позволило бы наилучшим образом сопоставить два изображения. Если такое преобразование находится и достаточно большое количество точек подтверждает эту модель(такие точки называют инлайнами), то скорее всего объект на изображении присутствует.

Конкретно в OpenCV есть функция FindHomography, только нужно с ней разобраться. Если я правильно понял, srcPoints и dstPoints — массивы особых точек на образце и изображении, где элементы с одинаковыми индексами — это и есть пары сопоставленных точек. Возвращает матрицу преобразования H, но как сигнализируется об успешности ее поиска — нужно разобраться. Возможно, нагуглить какую-нибудь другую реализацию. Я бы попробовал оценить результат по доле инлайнов в общем количестве точек.
Поподробнее про RANSAC и подобную задачу в целом можно почитать тут: engineering.purdue.edu/kak/courses-i-teach/ECE661.08/solution/hw4_s1.pdf
Ответ написан
becks
@becks Автор вопроса
Огромное спасибо за исчерпывающий ответ. Сам на выходных еще почитал по теме, сейчас понимаю уже больше. Распишу, что и как делаю, уже с учетом вашего ответа.

1) С помощью SURF ( класс SurfFeatureDetector, метод detect) определяю ключевые точки на образце и изображении.
2) Для найденных точек рассчитываю значения дескрипторов ( класс SurfDescriptorExtractor, метод compute).
3) Сопоставляю точки на целевом объекте и в сцене, получаю так называемые матчи ( FLANN, класс FlannBasedMatcher, метод match).

Тут я как раз и хотел измерять расстояние между «матчами», но только не по min, max как описал в посте, а по среднему. И, если это значение меньше какого-то пограничного значения, то это говорит о нахождении картинки1 на картинке2. Но поскольку вы подсказываете, что количество ложных срабатывай велико, пока отказываюсь от этого варианта.

4) В том примере, который я как раз и нашел (переделываю) используется как раз findHomography. docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html
Mat H = findHomography( obj, scene, CV_RANSAC );
CV_RANSAC — как раз использую RANSAC.
Но вот ее назначения я совсем не понимаю и как из матрицы преобразований H получить точные соответствия или что-то другое, что можно использовать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы