2012年6月30日土曜日

Installation of Point Cloud Library to iMac

Introduction


    At the tutorial in SSII2012, a brief introduction to the Point Cloud Library(PCL) was provided. It is the library for processing a point cloud (i.e. 3D point group) generated by a depth sensor. The Kinect and Xtion are familiar devices as the depth sensors. Recently I bought the Xtion Pro Live. So, in this page, I describe the procedures to run a sample program in PCL with the Xtion Pro Live.

My Environment

  1. iMac
  2. Processor:3.06GHz Intel Core 2 Duo
  3. Mac OS X 10.7.4
  4. Xcode 4.3.3

Installation of Prerequisite Libraries


    First, I installed the following packages by using macports.
  1. cmake @2.8.8
  2. boost  @1.49.0
  3. eigen3 @3.0.5
  4. flann @1.7.1
  5. vtk5 @5.8.0
  6. qhull @2012.1
  7. libusb @1.0.9 
The versions of all packages are those which port search displays. Only for libusb, the variant universal is needed. It takes a long time to compile vtk5.
    Next, I downloaded binary packages of the OpenNI and Sensor from this site.
  1. openni-bin-dev-macosx-v1.5.4.0.tar.bz2 
  2. sensor-bin-macosx-v5.1.2.1.tar.bz2
  3. nite-bin-macosx-v1.5.2.21.tar.bz2
Though the NITE is not needed for installing the PCL, I installed it for future reference. Decompressing them, a script file install.sh is found for each directory. All you have to do is just as follows: At this point, preparation for installing the PCL is completed.

Installation of Point Cloud Library (PCL)


    From this site, I could download the binary package of the PCL, and install it easily. However, when compiling a sample program in PCL, the link with the dependent library failed. Probably, it's because the versions of the prerequisite libraries are different from those consistent with the binary package of the PCL. So, I decided to compile the source codes of the PCL. The file PCL-1.5.1-Source.tar.bz2 can be downloaded from this site. The way to make is here. The default place where libraries and headers are installed is /usr/local.

Execution of Sample Program


    The tool cmake is recommended for compiling the program including PCL. In this page, I show how to compile it on the Xcode4.3.3.

creation of new project

I create a new project as Command Line Tool.

adding of a sample program

I added this file to the project.

setting for compilation

Other Linker Flags:
-lpcl_common -lpcl_visualization -lboost_thread-mt -lpcl_io -lpcl_filters 
Header Search Paths:
/usr/local/include/pcl-1.5/ /opt/local/include /opt/local/include/eigen3/ /usr/include/ni/ /opt/local/include/vtk-5.8/
Library Search Paths:
/usr/local/lib /opt/local/lib 

execution

When executing the project after connecting with the Xtion Pro Live, the following error occurred.

Open failed: File not found!
node depth problems
node image problems
node ir problems


This site tells us that
  • create a new directory /etc/primesense
  • copy the following file into the directory
    OpenNI-Bin-Dev-MacOSX-v1.5.4.0/Samples/Config/SamplesConfig.xml
After doing so, I got the same error. I ran grep to the file PCL-1.5.1-Source/io/src/openni_camera/openni_device.cpp, and found two places where SamplesConfig.xml must exist:
  • /etc/openni/SamplesConfig.xml
  • /etc/primesense/SamplesConfig.xml
Therefore, I also copied the SamplesConfig.xml into the directory /etc/openni/. Then, the program works well except for the following warning:
node ir problems

Unsolved Issues


    In the case of Debug mode, the program works well. But, in the case of Release mode, it encounters the segmentation fault.

OpenNIサンプルプログラムの実行

Xcode4.3.3でOpenNIのサンプルプログラムNiSimpleViewer.cppをコンパイルする手順を示す。

新規プロジェクトの作成

Command Line Toolとしてプロジェクトを作成する。

サンプルプログラムの登録

OpenNI-Bin-Dev-MacOSX-v1.5.4.0/Samples/NiSimpleViewerにあるファイルNiSimpleViewer.cppをプロジェクトに登録する。マクロ定義SAMPLE_XML_PATHを、SamplesConfig.xmlを配置した場所に変更する。
#define SAMPLE_XML_PATH "/etc/openni/SamplesConfig.xml"

コンパイルオプションの設定

targets settingを選択し以下を記述する。
Other Linker Flags: /usr/lib/libOpenNI.dylib -framework OpenGL -framework GLUT
Header Search Paths: /usr/include/ni

