2017-07-05 4 views
0

Je veux mettre en place un sac de mots visuels dans MATLAB. J'ai utilisé les fonctions SURF pour extraire des entités à partir des images et k-means pour regrouper ces entités en k clusters. J'ai maintenant k centroids et je veux savoir combien de fois chaque grappe est utilisée en assignant chaque caractéristique d'image à son voisin placard. Enfin, j'aimerais créer un histogramme de ceci pour chaque image.Encodez chaque image d'entraînement sous la forme d'un histogramme du nombre de fois où chaque élément de vocabulaire apparaît pour Bag of Visual Words

J'ai essayé d'utiliser la fonction knnsearch mais cela ne fonctionne pas dans ce cas.

Voici mon code Matlab:

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'; 

J'ai toutes les images disposent de fonctionnalités tableau et centre de cluster dans le tableau barycentre

Répondre

1

Vous y êtes presque. Vous n'avez même pas besoin d'utiliser knnsearch du tout. La variable assignments vous indique la fonction d'entrée mappée sur le cluster. assignments vous donnera un vecteur N x 1N est le nombre total d'exemples que vous avez, ou le nombre total de fonctionnalités dans la matrice d'entrée features. Chaque valeur assignments(i) vous indique quel est le cluster de l'exemple i (ou la ligne i) de features qu'il mappe. Le centroïde de cluster dicté par assignments(i) sera donné comme centers(i, :). Donc, étant donné que vous avez appelé kmeans, ce sera un vecteur N x 1 où chaque élément est de 1 à 500 avec 500 étant le nombre total de clusters désirés.

Faisons le cas simple où nous avons seulement une image dans votre livre de codes. Si c'est le cas, tout ce que vous avez à faire est de créer un histogramme de la variable assignments. L'histogramme de sortie h sera un vecteur 500 x 1 avec chaque élément h(i) étant le nombre de fois qu'un exemple utilisé centroid i comme sa représentation dans votre livre de codes. Utilisez simplement la fonction histcounts et assurez-vous que vous spécifiez les plages de corbeilles afin qu'elles coïncident avec chaque ID de grappe. Vous devez vous assurer que vous tenez compte du bin de fin, car les intervalles de bin sont exclusifs sur le bord droit, il suffit donc d'ajouter un nouveau bin à la fin.

Quelque chose comme cela fonctionnera:

h = histcounts(assignments, 1 : 501); 

Si vous voulez quelque chose de plus simple et vous ne voulez pas vous occuper de spécifier le bac final, vous pouvez utiliser accumarray pour obtenir le même résultat:

h = accumarray(assignments, 1); 

L'effet de accumarray nous assignons des paires clé-valeur où la clé est le centroïde que l'exemple mappé à et la valeur est simplement 1 pour toutes les clés. accumarray va bin toutes les valeurs dans assignments qui partagent la même clé et vous faites quelque chose avec ces valeurs. Le comportement par défaut de accumarray consiste à additionner toutes les valeurs, ce qui permet de calculer efficacement l'histogramme. Cependant, vous souhaitez effectuer cette opération pour plusieurs images, et non pour une seule image. Pour les problèmes de sac de mots visuels, nous aurons certainement plus d'une image de formation dans notre base de données.Par conséquent, vous voulez trouver l'histogramme des caractéristiques pour chaque image. Nous pouvons toujours utiliser le concept ci-dessus, mais une chose que je peux suggérer est que vous maintenez une variable séparée qui vous indique combien de fonctionnalités ont été détectées par image, alors vous pouvez indexer dans la variable assignments pour extraire les identifiants de centroïdes assignés, puis construire un histogramme de ceux-ci individuellement. Nous pouvons construire une matrice 2D où chaque ligne délimite l'histogramme de chaque image. Rappelez-vous que dans kmeans, chaque ligne vous indique à quel cluster chaque exemple a été affecté indépendamment des autres exemples dans vos données. En utilisant cela, vous utiliserez kmeans sur l'ensemble du jeu de données d'entraînement, puis soyez intelligent sur la façon dont vous accédez à la variable assignments pour extraire les clusters attribués pour chaque image d'entrée.

Par conséquent, modifier votre code afin qu'il ressemble à ceci:

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 va maintenant être une matrice N x 500 où chaque ligne est l'histogramme de chaque image que vous recherchez. Le dernier travail consistera à utiliser un algorithme d'apprentissage automatique supervisé (SVM, réseaux neuronaux, etc.) où les étiquettes attendues sont la description de chaque image que vous avez assignée à l'image accompagnée de l'histogramme de chaque image comme caractéristiques d'entrée. Le résultat final serait un modèle appris de sorte que lorsque vous avez une nouvelle image, calculez les fonctions SURF, les représenter dans un histogramme de fonctionnalités comme nous l'avons fait ci-dessus, puis alimentez-le dans le modèle de classification l'image représente.

P.S. Deep Learning/CNN font un bien meilleur travail, mais nécessitent beaucoup plus de temps pour s'entraîner. Si vous regardez les performances, n'utilisez pas Bag of Visual Words, mais c'est quelque chose de très rapide à mettre en œuvre et il est connu pour performer modérément bien, mais cela dépend bien sûr du type d'images que vous voulez classer.