cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

三次元画像計測システムofxActiveScanをopenFrameworks0.8.4(Windows MSVC2012)で動かしてみる(その1)

比較的小さい物体を綺麗に三次元モデル化したい(しかも対象物体の色が黒っぽくてレーザセンサで計測しづらい)用事があり、一晩ぐらいで何とか解決できる方法がないかなーと考えたとき、山崎俊太郎先生のActiveScanがopenFrameworksのaddon化されていたことを思い出しました。YCAM ProCamToolKit[3]にも実装の多くを依存しています。開発者はmicuatさんです。これを利用してスピード解決を目指します。

1.必要なアイテム確認

必要なハードウェア
・液晶プロジェクター(ここではTAXAN PL201X)
・カメラ(ロジクールHD Webcam C270m)(注意!これではうまく動きませんでした)
・PC(Windows7 MSVC2012)

ソフトウェア環境
・MSVC2012
・openFrameworks 0.8.4

2.ソフトウェアのインストール

次のリンクのGithubからプロジェクトをダウンロードしてきて解凍し、フォルダ名の-masterを削除して、openFrameworksのaddonフォルダの中に放り込みます。micuat/ofxActiveScan · GitHub

また関連addonとしてofxCvが必要ですので、openFrameworks0.84のバージョンに合うものをダウンロードして同様にaddonフォルダに放り込みます。kylemcdonald/ofxCv at 0.8.4 · GitHub

プロジェクトジェネレータを使ってプロジェクトを作ることができるようになりましたので、3つ空のプロジェクトを作ります。いずれも関連addonはofxOpenCVとofxCvです。ofxKinectはキネクト1を使いたい人だけがチェックを入れてください。
プロジェクトの名前は3つのExampleを参考に、
1.myActiveScan_encode
2.myActiveScan_calibrate
3.myActiveScan_triangulate
などにしてください(何でもいいです)。

それぞれのofxActiveScanのexampleのsrcのtestApp.cpp, testApp.h, main.cppをコピーしてきて上書き保存してビルドします。

いずれのExampleにも実行には、config.ymlという設定ファイルが必要ですので、これを準備します。

3.設定ファイルconfig.ymlを編集する

gitに上がっているサンプルを確認してみます。

%YAML:1.0
proWidth: 1280
proHeight: 960
camWidth: 1024
camHeight: 768
grayLow: 0
grayHigh: 80
devID: 0
bufferTime: 1000
vertical_center: 1.12
nsamples: 1000

proWidth, proHeightはプロジェクターの最大実解像度です。
メーカー仕様書を確認するとすぐにわかります。リアル表示XGA(1024×768)とありますので、
proWidth: 1024
proHeight: 768
とします。KG-PL021X | 製品仕様 | TAXANプロジェクター

camWidth, camHeightはUSBカメラの解像度を指定します。同じようにメーカー仕様書を調べるとHD 720p (1280 x 720)を見つけることができますので、
camWidth: 1280
camHeight: 720
とします。HD Webcam C270h

grayLow, grayHighはプロジェクターの投影パターンの輝度を表し、Lowは黒、Highは白を意図します。数値範囲は0-255です。grayHighを投影した結果をカメラで計測した時に、カメラの計測結果が255を超えたサチュレーションを起こさないように注意深く実験して決定する必要があります。最初は、初期設定の通り
grayLow: 0
grayHigh: 80
としておきます。

devIDは、openCVで認識されるカメラ番号を意図しています。
ノートPCなどで内臓カメラがあるときに、USBポートに刺したカメラを使いたい場合、通常内臓カメラに0が振られますので、1以降の番号を指定することになります。
devID: 1

bufferTimeは、1パターンの投影とキャプチャの時間をミリ秒で指定します。
bufferTime: 1000

vertical_centerは、プロジェクターのマニュアルから気を付けて調べる必要があります。
マニュアルには、y value of the principal point of the projector divided by image height (0: top of the image, 1: bottom)とあります。the principal pointは主点と訳されるレンズ光学の用語です。
プロジェクターの光学軸をスクリーンまで延長したと仮定した場合に、スクリーン上のy軸(縦方向)のどの座標を指し示すことになるかを意味します。スクリーンの実投影範囲の上端を座標0、下端を1と正規化して表します。
説明が下手で分かりにくいかと思いますので、PL021Xの場合を例に見てみましょう。

f:id:cvl-robot:20150225143336p:plain

PL021Xの場合、プロジェクターを水平に置いて投影すると、投影面はちょっと上方になります。この投影範囲の上端が0、下端が1です。スクリーンとプロジェクターの光軸の交点は0~1の範囲を超えて、1.ちょっとということになります。メーカースペックとして、h1とh2というパラメータが与えられていますので、次の式で計算することができます。
vertival_center=h1/(h1-h2)
投影距離を自分の場合の設置状況に合わせて適当に、ここでは投写距離を0.68mと仮定して、h1は0.41、h2は0.04と得られますので、
vertical_center: 1.108
とします。そんなに厳密でなくても大丈夫だと思います。

%YAML:1.0
proWidth: 1024
proHeight: 768
camWidth: 1280
camHeight: 720
grayLow: 0
grayHigh: 80
devID: 0
bufferTime: 1000
vertical_center: 1.108
nsamples: 1000

カメラは16:9でなく4:3で動かせるようなので、
camHeight: 960
に変更。

実行テスト

VisualStudioのデバッグなしで開始で実行することを前提に、3つのプロジェクトファイルのそれぞれのデバッグ設定のコマンド引数に、データフォルダへのパスを書き込みます。

..\..\myActiveScan_encode\bin\data

f:id:cvl-robot:20150225234952p:plain

encode->calibrate->triangulationの順で動かしていきます。

f:id:cvl-robot:20150225233954j:plain

このような実験環境で動かして得られた結果がこちらです。

f:id:cvl-robot:20150225235128p:plain
(CAM_MODE)

デキター!と言いたいのですが、残念ながら結果がとてもおかしいです。

EASYCAM_MODEで角度をずらして見てみましょう。

f:id:cvl-robot:20150225235422p:plain

ぐちゃぐちゃです。
キムワイプの箱の角を上からズームアップしてみてみましょう。
一応、デプスっぽくなってはいるようですが・・・。

f:id:cvl-robot:20150225235519p:plain

さて、いったい何が悪くて、どうやって直せばいいんだろう?

[1] https://github.com/micuat/ofxActiveScan
[2] https://github.com/kylemcdonald/ofxCv/tree/0.8.4
[3] Guest Research Project vol.1 | YCAM InterLab

2015年5月号 目次|Interface