実行

実行すると、フルスクリーンで起動する。main関数内にある関数glutFullScreen()をコメントアウトすれば、NiSimpleViewer.cppの先頭にあるサイズで起動する。
#define GL_WIN_SIZE_X 640//1280
#define GL_WIN_SIZE_Y 480//1024

2012年6月28日木曜日

Implementation of Scene Recognition

Introduction


In this page, I explain my attempt to implement a scene recognition. This site has an interpretation enough to accomplish my purpose. As shown in the site, the steps to realize the scene recognition are as follows:
  1. extraction of local features
  2. detection of visual words
  3. construction of histograms by visual words
  4. training of Support Vector Machine(SVM)
  5. prediction by SVM
As the SVM is a supervised learning machine, I needed a number of images to train it. I selected a dataset LSP15. The dataset has indoor and outdoor images that are classified into 15 categories. The number of images in each category is about 200 to 300, and their size is approximately 300x300 pixels. I re-classified 15 categories into 2 ones, and considered a two-class classifier. My guideline is to use the open source libraries such as opencv2 to implement it.

Extraction of Local Features


The opencv2 supplies the class DescriptorExtractor. It has the static method create. Passing a string that indicates a type of local features as an argument to it, it returns the following extractors:
  1. SIFT
  2. SURF
  3. ORB
  4. BRIEF
To densely extract local features from an image, I calculated them on a grid of the image. where, src is an input image, keypoints is a cv::KeyPoint object including coordinates of grid points, and descriptors_ is an output (i.e. descriptors of local features) whose type is cv::Mat.

Detection of Visual Words


From the obtained local features I chose some ones, and ran the k-means clustering over them. The opencv2 has the class BOWKMeansTrainer to do the k-means clustering. After adding the selected local features by the method add, the method cluster is used to run the clustering where, trainer_ is a BOWKMeansTrainer object, descriptors is a set of selected local features, and vocabulary is an output (i.e. centroids of clusters).

Construction of Histograms


For this purpose, I used the class BOWImgDescriptorExtractor supplied by the opencv2. Setting the vocabulary calculated earlier to a BOWImgDescriptorExtractor object bow_extractor_, I calculated a histogram as below, where, keypoints is the same cv::KeyPoint object as used in Extraction of Local Features, and histogram is an output (i.e. histogram). One histogram is obtained from one image. Notice that the histogram calculated above is already normalized.

Training of SVM


The effective kernels to realize a scene recognition are as follows:
  1. χ2 kernel
  2. histogram-intersection kernel
In this study, I used the library shogun that supports these kernels. The library provides unified interfaces to several existing SVM implementations. My calculation procedure is as follows: Two arguments positive and negative passed to the method SvmTrainer::execute are histograms calculated from indoor and outdoor images. On the forth line, they are unified into one quantity features. On the ninth and tenth lines, I creat labels to distinguish between positive(indoor) and negative(outdoor) data. The kernel is constructed and initialized on the twelfth and thirteenth lines. Lastly, on the sixteenth and seventeenth lines, the svm is trained. As shown in the above codes, the backend library is libsvm. After training, the svm object is saved as follows: The library shogun has the method save_serializable that serializes the object. At this point, the classifier is completed.

Prediction by SVM


To restore the svm object, I used the method load_serializable. On the ninth line, the svm object is restored, and the prediction is executed on the twenty first line. The result is returned with the type of shogun::CLabels. It is saved on the twenty third line.

Parameter Setting


extraction of local features

I selected SIFT as the algorithm of the descriptor. Its dimension is 128. The grid interval is 5 pixels. The member variables size and angle in the class cv::KeyPoint are (16,24,32)-pixels and (0,120,240)-degrees, respectively.

detection of visual words

The number of clusters is 10000. The number of descriptors that are passed as an input is 648659. These descriptors are calculated from about one 60th of all images.

construction of histograms

I selected the BruteForce as the local search algorithm.

others

As I said at the start of this page, 15 categories are classified into the indoor group and the outdoor one. The number of images belonging to the indoor group is about half that belonging to the outdoor group. Adding mirror-reversed images to the indoor group, I balanced the number of the indoor images with that of the outdoor images.

Results


I carried out K-fold cross-validation. I set K=3. I partitioned all images into 3 groups, one group was retained as the validation data for testing the svm predictor, and remaining groups were used as training data. The cross-validation process was then repeated 3 times. The 3 results was averaged to produce a single estimation.


