【PCL入門】 Point Cloud Library のインストール
今回はPCLを使えるようにするまでを紹介します。
続きを読むWindows 8 で HSP3 アプリを終了時にランタイムエラーが発生する場合の対処
昔 Windows Vista / 7 向けに作ったHSP3製アプリケーションを Windows 8 で動かすと、終了時に "Microsoft Visual C++ Runtime Library Runtime Error" が出る場合があることに気づきました。
同じ症状で困っている人もいるみたい。
なお私の場合は、onexitで別ラベルへ飛ばした後、endを実行するところでランタイムエラーが起こってしまうので原因が不明でした。
と、ここで下記情報を発見:
oncmdで飛んだ先のラベルの中だと普通のエラーがランタイムエラーになってしまうそうです。
この情報を元に下記のコードを試しに実行してみたところ、onexitでも同じようにランタイムエラーが起こることがわかりました。
onexit goto *quit *main wait 10 goto *main *quit mes "quit" error = 1 / 0 // 本来は「Error 19 : 0で除算しました」になる end
ということで、解決策として下記のようにコードを改造しました。
onexit gosub *quit quitFlag = 0 *main if quitFlag : goto *terminate wait 10 goto *main *quit quitFlag = 1 return *terminate mes "quit" error = 1 / 0 // 「Error 19 : 0で除算しました」 end
変更点は次の通り:
- onexitで飛んだ先のラベル内では終了するというフラグだけを立てる
- mainループの中で、常にフラグをチェック
- フラグを元にonexit外のラベルから終了処理ラベルにジャンプ
かっこ悪いですが、これならちゃんと Error 19 になります。
ちなみに、先に述べた拙作アプリにこの改造を行ったところ、endで何のエラーも起こらず終了してくれるようになりました。
とりあえず Windows 8 でランタイムエラーが出るようになったら、まずはこんな風に改造してみるのがいいかもしれません。
VS2013 で FLANN 1.8.4 をビルド
VS2013 での FLANN 1.8.4 のビルドのメモ。
あるヘッダファイルを修正しないとうまくビルドできなかった。
環境
- Windows 7 Professional x64
- Microsoft Visual Studio Premium 2013
エラー内容
error C2228: '.serialize' : 左側がクラス、構造体、共用体ではありません。
修正箇所
- 上記のサイトを参考に、serialization.h内の92行目あたりに3行追加
// declare serializers for simple types BASIC_TYPE_SERIALIZER(char); BASIC_TYPE_SERIALIZER(unsigned char); BASIC_TYPE_SERIALIZER(short); BASIC_TYPE_SERIALIZER(unsigned short); BASIC_TYPE_SERIALIZER(int); BASIC_TYPE_SERIALIZER(unsigned int); BASIC_TYPE_SERIALIZER(long); BASIC_TYPE_SERIALIZER(unsigned long); BASIC_TYPE_SERIALIZER(float); BASIC_TYPE_SERIALIZER(double); BASIC_TYPE_SERIALIZER(bool); #ifdef _MSC_VER // 追加 BASIC_TYPE_SERIALIZER(unsigned __int64); // 追加 #endif // 追加
最終的なビルド手順
- FLANNのソースコードをダウンロード・解凍。今回はC:\FLANN下に解凍した。
- src/cpp/flann/util/serialization.hを上述の通り修正
- cmake して Visual Studio で開けるソリューションファイルを作成
- スタートメニューからCMake (cmake-gui) を起動
- 必要事項を入力して "Configure" を押す
- "Where is the source code:" に "C:\FLANN"
- "Where to build the binaries:" に "C:\FLANN\build" (どこでもいい)
- 何か設定が必要であればする
- 今回は特に何もしない
- "Generate" を押す
- C:\FLANN\build に作成された flann.sln を管理者権限で開く
- 下記のINSTALLで、ビルドしたファイルをProgram Files下にコピーするのに管理者権限が必要
- INSTALLしなくていいなら flann.sln は普通に開いてよい
- 先に Visual Studio 2013 を管理者権限で開いてから flann.sln を開くとよい
- 下記のINSTALLで、ビルドしたファイルをProgram Files下にコピーするのに管理者権限が必要
- メニュー「ビルド」→「バッチビルド」をクリック
- 次の4つにチェックを入れて「ビルド」を押す
- ALL_BUILD (Debug)
- ALL_BUILD (Release)
- INSTALL (Debug)
- INSTALL (Release)
VS2013 で Boost 1.55.0 をビルド
VS2013 での Boost 1.55.0 のビルドのメモ。あるヘッダーファイルに修正を加えてからでないとビルドが成功しなかった。
環境
- Windows 7 Professional x64
- Visual Studio Premium 2013
エラー内容
c:\Boost\boost_1_55_0\boost/archive/iterators/transform_width.hpp(151) : error C2039: 'min' : 'std' のメンバーではありません。 c:\Boost\boost_1_55_0\boost/archive/iterators/transform_width.hpp(151) : error C3861: 'min': 識別子が見つかりませんでした
修正箇所
- 参考:https://svn.boost.org/trac/boost/ticket/9196
- boost/archive/iterators/transform_width.hppの冒頭部分に algorithmのインクルードを追加
#include <boost/config.hpp> #include <boost/serialization/pfto.hpp> #include <algorithm> // 追加箇所 #include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_traits.hpp>
最終的なビルド手順
- Boostのソースをダウンロードして解凍する。今回はC:\Boost下に解凍。
- boost/archive/iterators/transform_width.hppを上述の通り修正
- 開発者コマンドプロンプトを開く
- 「スタートメニュー」→「Visual Studio 2013」→「Visual Studio ツール」
- ショートカットフォルダが開く
- (C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts)
- 「開発者コマンドプロンプト for VS2013」を起動
- コマンドを入力してビルド、インストール
- パラメータの意味は次の通り
- toolset: msvc-12.0 (VS2013) のコンパイラを使用
- link: static link library (.lib) か dynamic link library (.dll) か
- runtime-link: C/C++ランタイムライブラリを static link するか dynamic link するか
- address-model: 32bit か 64bit か
- build-dir: ビルド用ディレクトリ
- stagedir: libを出力する場所
- j: このビルドをする際に使用するCPUコア数 (並列処理)
- install --prefix: インストール先
- パラメータの意味は次の通り
> cd C:\Boost\boost_1_55_0 > bootstrap.bat > b2.exe toolset=msvc-12.0 link=static runtime-link=static,shared --build-dir=build/x64 --stagedir=stage/x64 address-model=64 -j 8 install --prefix="../"
Structure Sensor から距離画像やポイントクラウドを取得
前回の「Structure Sensor を Windows へ接続」の続きです。OpenNI2を使って距離画像(深度画像)・赤外線画像・ポイントクラウドを取得してみました。
ソースコード
Structure Sensor からデータを取得するC++のモジュール "structure_grabber" をGithubにおきました。
概要
距離画像・ポイントクラウドの取得は下記4つのファイルとOpenNI2ライブラリで可能です。
- structure_grabber.h
- structure_grabber.cpp
- oni2_grabber.h
- oni2_grabber.cpp
ただし、上記GitHubのサンプル内では、Visualizeのために距離画像についてはOpenCVを、ポイントクラウドについてはPoint Cloud Library (PCL)を使っています。
簡単な使い方
データ取得の方法を簡単に書くと下記の通りになります。
- インクルード:
#include <opencv2/opencv.hpp> #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include "structure_grabber.h"
- 設定
StructureGrabber grabber; grabber.enableDepth(); grabber.enableInfrared(); grabber.setDepthRange(0.3, 5.0); grabber.open();
- データの取得:
cv::Mat depth_image, infrared_image; pcl::PointCloud<pcl::PointXYZ> cloud; grabber.acquire(); grabber.copyDepthImageTo(depth_image); grabber.copyInfraredImageTo(infrared_image); grabber.copyPointCloudTo(cloud);
撮影結果1
撮影対象:
机の上にコップとお椀、後ろには椅子とホワイトボード。
距離画像と赤外線画像:
赤外線のLightCodingパターンが辛うじて見えます
(おまけ) 色付き距離画像:
ポイントクラウド:
結構キレイにとれている感じがします。
撮影結果2
撮影対象:
廊下のT字路
距離画像と赤外線画像:
赤外線画像は人の目には何も見えない状態です。
ポイントクラウド:
3本の線は座標軸です。交点が撮影視点で、赤がX軸、緑がY軸、青がZ軸。
ちなみに俯瞰すると、遠くの方では誤差が目立ちます。
Kinectでも遠すぎるとこうなりますね。
さらに、4,5m離れた先では取得データが丸みを帯びてしまいます。
画像左側の円弧のように点が濃く分布しているところは、実際には平面です。公式データでは「40cm~3.5mの範囲で利用可能」と書いてありましたが、その通りなようです。
まとめ
- Structure Sensor を叩くモジュールを実装しました。
- 4m以上遠い場所の正確な3次元データは得られないことがわかりました。
Structure Sensor を Windows へ接続
はじめに
"Structure Sensor" というiOS向けの超小型デプスセンサーについて、いろいろな方が既にレビューをされています。(ちなみにデプスセンサーとは距離情報を取得できるセンサーで、MicrosoftのKinectを契機にかなり有名になりました。)
ただ、書かれている記事のほとんどが「iOSに繋げてみた」「デモアプリを使ってみた」ばかりのようなので、私は「iOS以外にUSB接続して、自力でデータを取り出す方法」を書きたいと思います。具体的には、今回はまず「Windowsから Structure Sensor を触る方法」を書いて、後に「Windowsで深度画像とポイントクラウドを取り出す方法」を書く予定です。
- (2014/07/02追記) 次記事:
環境の準備
Structure Sensor は iOS からは Structure SDK というものを使えば触ることができます。そしてiOS以外の場合は OpenNI2 (OpenNI1ではダメ) を使えばよいそうです。
というわけで、まずOpenNI2を用意。
OpenNI2は今はStructure Sensorの下記のサイトからバイナリやドキュメントがダウンロードできます。
インストール後はOpenNI2のフォルダ内のどこかにあるPS1080.ini内の
;UsbInterface=2
になっているところを
UsbInterface=0
に修正します。これでStructure Sensorからデータを読み出すことができるようになりました。