OpenCv/С++ - легко найти сходство с картинкой с большой базой данных

Я хотел бы сделать сравнение с запросом с картинками в базе данных (около 2000).

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

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

Сообщения (самые интересные):

Простой и быстрый метод сравнения изображений для сходства;

Ближайшие соседи по высокоразмерным данным?;

Как понять чувствительность локализации?;

Отпечаток пальца для сравнения подобия многих изображений;

С++/SIFT/SQL - если есть способ эффективно сравнить дескриптор SIFT изображения с дескриптором SIFT в базе данных SQL?

документы:

Поиск объектов с большими словарями и быстрое пространственное сопоставление,

Поиск сходства изображений с компактными структурами данных,

LSH,

Ближнее двойное обнаружение изображения min-Hash и tf-idf Weighting

Словарь дерева

Агрегирование локальных дескрипторов

Но я все еще запутался.

Первое, что я сделал, это реализовать BoW. Я проверил "Сумку слов" (с ORB как детектором и дескриптором, а также использовал функции VLAD) с 5 классами, чтобы проверить его эффективность. После долгого обучения я запустил его. Он хорошо работал с точностью 94%. Это очень хорошо.

Но для меня есть проблема:

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

Для этого, вы согласны со мной? Это не лучший способ сделать то, что я хотел бы? Может быть, есть другой способ использовать BoW, чтобы найти сходство в базе данных?

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

std::vector<cv::Mat> all_descriptors_database;
for (i → 2000) :
    cv::Mat request=cv::imread(img);
    computeKeypoints(request) ;
    computeDescriptors(request) ;
    all_descriptors_database.pushback(descriptors_of_request)

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

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

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

Поэтому я хотел использовать этот метод. Так внутри моей петли я сделал что-то вроде этого:

//Create Flann LSH index
cv::flann::Index flannIndex(all_descriptors_database.at(i), cv::flann::LshIndexParams(12, 20, 2), cvflann::FLANN_DIST_HAMMING);
        cv::Mat results, dists;
        int k=2; // find the 2 nearest neighbors
        // search (nearest neighbor)
        flannIndex.knnSearch(query_descriptors, results, dists, k, cv::flann::SearchParams() );

Однако у меня есть несколько вопросов:

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

  • Я нашел в Интернете некоторые библиотеки, которые реализуют LSH, например http://lshkit.sourceforge.net/ или http://www.mit.edu/~andoni/LSH/. Так в чем разница между этими библиотеками и четырьмя строками кода, написанными с помощью OpenCV? Поскольку я проверял библиотеки и для своего начинающего, как я, было так трудно попытаться его использовать. Я немного смутился.

Третье:

Я хотел сделать отпечаток каждого дескриптора для каждого изображения (чтобы вычислить расстояние Хэмминга с базой данных), но это невозможно сделать. OpenCV/SURF Как создать хэш/отпечаток/подпись изображения из дескрипторов?

Итак, с 3 дней, я заблокирован по этой задаче. Я не знаю, ошибаюсь ли я или нет. Возможно, я что-то пропустил.

Надеюсь, вам будет достаточно ясно. Спасибо за чтение

+7
источник поделиться
1 ответ

Ваш вопрос довольно большой. Однако я дам вам несколько советов.

  • Сумка слов может работать, но классификация не нужна. Протокол BoW обычно состоит из:

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

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

  • Я не понял вашу точку зрения.

  • Я бы предложил прочитать статьи Г. Хинтона (например, этот) по уменьшению размерности с помощью глубоких автокодеров и сверточных нейронных сетей. Он может похвастаться избиением LSH. Что касается инструментов, я бы рекомендовал взглянуть на BVLC Caffe, большую библиотеку нейронной сети.

0
источник

Связанные вопросы


Похожие вопросы

Посмотрите другие вопросы по меткам или Задайте вопрос