Zuerst müssen Sie ein Wörterbuch von visuellen Worten zu erhalten, oder um genauer zu sein: Cluster die SIFT Merkmale aller Bilder k -Mittel Clustering. In [1] wird eine grobe Häufung unter Verwendung von z.B. 64 oder 256 Cluster wird empfohlen.
Dazu müssen wir alle Deskriptoren in einer Matrix verketten, die wir dann an die vl_kmeans
Funktion übergeben können. Ferner konvertieren wir die Deskriptoren von uint8
in single
, da die vl_kmeans
-Funktion erfordert, dass der Eingang entweder single
oder double
ist.
all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);
Zweitens müssen Sie eine Zuordnungsmatrix erstellen, welche die Abmessungen NumberOfClusters-by-NumberOfDescriptors hat, die jeder Deskriptor zu einem Cluster zuordnet. Sie haben eine große Flexibilität bei der Erstellung dieser Zuweisungsmatrix: Sie können weiche oder harte Zuweisungen vornehmen, Sie können nach Ihrem Ermessen einfache Nächste-Nachbarn-Suche oder kd-Bäume oder andere ungefähre oder hierarchische Nächste-Nachbarn-Schemata verwenden.
Im Tutorial verwenden sie kd-Bäume, bleiben wir also dabei: Zunächst muss ein kd-Baum erstellt werden. Dieser Vorgang gehört direkt nach den centroids
finden:
kdtree = vl_kdtreebuild(centroids);
Dann sind wir bereit, das VLAD Vektor für jedes Bild zu konstruieren. Daher müssen wir alle Bilder erneut durchlaufen und ihren VLAD-Vektor unabhängig berechnen. Zuerst erstellen wir die Zuweisungsmatrix genau wie im Tutorial beschrieben. Dann können wir die SIFT-Deskriptoren unter Verwendung der vl_vlad
-Funktion codieren. Der resultierende VLAD Vektor wird die Größe NumberOfClusters haben * SiftDescriptorSize, das heißt 64 * 128 in unserem Beispiel ..
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
Schließlich haben wir die hochdimensionalen VLAD Vektoren für alle Bilder in der Datenbank. Normalerweise möchten Sie die Dimensionalität der VLAD-Deskriptoren z. Verwenden von PCA.
Jetzt, da neues Bild, das nicht in der Datenbank ist, können Sie extrahieren die SIFT vl_sift
Funktionen verwenden, erstellen Sie die Zuordnungsmatrix mit vl_kdtreequery
, und erstellen Sie den VLAD Vektor für das Bild mit vl_vlad
. Also, Sie müssen nicht neu Centroide finden oder einen neuen kd-Baum erstellen:
% 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] Arandjelovic, R., & Zisserman, A. (2013). Alles über VLAD. IEEE Konferenz über Computer Vision und Mustererkennung (CVPR), 1578-1585. https://doi.org/10.1109/CVPR.2013.207
Große Antwort, vielen Dank. –