2017-07-05 2 views
0

MATLABにビジュアルワードのバッグを実装したいと思います。私は画像から特徴を抽出するためにSURF特徴を使用し、kクラスタにこれらの特徴をクラスタ化するk-手段を使用した。私は今kセントロイドを持っていて、各画像の特徴をそのクローゼットの隣人に割り当てることによって、各クラスタが何回使用されているか知りたい。最後に、各画像のヒストグラムを作成したいと思います。各トレーニングイメージを、各語彙要素がBag of Visual Wordsのために表示される回数のヒストグラムとして符号化します。

knnsearch機能を使用しようとしましたが、この場合は機能しません。私はすべての画像が

答えて

1

あなたはほとんどそこにいる重心配列に機能アレイとクラスタ中心に備わってい

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

は、ここに私のMATLABコードです。 knnsearchをまったく使用する必要はありません。 assignments変数は、どの入力フィーチャがどのクラスタにマップされているかを示します。 assignmentsN x 1ベクトルを返します。Nはサンプルの総数、または入力マトリックスfeaturesのフィーチャーの総数です。各値assignments(i)は、どのクラスタにi(または行i)のマップがマップされているかを示します。 assignments(i)によって指示されるクラスタ重心は、centers(i, :)として与えられる。 したがって、kmeansをどのように呼び出すと、それはN x 1ベクトルになります。各要素は1〜500で、500は必要なクラスタの総数です。

コードブックに画像が1つしかないという単純なケースを考えてみましょう。この場合、assignments変数のヒストグラムを作成するだけです。出力ヒストグラムh500 x 1ベクトルになり、各要素のh(i)は、コードブックで重心iがその例として使用された例の回数です。

histcounts関数を使用して、各クラスタIDと一致するようにビン範囲を指定するようにしてください。ビンの範囲は右端で排他的なので、最後のビンを追加するだけで、終了ビンを考慮する必要があります。

これがうまくいくような何か:

h = histcounts(assignments, 1 : 501); 

あなたはシンプルな何かをしたいとあなたが最後ビンの指定を心配したくない場合は、同じ結果を達成するためにaccumarrayを使用することができます。

h = accumarray(assignments, 1); 

accumarrayの効果は、キーが例にマップされた重心であり、値がすべてのキーに対して単純に1であるキーと値のペアを割り当てます。 accumarrayは、同じキーを共有するassignmentsのすべての値をビンし、それらの値で何かを行います。 accumarrayのデフォルトの動作は、ヒストグラムを効果的に計算しているすべての値を合計することです。


ただし、1つの画像だけでなく、複数の画像に対してこの処理を行いたいとします。 Bag of Visual Wordsに問題がある場合は、データベースに複数のトレーニング画像が含まれています。したがって、の各画像のヒストグラムは、です。上記の考え方は引き続き使用できますが、イメージごとに検出されたフィーチャーの数を示す別の変数を維持することをお勧めします。assignments変数にインデックスを付けて、割り当てられた重心IDを抽出し、それらのヒストグラムを個別に構築する。各行が各画像のヒストグラムを描写する2Dマトリクスを構築することができる。 kmeansには、各行が各サンプルがどのクラスターに割り当てられているかを、データ内の他の例とは独立して示しています。これを使用すると、トレーニングデータセット全体でkmeansを使用し、assignments変数にどのようにアクセスして、各入力画像に割り当てられたクラスタを抽出するかを知ることができます。

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は今、それぞれの行は、あなたが求めている各画像のヒストグラムであるN x 500行列になります。それはこのようなものを見えるように

したがって、あなたのコードを変更します。最後の仕事は、教師付き機械学習アルゴリズム(SVM、ニューラルネットワークなど)を使用することです。ここで、期待されるラベルは、各画像のヒストグラムを入力フィーチャとして添付した画像に割り当てられた各画像の説明です。最終的な結果は、学習したモデルです。新しい画像を作成したときに、SURFの機能を計算し、上で行ったような機能のヒストグラムでそれらを表現し、それを分類モデルに入力して、イメージは表す。

P.S.ディープラーニング/ CNNはこれではるかに優れた仕事をしますが、訓練にはもっと時間が必要です。あなたがパフォーマンスを賢明に見ているならば、Bag of Visual Wordsを使わないでください。これは実装が非常に速いものであり、中程度のパフォーマンスを発揮することは知られていますが、もちろん分類したい画像の種類によって異なります。

関連する問題