χ2kernel

width=0.5, c=10


indoor outdoor
recognition rate 0.820 0.819

histogram-intersection kernel

β=1,c=10


indoor outdoor
recognition rate 0.781 0.827

gauss kernel

width=0.5,c=100


indoor outdoor
recognition rate 0.813 0.805

Todo List


  1. I will open my source codes.
  2. My purpose was to construct the framework of the scene recognition. I used the standard algorithms. I will consider the Gaussian Mixture Model that has a continuous distribution in contrast to the histogram. I would like to study the Fisher's Vector under intense investigation.
  3. I will extend the two-class classifier to 15-class one.
  4. I will consider parallelization by Hadoop to train the svm and predict by it.
  5. I will implement a web application that receives an image from an user and sends a prediction to the user.

Reference Sites

  1. n_hidekey's dialy:This site gives a detailed description of procedures for a scene recognition.
  2. LSP15:dataset used in this page
  3. shogun:SVM library
  4. More Than Technical:an implementation sample of a scene recognition with the opencv
  5. "Trend and Theory in Large-Scale Object and Scene Recognition", Tatsuya Harada.

2012年6月20日水曜日

Point Cloud LibraryのiMacへのインストール 補足

前回書き終えてふと思い出しました。cmakeはxcodeやvisual studioのプロジェクトを作れることを。 「..」は1つ上の階層にCMakeLists.txtがあるので。 出来上がったプロジェクトをコンパイルすると、これが出ます。

The scheme 'openni_grabber' contains no buildables that can be built for the SDKs supported by the run destination My Mac 64-bit. Make sure your targets all specify SDKs that are supported by this version of Xcode.

調べると、Base SDKをCurrent Mac OSに変更すれば良いらしい。確かにコンパイルできました。

2012年6月19日火曜日

Point Cloud LibraryのiMacへのインストール

はじめに

 

 SSII2012のチュートリアルで、Point Cloud Libraryが紹介されていた。これは、デプスセンサの出力値(3次元点群)を処理するためのライブラリである。デプスセンサとしてKinectが有名である。今回、Kinect互換デバイス、Xtion Pro Liveを購入した。以下、サンプルを動かすまでの手順を記す。

環境

  1. iMac
  2. プロセッサ:3.06GHz Intel Core 2 Duo
  3. Mac OS X 10.7.4
  4. Xcode 4.3.3

依存ライブラリのインストール 

 

最初に、macportsを使って以下のパッケージをインストールした。
  1. cmake @2.8.8
  2. boost  @1.49.0
  3. eigen3 @3.0.5
  4. flann @1.7.1
  5. vtk5 @5.8.0
  6. qhull @2012.1
  7. libusb @1.0.9 
いずれのバージョンも、port searchで見つかる最新版である。ただし、libusbだけはuniversalというバリアントを付加する必要がある。 また、vtk5のコンパイルには少々時間がかかる。
次に、OpenNIとSensorのバイナリをここからダウンロードした。
  1. openni-bin-dev-macosx-v1.5.4.0.tar.bz2 
  2. sensor-bin-macosx-v5.1.2.1.tar.bz2
  3. nite-bin-macosx-v1.5.2.21.tar.bz2
niteは必要ないが、ついでである。これを解凍するとディレクトリ内にinstall.shがあるのでこれを実行すれば良い。 ここまでで、Point Cloud Libraryをインストールする準備が整った。

Point Cloud Library(PCL)のインストール 

 

ここからバイナリを手に入れることができる。しかし、PCLのサンプルをコンパイルした際、依存ライブラリとのリンクに失敗した。推奨されている依存ライブラリのバージョンと異なるからであろう。なのでソースからコンパイルすることとした。ソースはここからダウンロードできる。
  1. PCL-1.5.1-Source.tar.bz2
インストール方法はここにある。 デフォルトのインストール先は、/usr/localである。以上でPCLがインストールされた。

サンプルプログラムの実行 

 

PCLを使ったプログラムのコンパイルにはcmakeが推奨されている。今回試した限りではXcodeでも可能である。以下手順を示す。

新規プロジェクトの作成

Command Line Toolとしてプロクジェクトを作成する。

サンプルプログラムの登録

ここにあるサンプルプログラムをプロジェクトに登録する。

コンパイルオプションの設定

