最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

bag of features を使用したイメージ カテゴリの分類

この例では、bag of features の手法を使用してイメージ カテゴリの分類を行う方法を説明します。この手法は、多くの場合 bag of words とも呼ばれます。視覚的イメージの分類は、テスト対象のイメージにカテゴリ ラベルを割り当てる処理です。カテゴリには犬、猫、列車、船舶など、あらゆるものを表すイメージが含まれます。

Caltech101 イメージ セットのダウンロード

bag of features によるイメージ カテゴリの分類について学ぶため、まず適切なイメージのデータセットをダウンロードします。最も広く引用され使用されるデータセットの 1 つに、Fei-Fei Li、Marco Andreetto および Marc 'Aurelio Ranzato によって収集された Caltech 101 があります。

% Location of the compressed data set
url = 'http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz';
% Store the output in a temporary folder
outputFolder = fullfile(tempdir, 'caltech101'); % define output folder

Web サイトからこのセットをダウンロードする際、インターネット接続の速度によってはかなり長時間を要する場合があるので注意してください。セットには 126 MB のデータが含まれているため、30 分以上かかる場合があります。下記のコマンドはその間 MATLAB をブロックします。別の方法として、Web ブラウザーを使用して、このセットをローカル ディスクにまずダウンロードしておくことができます。このやり方を選ぶ場合、上記の変数 'url' を、ダウンロードしたファイルを指すように再設定してください。

if ~exist(outputFolder, 'dir') % download only once
    disp('Downloading 126MB Caltech101 data set...');
    untar(url, outputFolder);
end

イメージ セットの読み込み

Caltech 101 セット全体について操作を行うと時間がかかるため、代わりに飛行機、フェリー、ラップトップの 3 つのカテゴリを使用します。bag of features の手法が効果を発揮するには、各イメージの領域の大部分がカテゴリの対象 (たとえば、オブジェクトや何らかのシーンなど) によって占められていなければなりません。

rootFolder = fullfile(outputFolder, '101_ObjectCategories');

Caltech 101 からの「飛行機」、「フェリー」、「ラップトップ」の各カテゴリに基づく ImageDatastore を作成します。データを管理しやすいよう imageDatastore を使用します。imageDatastore はイメージ ファイルの場所で操作を行うため、すべてのイメージをメモリに読み込むことはしません。したがって、大規模なイメージの集合で使用しても安全です。

categories = {'airplanes', 'ferry', 'laptop'};
imds = imageDatastore(fullfile(rootFolder, categories), 'LabelSource', 'foldernames');

次に示すように、カテゴリごとのイメージ数やカテゴリ ラベルを簡単に検査できます。

tbl = countEachLabel(imds)
tbl=3×2 table
      Label      Count
    _________    _____

    airplanes     800 
    ferry          67 
    laptop         81 

ラベルは ImageDatastore の作成に使用されたディレクトリ名を基に生成されますが、ImageDatastore オブジェクトの Labels プロパティを手動で設定することによりカスタマイズできることに注意してください。

学習用と検証用イメージ セットの準備

上記の imds ではカテゴリごとに含まれるイメージの数が等しくないため、最初に調整することで、学習セット内のイメージ数のバランスを取ります。

minSetCount = min(tbl{:,2}); % determine the smallest amount of images in a category

% Use splitEachLabel method to trim the set.
imds = splitEachLabel(imds, minSetCount, 'randomize');

% Notice that each set now has exactly the same number of images.
countEachLabel(imds)
ans=3×2 table
      Label      Count
    _________    _____

    airplanes     67  
    ferry         67  
    laptop        67  

セットを学習データと検証データに分けます。各セットからイメージの 30% を学習データに選択し、残る 70% を検証データとします。結果が偏らないようにランダムな方法で分割します。

[trainingSet, validationSet] = splitEachLabel(imds, 0.3, 'randomize');

上記の呼び出しは、学習タスク用と検証タスク用に準備される 2 つの imageDatastore オブジェクトを返します。下に示すのは、学習データに含まれる 3 つのカテゴリからのイメージの例です。

% Find the first instance of an image for each category
airplanes = find(trainingSet.Labels == 'airplanes', 1);
ferry = find(trainingSet.Labels == 'ferry', 1);
laptop = find(trainingSet.Labels == 'laptop', 1);

% figure

subplot(1,3,1);
imshow(readimage(trainingSet,airplanes))
subplot(1,3,2);
imshow(readimage(trainingSet,ferry))
subplot(1,3,3);
imshow(readimage(trainingSet,laptop))

ビジュアル ボキャブラリの作成とイメージ カテゴリ分類器の学習

bag of words は、自然言語処理分野の手法をコンピューター ビジョンに応用したものです。実際にはイメージに個々の単語が含まれるわけではないので、まず各イメージ カテゴリを表す SURF 特徴量の「ボキャブラリ」を作成します。

