Sie sind fast da. Sie müssen überhaupt nicht knnsearch
verwenden. Die Variable assignments
teilt Ihnen mit, welches Eingabemerkmal zu welchem Cluster gehört. assignments
gibt Ihnen einen N x 1
Vektor, wobei N
die Gesamtzahl der Beispiele ist, die Sie haben, oder die Gesamtzahl der Features in der Eingabematrix features
. Jeder Wert assignments(i)
sagt Ihnen, welcher Cluster das Beispiel i
(oder Zeile i
) von features
es zuordnet. Der Clusterschwerpunkt, der durch assignments(i)
diktiert wird, würde als centers(i, :)
angegeben werden. Daher gegeben, wie Sie kmeans
aufgerufen haben, wird es ein N x 1
Vektor sein, wobei jedes Element von 1 bis 500 ist, wobei 500 die Gesamtzahl der gewünschten Cluster ist.
Machen wir den einfachen Fall, in dem wir nur ein Bild in Ihrem Codebuch haben. Wenn dies der Fall ist, müssen Sie nur ein Histogramm der Variablen assignments
erstellen. Das Ausgabehistogramm h
ist ein 500 x 1
Vektor mit jedem Element h(i)
, das die Anzahl von Beispielen ist, die ein Schwerpunkt i
als seine Darstellung in Ihrem Codebuch verwendet.
Verwenden Sie einfach die histcounts
-Funktion und stellen Sie sicher, dass Sie die Bin-Bereiche angeben, so dass sie mit jeder Cluster-ID übereinstimmen. Sie müssen sicherstellen, dass Sie das End-Bin berücksichtigen, da die Bin-Bereiche an der rechten Kante exklusiv sind. Fügen Sie einfach ein zusätzliches Bin am Ende hinzu.
So etwas wie dies funktioniert:
h = histcounts(assignments, 1 : 501);
Wenn Sie etwas einfacher, und Sie wollen nicht über die Angabe des Endes bin kümmern, können Sie accumarray
verwenden das gleiche Ergebnis zu erzielen:
h = accumarray(assignments, 1);
Der Effekt von accumarray
Wir weisen Schlüssel-Wert-Paare zu, wobei der Schlüssel der Schwerpunkt ist, dem das Beispiel zugeordnet wurde, und der Wert ist einfach 1 für alle Schlüssel. accumarray
werden bin alle Werte in assignments
, die den gleichen Schlüssel teilen, und Sie tun etwas mit diesen Werten. Das Standardverhalten von accumarray
besteht darin, alle Werte zu summieren, wodurch das Histogramm effektiv berechnet wird.
Sie möchten dies jedoch für mehrere Bilder, nicht nur ein einzelnes Bild. Für Bag of Visual Words Probleme werden wir sicherlich mehr als ein Trainingsbild in unserer Datenbank haben.Daher möchten Sie das Histogramm der Features für jedes Bild finden. Wir können das obige Konzept weiterhin verwenden, aber eine Sache, die ich vorschlagen kann, ist die Pflege einer separaten Variablen, die Ihnen sagt, wie viele Merkmale pro Bild erkannt wurden. Dann können Sie in die Variable assignments
indizieren, um die korrekten zugewiesenen Zentroid-IDs zu extrahieren Erstellen Sie ein Histogramm dieser einzeln. Wir können eine 2D-Matrix erstellen, in der jede Zeile das Histogramm jedes Bildes abgrenzt. Denken Sie daran, dass Sie in kmeans
in jeder Zeile angeben, welchem Cluster jedes Beispiel unabhängig von den anderen Beispielen in Ihren Daten zugewiesen wurde. Wenn Sie dies verwenden, verwenden Sie kmeans
für das gesamte Trainings-Dataset. Machen Sie sich dann Gedanken darüber, wie Sie auf die Variable assignments
zugreifen, um die zugewiesenen Cluster für jedes Eingabebild zu extrahieren.
Deshalb ändern Sie den Code so, dass es so etwas wie folgt aussieht:
clc;
clear;
close all;
folder = 'CarData/TrainImages/cars';
filePattern = fullfile(folder, '*.pgm');
f=dir(filePattern);
files={f.name};
num_features = zeros(numel(files), 1); % New - for keeping track of # of features per image
for k=1:numel(files)
fullFileName = fullfile(folder, files{k});
H = fspecial('log');
image=imfilter(imread(fullFileName),H);
temp = detectSURFFeatures(image);
[im_features, temp] = extractFeatures(image, temp);
num_features(k) = size(im_features, 1); % New - # of features per image
features{k}= im_features;
end
features = vertcat(features{:});
num_clusters = 500; % Added to make the code adaptive
[assignments,centers] = kmeans(double(features), num_clusters);
counter = 1; % Keeps track of where we need to slice in assignments
% Go through each image and find their histograms
features_hist = zeros(numel(files), num_clusters); % Records the per image histograms
for k = 1 : numel(files)
a = assignments(counter : counter + num_features(k) - 1); % Get the assignments
h = histcounts(a, 1 : num_clusters + 1);
% Or:
% h = accumarray(a, 1).'; % Transpose to make it a row
% Place in final output
features_hist(k, :) = h;
% Increment counter
counter = counter + num_features(k);
end
features_hist
wird nun eine N x 500
Matrix sein, wobei jede Zeile ist das Histogramm jedes Bild, das Sie suchen. Die letzte Aufgabe wäre die Verwendung eines überwachten maschinellen Lernalgorithmus (SVM, neuronale Netze usw.), wobei die erwarteten Bezeichnungen die Beschreibung jedes Bilds sind, das Sie dem Bild zugeordnet haben, begleitet vom Histogramm jedes Bildes als Eingabemerkmale. Das Endergebnis wäre ein erlerntes Modell. Wenn Sie ein neues Bild haben, berechnen Sie die SURF-Features, stellen Sie sie in einem Histogramm von Features wie oben dar und füttern Sie es in das Klassifikationsmodell, um Ihnen die erwartete Klasse oder Bezeichnung zu geben das Bild repräsentiert.
P.S. Deep Learning/CNNs leisten hier einen viel besseren Job, benötigen aber viel mehr Zeit zum Trainieren. Wenn Sie auf die Leistung achten, verwenden Sie nicht den Beutel mit visuellen Wörtern, aber das ist etwas sehr schnell zu implementieren und es ist bekannt, mäßig gut zu funktionieren, aber das hängt natürlich von den Arten von Bildern ab, die Sie klassifizieren möchten.