Other Linker Flagsに以下を追加する。
-lpcl_common -lpcl_visualization -lboost_thread-mt -lpcl_io -lpcl_filters 

Header Search Pathsに以下を追加する。
/usr/local/include/pcl-1.5/ /opt/local/include /opt/local/include/eigen3/ /usr/include/ni/ /opt/local/include/vtk-5.8/

Library Search Pathsに以下を追加する。
/usr/local/lib /opt/local/lib 

 

実行 

実行すると、以下のエラーが出る。
Open failed: File not found!
node depth problems
node image problems
node ir problems

ここによると、新規にディレクトリ/etc/primesenseを作成し、以下のファイルをその中にコピーせよとある。
  • OpenNI-Bin-Dev-MacOSX-v1.5.4.0/Samples/Config/SamplesConfig.xml
その通りにしても同じエラーが出る。PCLのソース(PCL-1.5.1-Source/io/src/openni_camera/openni_device.cpp)をgrepすると以下の2カ所からSamplesConfig.xmlを読んでいることが分る。
  • /etc/openni/SamplesConfig.xml
  • /etc/primesense/SamplesConfig.xml
従って、/etc/openni/の方にもSamplesConfig.xmlをコピーした。これで実行できた。ただし、
node ir problems
は依然として出たままである。また、Releaseモードでは落ちる。Debugモードでは動く。素直にcmakeを実行した方が良い。追記

2012年6月18日月曜日

シーン認識の実装

はじめに 

 

シーン認識エンジンを実装してみる。
作成手順に付いては、このサイトが詳しい。具体的な処理を書き下ろすと以下のようになる。
  1. 局所特徴量の抽出
  2. Visual Wordの作成
  3. ヒストグラムの作成
  4. SVMの作成  
  5. 予測器の作成
 学習型アルゴリズムであるので、大量の画像を用意しておく必要がある。今回使用した画像セットはLSP15である。15個のカテゴリに分類された室内・室外画像である。各カテゴリには、縦横200から300ピクセル程度の画像が200から300枚ほど含まれている。今回は、15個のカテゴリを室内と室外の2カテゴリに分類し直し、室内・室外を判定する認識エンジンを考察した。実装に当たっては、opencv2など既存のライブラリを最大限利用することとした。

 局所特徴量の抽出

 

 opencv2にはDescriptorExtractorなるクラスが用意されている。このクラスは静的メソッドcreateを持ち、その引数に局所特徴量の種類を文字列として渡すだけで、以下の抽出器を作成することができる。
  1. SIFT
  2. SURF
  3. ORB
  4. BRIEF
さらに、局所特徴量を密に取り出すため一定間隔で画像上の画素を拾い、その点での特徴量を計算した。 ここでsrcは入力画像、keypointsは格子点座標などの情報、descriptors_は出力値(特徴ベクトル)である。出力値の型はcv::Matである。

Visual Wordの作成 

 

先に計算した特徴ベクトルの集合から、いくつか適当に取り出し、これらをクラスタリングする。opencv2にはこれを実行するクラスBOWKMeansTrainerが用意されている。このクラスはメソッドaddclusterを提供する。 addで特徴ベクトルの集合を渡し、 clusterでクラスタリングを実行する。 ここで、trainer_はBOWKMeansTrainerのオブジェクト、descriptorsは特徴ベクトルの集合、vocabularyは出力値(各クラスタの重心座標)である。

ヒストグラムの作成 

 

ここでもopencv2を使用する。クラスBOWImgDescriptorExtractorを利用すれば良い。 先に計算したvocabulary(重心座標の集合)を渡し、 ヒストグラムを計算する。 ここで、bow_extractor_はBOWImgDescriptorExtractorのオブジェクト、srcは入力画像、keypointsは特徴量の抽出時に使用した格子点座標、histogramは出力値(ヒストグラム)である。1枚の画像から1つのヒストグラムが作成される。ヒストグラムの頻度の総和は1に規格化される。

SVMの作成 

 

シーン認識に有効とされるカーネルは以下の2つである。
  1. χ2カーネル
  2. ヒストグラムインターセクションカーネル