これは関数 bagOfFeatures の一度の呼び出しで、以下を実行することができます。

  1. すべてのイメージ カテゴリにある全イメージから SURF 特徴量を抽出する

  2. k-means クラスタリングを使用した特徴空間の量子化により、特徴の数を減らしてビジュアル ボキャブラリを作成する

bag = bagOfFeatures(trainingSet);
Creating Bag-Of-Features.
-------------------------
* Image category 1: airplanes
* Image category 2: ferry
* Image category 3: laptop
* Selecting feature point locations using the Grid method.
* Extracting SURF features from the selected feature point locations.
** The GridStep is [8 8] and the BlockWidth is [32 64 96 128].

* Extracting features from 60 images...done. Extracted 247480 features.

* Keeping 80 percent of the strongest features from each category.

* Balancing the number of features across all image categories to improve clustering.
** Image category 2 has the least number of strongest features: 58003.
** Using the strongest 58003 features from each of the other image categories.

* Using K-Means clustering to create a 500 word visual vocabulary.
* Number of features          : 174009
* Number of clusters (K)      : 500

* Initializing cluster centers...100.00%.
* Clustering...completed 31/100 iterations (~3.14 seconds/iteration)...converged in 31 iterations.

* Finished creating Bag-Of-Features

また、bagOfFeatures オブジェクトは、あるイメージ内でのビジュアル ワードの出現回数を数える encode メソッドを提供します。これによってヒストグラムが作成され、イメージの新しい簡易な表現となります。

img = readimage(imds, 1);
featureVector = encode(bag, img);

% Plot the histogram of visual word occurrences
figure
bar(featureVector)
title('Visual word occurrences')
xlabel('Visual word index')
ylabel('Frequency of occurrence')

このヒストグラムは、分類器の学習と実際のイメージ分類のための基礎となります。基本的に、これはイメージを特徴ベクトルにエンコードしたものです。

各カテゴリからのエンコードされた学習イメージは、関数 trainImageCategoryClassifier で呼び出された分類器学習プロセスに渡されます。この関数は Statistics and Machine Learning Toolbox™ のマルチクラス線形 SVM 分類器に依存することに注意してください。

categoryClassifier = trainImageCategoryClassifier(trainingSet, bag);
Training an image category classifier for 3 categories.
--------------------------------------------------------
* Category 1: airplanes
* Category 2: ferry
* Category 3: laptop

* Encoding features for 60 images...done.

* Finished training the category classifier. Use evaluate to test the classifier on a test set.

上記の関数は入力の bag オブジェクトの encode メソッドを使用して、trainingSet からの各イメージ カテゴリを表す特徴ベクトルを生成します。

分類器のパフォーマンスの評価

学習済みの分類器 categoryClassifier が得られたので、次にその評価を行います。正常性チェックとして、学習セットを使ったテストを行います。ほぼ完璧な、つまり対角要素が 1 の混同行列が得られるはずです。

confMatrix = evaluate(categoryClassifier, trainingSet);
Evaluating image category classifier for 3 categories.
-------------------------------------------------------

* Category 1: airplanes
* Category 2: ferry
* Category 3: laptop

* Evaluating 60 images...done.

* Finished evaluating all the test sets.

* The confusion matrix for this test set is:


                        PREDICTED
KNOWN        | airplanes   ferry   laptop   
--------------------------------------------
airplanes    | 0.95        0.05    0.00     
ferry        | 0.00        1.00    0.00     
laptop       | 0.05        0.00    0.95     

* Average Accuracy is 0.97.

次に、学習に使用されなかった validationSet で分類器を評価します。既定では、関数 evaluate は混同行列を返します。これは、分類器の性能の優れた初期指標となります。

confMatrix = evaluate(categoryClassifier, validationSet);
Evaluating image category classifier for 3 categories.
-------------------------------------------------------

* Category 1: airplanes
* Category 2: ferry
* Category 3: laptop

* Evaluating 141 images...done.

* Finished evaluating all the test sets.

* The confusion matrix for this test set is:


                        PREDICTED
KNOWN        | airplanes   ferry   laptop   
--------------------------------------------
airplanes    | 0.81        0.13    0.06     
ferry        | 0.02        0.98    0.00     
laptop       | 0.00        0.00    1.00     

* Average Accuracy is 0.93.
% Compute average accuracy
mean(diag(confMatrix));

関数 evaluate で返される残りの引数を使用して、追加の統計量を導出することもできます。imageCategoryClassifier/evaluate のヘルプを参照してください。満足できる結果が得られるまで、さまざまなパラメーターを調整して学習済みの分類器の評価を続けることができます。

新たに学習した分類器のテスト イメージでの試用

ここで、新たに学習させた分類器を適用して新しいイメージを分類できます。

img = imread(fullfile(rootFolder, 'airplanes', 'image_0690.jpg'));
[labelIdx, scores] = predict(categoryClassifier, img);

% Display the string label
categoryClassifier.Labels(labelIdx)
ans = 1x1 cell array
    {'airplanes'}