2017-07-05 23 views
0

Ich möchte einen Beutel mit visuellen Wörtern in MATLAB implementieren. Ich benutzte SURF-Features, um Features aus den Bildern zu extrahieren, und k-means, um diese Features in k Cluster zu clustern. Ich habe jetzt k Zentroide und ich möchte wissen, wie oft jeder Cluster verwendet wird, indem ich jedes Bildmerkmal seinem benachbarten Nachbarn zuweise. Schließlich möchte ich für jedes Bild ein Histogramm erstellen.Kodieren Sie jedes Trainingsbild als ein Histogramm der Anzahl der Male, die jedes Vokabularelement für Beutel mit visuellen Wörtern angezeigt wird

Ich habe versucht, knnsearch Funktion zu verwenden, aber es funktioniert in diesem Fall nicht.

Hier ist meine MATLAB-Code:

clc; 
clear; 
close all; 
folder = 'CarData/TrainImages/cars'; 
filePattern = fullfile(folder, '*.pgm'); 
f=dir(filePattern); 
files={f.name}; 
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); 
    features{k}= im_features; 

end 

features = vertcat(features{:}); 
image_feats = []; 
[assignments,centers] = kmeans(double(features),500); 
vocab = centers'; 

Ich habe alle Bilder verfügen über Features Array- und Cluster-Zentrum in Schwerpunkt Array

Antwort

1

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.

Verwandte Themen