今回の考察では、これらをサポートしているSVMライブラリshogunを利用した。このライブラリは複数の既存ライブラリを共通のインターフェースから使えるようにしたラッパーである。計算の手順は以下の通りである。 メソッドexecuteの引数positivenegativeはそれぞれ室内画像、室外画像から作られたヒストグラムの集合である。4行目でこれを1つに統合する。9,10行目で、室内か室外かを区別するラベルを作成する。12,13行目でカーネルを作成する。そして、16,17行目で学習を行っている。ソースから分る通り、実際に計算を行っているのはlibsvmである。 学習のあと、svmのオブジェクトを保存する。 shogunはオブジェクトをシリアライズするメソッドsave_serializableを提供する。これを利用した。ここまでで、識別器が完成した。

予測器の作成 

 

save_serializableの逆を行うメソッドload_serializableを使う。 9行目でsvmオブジェクトを再現し、21行目で予測する。結果はshogun::CLabels型で返される。23行目でこれを保存している。

各種パラメータの設定 

 

特徴量抽出

記述子はSIFTを採用した。次元数は128である。格子間隔は5ピクセルである。クラスcv::KeyPointのメンバ変数sizeの値は(16,24,32)の3つ、同じくメンバ変数angleの値は(0度,120度,240度)とした。

Visual Wordの作成

作成するクラスタの数を1万とした。入力値とした記述子の数は648659個である。これは全画像のおよそ1/60の枚数から算出した記述子の数である。

ヒストグラムの作成

近傍探索のアルゴリズムとしてBruteForceを選択した。

その他

最初に述べたように、15カテゴリを室内と室外の2カテゴリに分けた。室内の画像数は室外の画像数のおよそ半分となった。室内画像に、左右反転画像を追加し2カテゴリの画像数を同程度とした。

結果

 

K-分割交差検定を行った。K=3である。全画像を3分割し、そのうち1つをテスト群、残りを訓練群とした。3回繰り返し認識率の平均値を計算した。

χ2カーネル

width=0.5, c=10


indoor outdoor
認識率 0.820 0.819

ヒストグラムインターセクションカーネル

β=1,c=10


indoor outdoor
認識率 0.781 0.827

ガウスカーネル

width=0.5,c=100


indoor outdoor
認識率 0.813 0.805

 

今後の予定


  1. ソースコードを公開する。
  2. 今回の実装は、シーン認識の骨組みを作ることが目的であった。使用したアルゴリズムはどれも標準的なものばかりである。今回採用したヒストグラム(Bag Of Visual Words)を連続分布で置き換える手法(Gaussian Mixture Model)や、Fisher's Vectorと呼ばれる記述子についても考察する。
  3. 今回は2カテゴリを識別する判別器を作成した。これを15カテゴリに拡張する。
  4. 今回の実装では計算時間を度外視した。高速化も考慮に入れる。hadoopを使った並列化も考察する。
  5. Webブラウザを通して画像を受け付け、判別結果を返す仕組みをdjangoを使って実装する。

参考サイト

 

  1. n_hidekeyの日記:画像認識について大変分りやすくまとめられている。
  2. LSP15:画像セット
  3. shogun:SVMライブラリ
  4. More Than Technical:opencvを用いた画像認識の実装例
  5. 「大規模データを用いた一般物体認識・シーン認識の潮流と理論」:原田達也氏のまとめ。先日のSSII2012でも講演されていた。

追記


ソースを公開すると言いつつしてないですね。ごめんなさい。 以下3つを公開します。
  1. SvmPredictor
  2. SvmTrainer
  3. Common
CommonはSvmPredictor/SvmTrainerで共有しているファイルです。

2012年6月9日土曜日

Syntax Highlighterの導入

ブログの中にソースコードを挿入したい。
調べたところ、Syntax Highlighterなるスクリプトがあることが分った。 面倒そうである。このサイトのhostingのページを見ると、 スクリプトをダウンロードせずともできるとある。 さらに調べると、このサイトWay2Blogging で、最低限必要なスクリプトを自動生成してくれることが分った。自動生成されたスクリプトを、bloggerのテンプレートを記述しているHTML文の中に 挿入すれば良い。挿入箇所は、</head>の直前が良いらしい。 そして、ブログ本文中にコードを挿入するときは以下のようにする。 <script class="brush: cpp" type="syntaxhighlighter"> <![CDATA[ ここにコードを書く(エスケープ不要) ]]> </script> 試しに、手元にあるソースをコピペしてみた。 きれいに表示された。 以下のサイトを参考にしました。
bloggerのテンプレート内に挿入する件:暇つぶし
エスケープの件:Pirates of 富山湾