Извлечение VLAD из дескрипторов SIFT в VLFeat с помощью Matlab

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

Я зацикливаюсь на каждом изображении, загружаю его и получаю дескрипторы SIFT следующим образом:

repo = '/media/data/images/';
filelist = dir([repo '*.jpg']);
sift_descr = {}

for i = 1:size(filelist, 1)
    I = imread([repo filelist(i).name]) ;
    I = single(rgb2gray(I)) ;
    [f,d] = vl_sift(I) ;
    sift_descr{i} = d
end

Однако VLAD требует, чтобы матрица дескрипторов была 2D. Смотрите здесь. Как правильно обрабатывать дескрипторы SIFT до кодирования VLAD? Спасибо.

1 ответ

Решение

Во-первых, вам нужно получить словарь визуальных слов или, если быть более точным, кластеризовать функции SIFT для всех изображений, используя кластеризацию k- средних. В [1] рекомендуется грубая кластеризация с использованием, например, 64 или 256 кластеров.

Для этого нам нужно объединить все дескрипторы в одну матрицу, которую мы затем можем передать vl_kmeans функция. Далее мы конвертируем дескрипторы из uint8 в single как vl_kmeans Функция требует, чтобы вход был либо single или же double,

all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);

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

В этом уроке они используют kd-деревья, поэтому давайте придерживаться этого: во-первых, необходимо построить kd-дерево. Эта операция принадлежит сразу после нахождения centroids:

kdtree = vl_kdtreebuild(centroids);

Затем мы готовы построить вектор VLAD для каждого изображения. Таким образом, мы должны снова просмотреть все изображения и независимо рассчитать их вектор VLAD. Сначала мы создаем матрицу назначений в точности так, как описано в руководстве. Затем мы можем кодировать дескрипторы SIFT, используя vl_vlad функция. Результирующий вектор VLAD будет иметь размер NumberOfClusters * SiftDescriptorSize, то есть 64*128 в нашем примере.

enc = zeros(64*128, numel(sift_descr));

for k=1:numel(sift_descr)

    % Create assignment matrix
    nn = vl_kdtreequery(kdtree, centroids, single(sift_descr{k}));
    assignments = zeros(64, numel(nn), 'single');
    assignments(sub2ind(size(assignments)), nn, 1:numel(nn))) = 1;

    % Encode using VLAD
    enc(:, k) = vl_vlad(single(sift_descr{k}), centroids, assignments);
end

Наконец, у нас есть высокоразмерные векторы VLAD для всех изображений в базе данных. Обычно вы хотите уменьшить размерность дескрипторов VLAD, например, используя PCA.

Теперь, учитывая новое изображение, которого нет в базе данных, вы можете извлечь функции SIFT, используя vl_sift создать матрицу назначения с vl_kdtreequery и создайте вектор VLAD для этого изображения, используя vl_vlad, Таким образом, вам не нужно находить новые центроиды или создавать новое дерево kd:

% Load image and extract SIFT features
new_image = imread('filename.jpg');
new_image = single(rgb2gray(new_image));
[~, new_sift] = vl_sift(new_image);

% Create assignment matrix
nn = vl_kdtreequery(kdtree, centroids, single(new_sift));
assignments = zeros(64, numel(nn), 'single');
assignments(sub2ind(size(assignments)), nn, 1:numel(nn))) = 1;

% Encode using VLAD
new_vlad = vl_vlad(single(new_sift), centroids, assignments);

[1] Аранджелович Р. и Циссерман А. (2013). Все о ВЛАДЕ. Конференция IEEE по компьютерному зрению и распознаванию образов (CVPR), 1578–1585. https://doi.org/10.1109/CVPR.2013.207

Другие вопросы по тегам