ページ

2014年2月7日金曜日

Creative Senz3DをPoint Cloud Libraryで利用する

Depthカメラから取得されるような点群データを汎用的に扱うライブラリとして、Point Cloud Library (PCL)というものが存在します。このPCLがついこの前、バージョン1.7.1からCreativeのSenz3DというDepthカメラに対応しました。
しかし、公式ページのダウンロードページにはPCL 1.5.1までのバイナリしか用意されていないために、このままではWindows環境でPCLからSenz3Dを利用することはできません。

そこで、公式ページのチュートリアルに則ってWindows環境にインストールしてみました。

--

まず、ビルドに必要なライブラリを公式ページのダウンロードページにある3rd Party Librariesで確認して、ダウンロード、インストールしておきます。boost、Eigen、FLANN、VTK、Qt、QHull、OpenNI、あとはこれらに加えてIntel Perceptual Computing SDK(PerC SDK)が必要です。

ビルドはCMakeを利用して行います。インストールしていない場合にはここからWindows版バイナリをインストールしておきます。また、チュートリアルではコンパイラにVisual Studio 2010を利用します。こちらも併せてインストールしておく必要があります。

次に、githubのプロジェクトページからソースコードをZIPでダウンロードします。
適当なディレクトリに解答して、CMakeを開き

Source Directory: C:/unzipped directory/PCL 1.7.1
Build Directory: C:/unzipped directory/PCL 1.7.1/build

みたいに指定します。この状態でとりあえずConfigureを押すと、CMakeさんが依存関係のあるライブラリのパスを色々探してくれます。GeneratorにはVisual Studio 10を選択します。
※前に別のプロジェクトでCMakeを利用した事がある場合には、Configureを押す前に、Delete Cacheしておきましょう。

全てインストーラのデフォルトパスにインストールした場合には問題無いと思いますが、
依存関係のあるライブラリをインストールしていても、CMakeが正しく見つけられない場合があります。その場合にはConfigureがErrorを表示して失敗してしまい、ビルド用のプロジェクトをGenerateすることができません。CMakeが正しくライブラリを見つけられるようにフィールドを修正する必要があります。修正はチュートリアルの通りにやれば大丈夫です。

CMakeのGenerateが成功したら、VSでソリューションを開いてビルドします。
この時、Releaseビルドを選択してビルドします。PCL 1.7.1ではPerC SDK経由でSenz3Dから情報を取得しますが、PCL 1.7.1のFindPXCAPI.cmakeはPerC SDKのRelease版ライブラリの場所がハードコードされていて、Debugビルドを行うとビルドに失敗するためです。また、環境にかかわらず64bit版のDLLをロードしようとするために、32bit環境ではリンクに失敗します。その際には、PCLを解凍したディレクトリのcmake/Modules/FindPXCAPI.cmakeを

set(PXCAPI_LIB_DIRS ${PXCAPI_DIR}/lib/Win32 ${PXCAPI_DIR}/sample/common/lib/Win32/v100)
set(PXCAPI_LIBS ${PXCAPI_DIR}/lib/Win32/libpxc.lib ${PXCAPI_DIR}/sample/common/lib/Win32/v100/libpxcutils.lib)

のように修正して、32bit版のDLLが読み込まれるように設定します。また、PCLをDebugビルドする場合にはlibpxc_d.lib、libpxcutils_d.libを読み込むようにこのファイルを変更します。変更を行わずにReleaseのlibファイルを読み込んだ状態でDebugビルドを行うと、

error LNK2038: '_ITERATOR_DEBUG_LEVEL' の不一致が検出されました。値 '0' が 2 の値 'pcl_io_debug.obj' と一致しません。

リンク時にのようなエラーが表示されてしまいます。

--

コンパイルエラーの解消


ビルドを行うと、
png_io.hの147行目で

error C2143: 構文エラー : ';' が ''template<'' の前にありません。

のようなエラーが表示されてビルドが失敗します。これは、PCL_DEPRECATEDマクロをtemplate関数に利用するとVSのコンパイラがエラーを表示するという問題のようで、Githubのmasterでは既に修正されている問題のようです。

どうやら1.7.1 releaseではこのバグが修正されていないようですので、このPull Requestにならって、png_io.hの147行目を

template <typename T>
PCL_DEPRECATED (void savePNGFile (const std::string& file_name, const pcl::PointCloud<T>& cloud),

のように修正したところ、ビルドが通りました。これはどうやらWindows環境限定の問題らしく、1.7.1ではテストから漏れていたようです。

リンカエラーの解消


リンクの段階でも、pcl_ioで以下のようなエラーが発生します。

error LNK2005: "public: void __thiscall std::_Container_base0::_Orphan_all(void)" (?_Orphan_all@_Container_base0@std@@QAEXXZ) は既に libpxcutils.lib(util_pipeline_raw.obj) で定義されています。

これは、MSVCランタイムが2回インクルードされていることが原因らしいです。
pcl_ioのほうではMulti-threaded DLL (/MD)オプションが指定されているのに、libpxcutils.dllのほうではMulti-threaded (/MT)オプションが指定されていて、それが原因になって不具合が発生しているようです。
※MDオプションとMTオプションの違いはMSDNが詳しいです。特に何も指定しない場合はMTが適用されるそうです。

この問題を解決するために、libpxcutilsをオプションを変更してリビルドします。
libpxcutlisのソースディレクトリ(デフォルトはC:\Program Files\Intel\PCSDK\sample\common)に移動して、vs2010用のソリューションファイルを開きます。次に、libpxcutilsのプロパティを開き、構成プロパティ > C/C++ > コード生成 > ランタイムライブラリの設定をマルチスレッド DLL (/MD)に変更します。そして、Releaseビルドを選択してビルドします。

そして、libpxcutils.libファイルがlib\Win32\v100に新しく生成されたことを確認して、pcl_ioをビルドします。これで上手くビルドできると思います。

--

ビルドが完了したら、INSTALLプロジェクトをビルドすることでC:\Program Files\PCLに生成されたファイルがコピーされます。インストール先のC:\Program Files\PCL\binにpathを通しておきましょう。

Senz3DをPCLを通して利用する場合には、以下の様なソースコードを含んだソリューションを作成します。


ソリューションの設定でPCL、boost、Eigen、FLANN、VTK、Qt、QHull、OpenNIとPerCのインクルードディレクトリとリンカディレクトリを設定して、依存ファイルpcl_common_release.lib、pcl_io_release.lib、pcl_visualization_release.libを追加します。設定済みのソリューションをGithubにアップしておきました。
なお、この時ReleaseビルドされたPCLをリンクする場合には、ソリューションもRelease設定にする必要があります。 ここを間違えると、pcl::visualization::CloudViewerのコンストラクタで実行時にbad_alloc例外が出ます。

--

ビルドして実行すると、CloudViewerにSenz3Dから取得された点群が表示されます。



PerC SDKがアクティベートされるまでにしばらく時間がかかるので、起動して少し待たないと点群が表示されないようです。また、手持ちの環境では動作が重く、1fpsも出ませんでした。CloudViewerは高いフレームレートの描画には向いていないようなので、アプリケーションとして利用する場合には自前で描画するのが良さそうです。

0 件のコメント:

コメントを投稿