Как использовать функцию сопоставления vlfeat sift в коде C?

Я только что нашел один похожий вопрос здесь. Но я просто хочу сделать сопоставление на основе результата описания из vlfeat. Цель состоит в том, чтобы определить, содержит ли изображение объект на другом изображении, на основе извлечения и сопоставления описаний функций просеивания. И мне нужно сделать это на C, а не на Matlab.

Итак, как я могу вызвать функцию vl_ubcmatch в коде C?


person mrmoment    schedule 14.11.2014    source источник


Ответы (2)


Итак, как я могу вызвать функцию vl_ubcmatch в коде C?

Это функция MEX, которая только предназначен для вызова из MATLAB. Вы не можете повторно использовать его как есть из программы C общего назначения.

Цель определить, содержит ли изображение объект на другом изображении [...] Как выполнить алгоритм сопоставления SIFT, если я использую vlfeat?

VLFeat C API не предоставляет встроенных функций сопоставления SIFT. Таким образом, в основном вам нужно адаптировать так называемый раздел кода ratio test [1] из этого раздел кода MATLAB C, что довольно просто (см. ниже).

Основным недостатком, если вы хотите выполнить надежное сопоставление, является то, что эта функция не учитывает геометрию, то есть координаты ключевых точек.

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

Но также вы можете ускорить вычисление соответствий с помощью kd-tree.

Таким образом, альтернативой, если вам нужна простая реализация C, является использование Open SIFT Роба Хесса, который включает в себя все, что вам нужно. , а также готовый к использованию инструмент командной строки (и, следовательно, пример) сопоставления:

См. match.c.


typedef struct {
    int k1;
    int k2;
    double score;
} Pair;

Pair *
compare(
    Pair *pairs,
    const float *descr1,
    const float *descr2,
    int K1,
    int K2,
    int ND,
    float thresh
)
{
    int k1, k2;

    /* Loop over 1st image descr. */
    for (k1 = 0; k1 < K1; ++k1, descr1 += ND ) {
        float best = FLT_MAX;
        float second_best = FLT_MAX;
        int bestk = -1;

        /* Loop over 2nd image descr. and find the 1st and 2nd closest descr. */
        for (k2 = 0; k2 < K2; ++k2, descr2 += ND ) {
            int bin;
            float acc = 0;

            /* Compute the square L2 distance between descriptors */
            for (bin = 0 ; bin < ND ; ++bin) {
                float delta = descr1[bin] - descr2[bin];
                acc += delta*delta;
                if (acc >= second_best)
                    break;
            }

            if (acc < best) {
                second_best = best;
                best = acc;
                bestk = k2;
            }
            else if (acc < second_best) {
                second_best = acc;
            }
        }

        /* Rewind */
        descr2 -= ND*K2;

        /* Record the correspondence if the best descr. passes the ratio test */
        if (thresh * best < second_best && bestk != -1) {
            pairs->k1 = k1;
            pairs->k2 = bestk;
            pairs->score = best;
            pairs++;
        }
    }

    return pairs;
}
  • K1: количество дескрипторов в изображении 1,
  • K2: количество дескрипторов на изображении 2,
  • ND: размер дескриптора (= 128 для SIFT),
  • descr1 и descr2: дескрипторы изображения 1 и 2 соответственно. в основном порядке строк, например, K1 строк x ND столбцов),
  • thresh: пороговое значение теста отношения, например, 1.5 в коде MATLAB.

[1] см. 7.1 Сопоставление ключевых точек из статьи Д. Лоу.

person deltheil    schedule 15.11.2014

Вы будете использовать библиотеку vlfeat так же, как и любую другую библиотеку на C. Сначала убедитесь, что эта библиотека установлена ​​на вашем компьютере и вы знаете, где она установлена. Вам нужно будет включить требуемый заголовок для каждой части vlfeat, которую вы используете. Обычно общий заголовок библиотеки для vlfeat, а затем специальный заголовок для sift (например, #include "sift.h") (иногда общий заголовок отсутствует). Вам нужно будет убедиться, что команда gcc или g++ включает правильные INCLUDE_PATH и LIBRARY_PATH для вашей среды, что позволит gcc найти ваши vlfeat файлы. (например, -I/path/to/dir/holding_sift.h и -L/path/to/vlfeatlib) Таким образом, вы получите что-то вроде этого для C:

gcc -o exename exename.c -I/path/to/dir/holding_sift.h -L/path/to/vlfeatlib -lvl

В сети есть документация, которая поможет. См.: как настроить базовый проект C++, использующий библиотеку VLFeat. Если у вас есть дополнительные вопросы, просто напишите в комментариях.

person David C. Rankin    schedule 14.11.2014
comment
API C описаны на странице vlfeat.org/api/sift.html. Там есть только просеивающий дескриптор, генерирующий (извлекающий) API. Я не могу найти соответствующий связанный API. И в исходнике я нахожу vl_ubcmatch.c, который выполняет базовый алгоритм сопоставления. Но я не знаю, как вызвать эту функцию алгоритма в этом файле .c (где есть много определений макросов, которые кажутся связанными с Matlab). Мой главный вопрос: как выполнить алгоритм сопоставления SIFT, если я использую vlfeat? - person mrmoment; 14.11.2014
comment
Это была основная часть ответа. Вы будете включать sift.h в свой код вместе с другими включениями (stdio.h и т.д..). Затем вы будете использовать функцию с правильными аргументами, как указано в sift.h вашего кода. Затем вы скомпилируете код (либо gcc, либо g++), указав библиотеку -lvl, чтобы компоновщик знал, что нужно включить этот код, и вам может понадобиться/не нужно указывать -I/path и/или -L/path, чтобы gcc и ld нашли библиотеку и sift.h заголовок в зависимости от вашей среды. Никаких трюков. - person David C. Rankin; 14.11.2014
comment
Вам также необходимо убедиться, что у вас установлена ​​binary для библиотеки, а не только исходный код. (вы можете собрать бинарную библиотеку vlfeat из исходников, но она также предоставляется в бинарной форме) - person David C. Rankin; 14.11.2014
comment
У меня есть два просеянных файла, извлеченных из двух файлов изображений, 1.sift и 2.sift (или соответствующих структур данных в памяти). Как узнать, соответствует ли 2.sift 1.sift? Оцените, если проиллюстрирован какой-либо фрагмент кода. - person mrmoment; 14.11.2014
comment
Хорошо, теперь мы знаем, где вы застряли. Раньше я не использовал просеивание, но файлы просеивания должны содержать некоторый тип структуры данных, которая содержит общие черты между image_1 и image_2, что позволит сшить два изображения вместе. Какую форму это принимает, я не знаю. Я просматривал данные в файлах и искал координаты/значения цвета/и т. д., которые просеивались как эквивалентные между изображениями. Чтобы vlfeat/sift объединил изображения, эти общие черты должны присутствовать. Он может даже содержать карту изображений имен файлов, содержащих эквивалентные данные. Если завтра будет возможность, то установлю - person David C. Rankin; 14.11.2014