Как удалить ложные совпадения из FLANNBASED Matcher в OPENCV?

[Просим вас прочитать детали вопроса, прежде чем пометить его как дубликат или отказаться от голосования. Я тщательно искал и не мог найти решение, и поэтому разместил вопрос здесь.]

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

Мое решение основано на следующем исходном коде:

https://github.com/Itseez/opencv/blob/master/samples/cpp/matching_to_many_images.cpp

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

Я изменил приведенный выше пример и сгенерировал:

 vector<vector<DMatch>> matches;
vector<vector<DMatch>> good_matches;

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

Изменить 1:

Моя реализация выглядит следующим образом:

  1. Для каждого изображения в наборе данных вычисляют дескрипторы SURF.

  2. Объедините все дескрипторы в одну большую матрицу.

  3. Создайте индекс FLANN из объединенной матрицы.

  4. Вычислить дескрипторы для изображения запроса.

  5. Запустите KNN-поиск по индексу FLANN, чтобы найти топ 20 или меньше лучшее соответствие изображения. К установлен как 20.

  6. Отфильтруйте все неадекватные совпадения, вычисленные на предыдущем шаге. (Как??)

Я успешно выполнил шаги с 1 по 5. Я столкнулся с проблемой на шаге 6, когда не могу удалить ложные совпадения.

8

Решение

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

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

Самый простой способ сделать это — объединить дескрипторы локальных объектов в локальный дескриптор. Стандартный метод здесь — «мешок визуальных слов». В OpenCV это называется Bag-Of-Words (например, BOWTrainer, BOWImgDescriptorExtractor так далее). Посмотрите на документацию для использования этого.

Есть некоторый пример кода в samples/cpp/bagofwords_classification.cpp

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

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

Вы не можете удалить очки из FLANN (1, 2, 3). FLANN строит дерево для быстрого поиска. В зависимости от типа дерева удаление узла становится невозможным. Угадайте, что FLANN использует KD-дерево, которое (легко) не позволяет удалять точки.

FlannBasedMatcher не поддерживает маскирование допустимых совпадений наборов дескрипторов, потому что flann :: Index не поддерживает это.

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

редактировать

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

Вам нужны функции DescriptorMatcher::clear() а потом DescriptorMatcher::add(const vector<Mat>& descriptors) за это. Referenz.

11

Другие решения

Во-первых, вам нужно определить «неадекватные совпадения», без этого определения вы ничего не сможете сделать.

Есть несколько свободных определений, которые приходят на ум:

1: неадекватные совпадения = совпадение с расстоянием> предварительно определенное расстояние

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

http://docs.opencv.org/trunk/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html#flann-index-t-radiussearch

2: неадекватные совпадения = совпадение с расстоянием> динамически определенное расстояние на основе найденного k-nn

Это сложнее, и мне кажется, что у меня есть два возможных решения:

2a: Определить некоторый коэффициент теста на основе расстояния первого 1-NN, например:

базовое расстояние = расстояние до 1NN

неадекватное match_k = match distance_k> = a * базовое расстояние;

2b: Использовать метод динамической пороговой привязки, такой как порог Оцу, для нормализованного распределения расстояний для k-nn, таким образом, разделив k-nn на две группы, группа, которая содержит 1-nn, является адекватной группой, другая это неадекватная группа.

http://en.wikipedia.org/wiki/Otsu«S_method,

http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#threshold.

6

По вопросам рекламы [email protected]