今日はこちらのイベントに参加してきました。
「コンピュータビジョン・拡張現実感に関する普通じゃない勉強会 2.0」
http://kougaku-navi.net/vrarxr/
詳しい説明は、タロタローグブログ様等でされているみたいなので、ここでは主に僕が興味を持ったものをご紹介します。
< R 2 : Real×Reality >
ARで有名な慶應大学の稲見教授とポストペットの開発者である八谷さん、工学ナビの橋本さんと同じ職場の福地さんとのパネルセッション。
皆さん非常に面白い話をされていて全部紹介したいところですが、中でも八谷さんの視聴覚交換マシンに興味を持ちました。
これは二人の人が装着するHMDで、お互いの視覚と聴覚を交換することができます。つまり相手と向かい合っているときには、自分の姿が見えてしまうというものです。相手の立場(視聴覚)に実際に立ってしまった時にどんな気持ちになるかを、自分で体験してみたいと思わせる作品でした。
< XR : AR Cooking 素材の組み合わせは∞ >
ARToolKitのマーカーを分解し、そのパズルの組み合わせによって異なるCGを表示することで、それを子供の情操教育に役立てようというアプリ。
肉や玉ねぎなどの食材が描かれたマーカーの組み合わせで、ハンバーグやシチューといった異なる料理のCGが表示されます。
今までのAR作品とは違った観点から作られているようで、一般の方向けなのが興味深かったです。
< πR : 盛り上がるディスプレイ >
柔らかいゲルを使ったマルチタッチディスプレイを用いて、2次元の嫁をディスプレイのこちら側に呼ぼうというプロジェクト。
プレゼンの進行がとてもユニークで、三分クッキングのBGMとともにゲル制作実演などが始まったりと、かなり笑わせていただきました。
< ∀R : 生と死を越えるリアリティ >
明治大学の准教授、宮下芳明さんのプレゼン。
ある人の音楽プレイヤーから漏れた音楽を、近くの別な人が自分のプレイヤーに移すことができ、それが子供を作ったり、短期間で死んだりする音楽システム「ノラ音漏れ」のお話。
後半はシリアスになり、亡くなった祖母をネット上に幽霊として蘇らせたいというプロジェクト。
幽霊のお話は何だかオカルトっぽい響きですが、そんなことはなく。
宗教や迷信からではなく、あくまで研究者として挑戦したいとのことでした。
身近な人が亡くなった経験というのは、他の人が思っている以上に衝撃的だったりします。
この技術が、もし本当に役立つのであれば、意義のあることなのではないかと感じました。
ここではご紹介できなかったプレゼンもみんなとても面白い内容で、また勉強になりました。
すごく楽しかったので、第3回も期待しています!
「コンピュータビジョン・拡張現実感に関する普通じゃない勉強会 2.0」
http://kougaku-navi.net/vrarxr/
詳しい説明は、タロタローグブログ様等でされているみたいなので、ここでは主に僕が興味を持ったものをご紹介します。
< R 2 : Real×Reality >
ARで有名な慶應大学の稲見教授とポストペットの開発者である八谷さん、工学ナビの橋本さんと同じ職場の福地さんとのパネルセッション。
皆さん非常に面白い話をされていて全部紹介したいところですが、中でも八谷さんの視聴覚交換マシンに興味を持ちました。
これは二人の人が装着するHMDで、お互いの視覚と聴覚を交換することができます。つまり相手と向かい合っているときには、自分の姿が見えてしまうというものです。相手の立場(視聴覚)に実際に立ってしまった時にどんな気持ちになるかを、自分で体験してみたいと思わせる作品でした。
< XR : AR Cooking 素材の組み合わせは∞ >
ARToolKitのマーカーを分解し、そのパズルの組み合わせによって異なるCGを表示することで、それを子供の情操教育に役立てようというアプリ。
肉や玉ねぎなどの食材が描かれたマーカーの組み合わせで、ハンバーグやシチューといった異なる料理のCGが表示されます。
今までのAR作品とは違った観点から作られているようで、一般の方向けなのが興味深かったです。
< πR : 盛り上がるディスプレイ >
柔らかいゲルを使ったマルチタッチディスプレイを用いて、2次元の嫁をディスプレイのこちら側に呼ぼうというプロジェクト。
プレゼンの進行がとてもユニークで、三分クッキングのBGMとともにゲル制作実演などが始まったりと、かなり笑わせていただきました。
< ∀R : 生と死を越えるリアリティ >
明治大学の准教授、宮下芳明さんのプレゼン。
ある人の音楽プレイヤーから漏れた音楽を、近くの別な人が自分のプレイヤーに移すことができ、それが子供を作ったり、短期間で死んだりする音楽システム「ノラ音漏れ」のお話。
後半はシリアスになり、亡くなった祖母をネット上に幽霊として蘇らせたいというプロジェクト。
幽霊のお話は何だかオカルトっぽい響きですが、そんなことはなく。
宗教や迷信からではなく、あくまで研究者として挑戦したいとのことでした。
身近な人が亡くなった経験というのは、他の人が思っている以上に衝撃的だったりします。
この技術が、もし本当に役立つのであれば、意義のあることなのではないかと感じました。
ここではご紹介できなかったプレゼンもみんなとても面白い内容で、また勉強になりました。
すごく楽しかったので、第3回も期待しています!
Wired Vision連続トークセッション「コミュニケーションデザインの未来」に出席してきました。
基本的には全く専門外のお話でしたが、ARに関するお話もされると聞いて興味を持ちました。
また、濱野さんの記事は以前も読んでいて、とても面白いと思っていたのも出席を決めた理由です。
事前に申し込まないといけないようなので、前の失敗を教訓に即登録。
非常に楽しみにしながら会場に向かいました。
何度も言いますが、トークの主な部分は専門外のため、ARに関係するお話だけピックアップします。
濱野さんはARに興味を持っておられ、その中でもコミュニケーションのためのARに注目されているようでした。
その例として、『場の空気を可視化する「ソーシャルAR(拡張現実)」』のお話、
もうひとつは、『ニコニコ動画とAR(現実拡張)技術が可能にする「ニコニコ現実」』というお話をされていました。
詳細は上記記事を読んでいただければ分かりますが、
・「ソーシャルAR」は現実世界の人間関係を拡張するためのAR
・「ニコニコ現実」は現実のいろんな事象に、ニコニコ動画のようなコメントを付けれる機能
といったような内容です。
僕自身もコミュニケーションのためのARを模索中で、UIをより直感的にすることで情報格差を緩和でき、作業領域や”お互いの空気”を共有することで、離れた相手とも深い共感が味わえるのではないかと考えたりしています。
この辺りの考え方が、今回のトークセッションで重要な言葉として出てきた「コンテンツよりも、それを基盤としたコミュニケーションが重要」(といった趣旨のお言葉)に繋がり、自分の方向性への自信にもなりました。
また、濱野さんの「ニコニコ動画」に関するお話なども聞き、「擬似同期」と呼ばれるコミュニケーションの重要性も再確認しました。
「ニコニコ動画」以外にも中高生版twitterと言われる「リアル」や「アメーバブログ」などのお話もあり、とても興味深かったです。
今回は沢山のお話を聞き、自分の考え方を広げることができました。
トーク自体も楽しく、あっという間の2時間でした。
基本的には全く専門外のお話でしたが、ARに関するお話もされると聞いて興味を持ちました。
また、濱野さんの記事は以前も読んでいて、とても面白いと思っていたのも出席を決めた理由です。
事前に申し込まないといけないようなので、前の失敗を教訓に即登録。
非常に楽しみにしながら会場に向かいました。
何度も言いますが、トークの主な部分は専門外のため、ARに関係するお話だけピックアップします。
濱野さんはARに興味を持っておられ、その中でもコミュニケーションのためのARに注目されているようでした。
その例として、『場の空気を可視化する「ソーシャルAR(拡張現実)」』のお話、
もうひとつは、『ニコニコ動画とAR(現実拡張)技術が可能にする「ニコニコ現実」』というお話をされていました。
詳細は上記記事を読んでいただければ分かりますが、
・「ソーシャルAR」は現実世界の人間関係を拡張するためのAR
・「ニコニコ現実」は現実のいろんな事象に、ニコニコ動画のようなコメントを付けれる機能
といったような内容です。
僕自身もコミュニケーションのためのARを模索中で、UIをより直感的にすることで情報格差を緩和でき、作業領域や”お互いの空気”を共有することで、離れた相手とも深い共感が味わえるのではないかと考えたりしています。
この辺りの考え方が、今回のトークセッションで重要な言葉として出てきた「コンテンツよりも、それを基盤としたコミュニケーションが重要」(といった趣旨のお言葉)に繋がり、自分の方向性への自信にもなりました。
また、濱野さんの「ニコニコ動画」に関するお話なども聞き、「擬似同期」と呼ばれるコミュニケーションの重要性も再確認しました。
「ニコニコ動画」以外にも中高生版twitterと言われる「リアル」や「アメーバブログ」などのお話もあり、とても興味深かったです。
今回は沢山のお話を聞き、自分の考え方を広げることができました。
トーク自体も楽しく、あっという間の2時間でした。
PTAM+ARToolKit+通信機能を合わせた動画を公開しました。
最後の通信の辺りは楽しんでいただけると思います。
詳細ページ:
http://render.s73.xrea.com/pipe_render/2009/03/ptam.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-2-2.html
http://render.s73.xrea.com/pipe_render/2009/04/ptam-3-1.html
BGM:エコテロニカ(sansuiさん)
※また、何度も書きますが、ライセンス上の問題により、
このバージョンのアプリは、実行ファイル・ソースコード共に公開いたしません。
ご了承ください。
最後の通信の辺りは楽しんでいただけると思います。
詳細ページ:
http://render.s73.xrea.com/pipe_render/2009/03/ptam.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-2-2.html
http://render.s73.xrea.com/pipe_render/2009/04/ptam-3-1.html
BGM:エコテロニカ(sansuiさん)
※また、何度も書きますが、ライセンス上の問題により、
このバージョンのアプリは、実行ファイル・ソースコード共に公開いたしません。
ご了承ください。
前回の改良によって、PTAMのCG座標系の中心点をユーザーが決められるようになるので、
この座標系を離れた複数のユーザーで共有することも可能になります。
ARToolKitでもこれは可能でしたが、PTAMの場合はマップを広げることができるので、マーカーが映るのは最初の1回だけでOKになります。
部屋中にマーカーを張ることなく、いろんな方向を見てもトラッキングが失敗しないようにすることが可能です。
この座標系をユーザー間で共有するには、最低限、座標系を表す変換行列(カメラ座標系とワールド座標系の)が必要になります。
----- < 座標系データの送受信 > -----
通信には、とりあえずWinSockを使用することにしました。
ここで送信されるデータは、まだ変換行列程度ですが、速度を重視してUDPを使用します。
Geekなぺーじ:winsockプログラミング
変換行列はmpTracker->GetCurrentPose()で取得できるので、
これをそのまま送ってやることになります。
----- < CGの描画 > -----
受信側でデータを受け取ったら、そのデータを使用してCGを描画します。
この時、この変換行列が”ワールド座標系からカメラ座標系”の変換を表していることに注意してください。
例えば、マップの描画時に新しいカメラを追加する場合はMapViewer::DrawMap()内に処理を追加します。
関数内のDrawCamera(se3CamFromWorld);をもう一つ追加して、その引数に受信した変換行列を設定してやれば終了です。
3Dモデル(4つの目)の描画は、ARDriver::Render()関数内の、mGame.DrawStuff()で行われています。
ただ、この関数をそのまま使うと、引数に指定したベクトル方向に視線を合わせるようになるので、
そこの処理をコメントアウトし、相手のカメラの座標系に合わせる様にします。
この時描画されるCGでは、相手のカメラの位置と方向のみを表すことができます。
なので、PTAMのサンプルに入っている目のCGのような、単純なモデルが適していると思われます。
この座標系を離れた複数のユーザーで共有することも可能になります。
ARToolKitでもこれは可能でしたが、PTAMの場合はマップを広げることができるので、マーカーが映るのは最初の1回だけでOKになります。
部屋中にマーカーを張ることなく、いろんな方向を見てもトラッキングが失敗しないようにすることが可能です。
この座標系をユーザー間で共有するには、最低限、座標系を表す変換行列(カメラ座標系とワールド座標系の)が必要になります。
----- < 座標系データの送受信 > -----
通信には、とりあえずWinSockを使用することにしました。
ここで送信されるデータは、まだ変換行列程度ですが、速度を重視してUDPを使用します。
Geekなぺーじ:winsockプログラミング
変換行列はmpTracker->GetCurrentPose()で取得できるので、
これをそのまま送ってやることになります。
----- < CGの描画 > -----
受信側でデータを受け取ったら、そのデータを使用してCGを描画します。
この時、この変換行列が”ワールド座標系からカメラ座標系”の変換を表していることに注意してください。
例えば、マップの描画時に新しいカメラを追加する場合はMapViewer::DrawMap()内に処理を追加します。
関数内のDrawCamera(se3CamFromWorld);をもう一つ追加して、その引数に受信した変換行列を設定してやれば終了です。
3Dモデル(4つの目)の描画は、ARDriver::Render()関数内の、mGame.DrawStuff()で行われています。
ただ、この関数をそのまま使うと、引数に指定したベクトル方向に視線を合わせるようになるので、
そこの処理をコメントアウトし、相手のカメラの座標系に合わせる様にします。
この時描画されるCGでは、相手のカメラの位置と方向のみを表すことができます。
なので、PTAMのサンプルに入っている目のCGのような、単純なモデルが適していると思われます。
PTAMの問題点の1つに、「マップの3D座標空間が勝手に決められてしまう」というものがあります。
3D座標空間は、初期化完了時に出るグリッド平面で表されます。
これはCGにとっては「地面」を意味しているので、地面が正しい位置にないとCG表示もおかしくなってしまいます。
(例えば、垂直な壁が地面になってしまう等)
この問題を解決するには、地面の決定に別な方法を使う必要があります。例えば、
ここで、上記の項目に何か見覚えがあるものが入っています。それは、「目印」の認識です。
これは、今まで散々使ってきたARToolKitを使えば簡単にできそうです。
----- < ライセンスの問題 > -----
ですが、ARToolKitの利用には、ライセンス面で大きな問題があります。
ARToolKitのライセンスはGPLになっています。
そして、PTAMのライセンスもGPLに近く、しかしこれとは異なるライセンスとなっています。
この2つのソースを一緒にし、そして実行ファイルやソースコードを公開した場合には、2つのライセンスが完全に重なってしまい、ライセンス違反となる危険性があります。
なので、現在のバージョンでは、実行ファイルやソースコードの公開は行えません。
では、出力結果のみを公開する場合はどうでしょうか?
GPLでは、出力結果のみの公開で(条件はありますが)ソースコードの公開義務は発生せず、問題は起きません。
PTAMの、出力結果を公開する場合では、それがPTAMから出力されたことを明記する必要があるようです。
これならば、PTAM+ARToolKitを実行し、その動画を公開した場合には問題がないように思えます。
----- < PTAMでのマーカー認識 > -----
さて、PTAMにてマーカーの認識処理を加える場合、どういった処理が考えられるでしょうか?
2の場合は、マーカーの頂点だけ、他の特徴点とは別な処理を行う必要があります。こちらは逆に簡単ですが、正確性に欠ける場合があります。
理想的には1番なのですが、とりあえず最初に2番で実装してみます。
----- < 実際の変更点 > -----
PTAMのソースにARToolKitの処理を入れます。
2番では、ARToolKitマーカーの認識処理であるarDetectMarkerをPTAM内で呼ぶことになります。
追記(2009/03/31 22:56)
目印は平面であることが分かれば十分なので、SIFTなどの特徴点認識が利用できるかもしれません。
さらに、初期化を行うときの特徴点を平面に固定してしまうなど、いろいろ考えられます。
まぁ目印があればとても分かりやすく、場合によってはPTAMの初期化がいらなくなるので、楽かもしれません。
3D座標空間は、初期化完了時に出るグリッド平面で表されます。
これはCGにとっては「地面」を意味しているので、地面が正しい位置にないとCG表示もおかしくなってしまいます。
(例えば、垂直な壁が地面になってしまう等)
この問題を解決するには、地面の決定に別な方法を使う必要があります。例えば、
- ユーザーのコントロールによって、地面の位置や方向を再調整する。
- 加速度センサーでカメラの下方向を認識、そのベクトルにほぼ垂直で、面を形作っている特徴点の集合を探す
- 地面の位置に目印を置いて、それを認識させる。
ここで、上記の項目に何か見覚えがあるものが入っています。それは、「目印」の認識です。
これは、今まで散々使ってきたARToolKitを使えば簡単にできそうです。
----- < ライセンスの問題 > -----
ですが、ARToolKitの利用には、ライセンス面で大きな問題があります。
ARToolKitのライセンスはGPLになっています。
そして、PTAMのライセンスもGPLに近く、しかしこれとは異なるライセンスとなっています。
この2つのソースを一緒にし、そして実行ファイルやソースコードを公開した場合には、2つのライセンスが完全に重なってしまい、ライセンス違反となる危険性があります。
なので、現在のバージョンでは、実行ファイルやソースコードの公開は行えません。
では、出力結果のみを公開する場合はどうでしょうか?
GPLでは、出力結果のみの公開で(条件はありますが)ソースコードの公開義務は発生せず、問題は起きません。
PTAMの、出力結果を公開する場合では、それがPTAMから出力されたことを明記する必要があるようです。
これならば、PTAM+ARToolKitを実行し、その動画を公開した場合には問題がないように思えます。
----- < PTAMでのマーカー認識 > -----
さて、PTAMにてマーカーの認識処理を加える場合、どういった処理が考えられるでしょうか?
- PTAMのマップ座標系を、マーカーから得られた3Dワールド座標系に合わせる
- 2次元画像内で、マーカーの四角の頂点位置を計算して、特徴点のリストに追加する
2の場合は、マーカーの頂点だけ、他の特徴点とは別な処理を行う必要があります。こちらは逆に簡単ですが、正確性に欠ける場合があります。
理想的には1番なのですが、とりあえず最初に2番で実装してみます。
----- < 実際の変更点 > -----
PTAMのソースにARToolKitの処理を入れます。
2番では、ARToolKitマーカーの認識処理であるarDetectMarkerをPTAM内で呼ぶことになります。
- PTAMプロジェクトにARToolKitの必要なプロジェクトを追加する
- PTAMのループ内で、arDetectMarkerを呼ぶようにする。
- arDetectMarkerの実行結果から、マーカーの頂点座標の値を取得する。
- 取得した頂点座標を、Tracker::TrackForInitialMap()内の特徴点のステレオペアを格納しているところに入れてやる。
- さらにその中で、MapMaker::InitFromStereo()が呼ばれているので、そこでステレオ計算させる。
- ステレオ計算され、3次元情報の点になったら、その4点から基準となる座標系を作成する。
- 作成したマーカー座標系使って、MapMaker::CalcPlaneAligner()内でグリッド平面の位置合わせを行う。
- 変形されたグリッド座標系に合わせるように、MapMaker::ApplyGlobalTransformationToMap()でマップ上の点が変形させられる。
追記(2009/03/31 22:56)
目印は平面であることが分かれば十分なので、SIFTなどの特徴点認識が利用できるかもしれません。
さらに、初期化を行うときの特徴点を平面に固定してしまうなど、いろいろ考えられます。
まぁ目印があればとても分かりやすく、場合によってはPTAMの初期化がいらなくなるので、楽かもしれません。
PTAMは優れたプログラムですが、問題点もいくつかあります。
その1つは、実行にある程度のスペックを必要とすることです。
現在発売されている通常の価格帯のPCであれば、このスペック不足はほとんど問題ありません。
しかし、PTAMをEeePCのような低価格PCや、w-zero3のような携帯端末で実行しようと、これが大きな問題となります。
そこで、その解決方法のうちの1つとして、別スレッドで実行されている「マップの更新」をスレッドで行わずに、
ユーザーの操作によって発生するイベントとして処理する方法を試してみます。
お気づきの方もいると思いますが、このような処理を行った場合、このプログラムは最早PTAM(Parallel Tracking and Mapping)とは言えず、STAM(Serial Tracking and Mapping)(なんじゃそりゃ)になってしまいます。
なので、本末転倒な気がしますが、たとえマップの更新が自動じゃなくても、その他のPTAMの機能はとても魅力的なものです。
これを携帯端末などで動かすことができれば、楽しいことができそうだと考え、改良してみることにしました。
---- < マップの更新処理に必要なもの > ----
この改良で重要なのが、「マップの更新がどのように行われるか?」ということです。
PTAMの解析でも大まかに説明しましたが、マップに特徴点を追加するにはキーフレームが必要になります。
ここで、キーフレームの決め方には2つ方法があります。
1.マップの初期化時に、ユーザーがスペースキーを押した時のフレーム(2個)が、キーフレームとして保存される。
2.マップをトラッキングしている時に、よりキーフレームに適したフレームが、自動的にキーフレームとして選ばれる。
1で決まった2つのキーフレームでは、特徴点のステレオ計算が行われて、3D座標としてマップに追加されます。
2で決まった1つのキーフレームは行列に入れられ、マップの更新スレッドが実行される度に一つずつマップに追加されます。
---- < キーフレームの追加方法 > ----
ということで、更新を手動で行う場合のキーフレームの追加方法も、2つあるということになります。
それは、ユーザーが決める方法と、自動で決めさせる方法です。
・ユーザーが決める場合: 初期化時と同じように、ユーザーが適切なキーフレームを選べるような手助けをしてあげなくてはいけません。
・自動で決めさせる場合: 適切なキーフレームが選ばれますが、それは現在見ている画像とは違うフレームになります。
さて、どちらを選ぶのがより良いでしょうか?
ちなみにPTAMの初期化作業は結構面倒で、慣れないと失敗します。対して、自動の場合はボタン1回押しで済み、フレームの違いも大きな問題にはなりません。
結果、後者の自動キーフレーム生成を選択しました。
キーフレームが追加できたら、あとは任意のタイミングでマップの更新処理を行ってやるだけです。
---- < ソースの変更点 > ----
では実際に、PTAMを改良していきます。
その1つは、実行にある程度のスペックを必要とすることです。
現在発売されている通常の価格帯のPCであれば、このスペック不足はほとんど問題ありません。
しかし、PTAMをEeePCのような低価格PCや、w-zero3のような携帯端末で実行しようと、これが大きな問題となります。
そこで、その解決方法のうちの1つとして、別スレッドで実行されている「マップの更新」をスレッドで行わずに、
ユーザーの操作によって発生するイベントとして処理する方法を試してみます。
お気づきの方もいると思いますが、このような処理を行った場合、このプログラムは最早PTAM(Parallel Tracking and Mapping)とは言えず、STAM(Serial Tracking and Mapping)(なんじゃそりゃ)になってしまいます。
なので、本末転倒な気がしますが、たとえマップの更新が自動じゃなくても、その他のPTAMの機能はとても魅力的なものです。
これを携帯端末などで動かすことができれば、楽しいことができそうだと考え、改良してみることにしました。
---- < マップの更新処理に必要なもの > ----
この改良で重要なのが、「マップの更新がどのように行われるか?」ということです。
PTAMの解析でも大まかに説明しましたが、マップに特徴点を追加するにはキーフレームが必要になります。
ここで、キーフレームの決め方には2つ方法があります。
1.マップの初期化時に、ユーザーがスペースキーを押した時のフレーム(2個)が、キーフレームとして保存される。
2.マップをトラッキングしている時に、よりキーフレームに適したフレームが、自動的にキーフレームとして選ばれる。
1で決まった2つのキーフレームでは、特徴点のステレオ計算が行われて、3D座標としてマップに追加されます。
2で決まった1つのキーフレームは行列に入れられ、マップの更新スレッドが実行される度に一つずつマップに追加されます。
---- < キーフレームの追加方法 > ----
ということで、更新を手動で行う場合のキーフレームの追加方法も、2つあるということになります。
それは、ユーザーが決める方法と、自動で決めさせる方法です。
・ユーザーが決める場合: 初期化時と同じように、ユーザーが適切なキーフレームを選べるような手助けをしてあげなくてはいけません。
・自動で決めさせる場合: 適切なキーフレームが選ばれますが、それは現在見ている画像とは違うフレームになります。
さて、どちらを選ぶのがより良いでしょうか?
ちなみにPTAMの初期化作業は結構面倒で、慣れないと失敗します。対して、自動の場合はボタン1回押しで済み、フレームの違いも大きな問題にはなりません。
結果、後者の自動キーフレーム生成を選択しました。
キーフレームが追加できたら、あとは任意のタイミングでマップの更新処理を行ってやるだけです。
---- < ソースの変更点 > ----
では実際に、PTAMを改良していきます。
- 最初にマップ更新スレッドを切らなくてはいけません。マップ更新のスレッドはMapMakerクラスで行われています。
このクラスはCVD::Threadを継承しているので、この継承関係をコメントアウトします。 - 継承を切ってしまうと、そのままコンパイルした時にエラーが出るので、必要ないもの(run()など)もコメントアウトします。
- ここで、MapMaker::Reset()を行わないようにしてしまうと、マップのリセットなども行われず、プログラムが動きません。
この関数もどこかで呼ばれるようにしましょう。(MapMaker::RequestReset()が呼ばれる所など) - キーフレームをマップに追加する処理は、MapMaker::AddKeyFrameFromTopOfQueue()で行われます。
これを任意のタイミング(スペースキー押下時など)に実行するようにします。 - このままだと、マップの修正処理が行われないので、MapMaker::BundleAdjustAll()などのマップ調整関数も、更新後に行われるようにしましょう。
PTAMの解析が進み、処理の全体像がなんとなく理解できてきたので、
PTAMプログラムへの入門として、動画を作成しました。
解説動画としては、情報が足りませんが、足がかりとして見ていただければと思います。
もう少し詳しい情報のページ:
http://render.s73.xrea.com/pipe_render/2009/03/ptam-1.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-2.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-3.html
BGM:エコテロニカ(sansuiさん)
PTAMプログラムへの入門として、動画を作成しました。
解説動画としては、情報が足りませんが、足がかりとして見ていただければと思います。
もう少し詳しい情報のページ:
http://render.s73.xrea.com/pipe_render/2009/03/ptam-1.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-2.html
http://render.s73.xrea.com/pipe_render/2009/03/ptam-3.html
BGM:エコテロニカ(sansuiさん)
2回目は、PTAMの処理プロセスの概要です。
--------- < 1.マップの初期化 > ---------
"Tracker::TrackFrame内の TrackForInitialMap()"
1.1.ユーザーがキーを押して、初期化スタート Tracker::GUICommandHandler
1.2.最初のキーフレームが決定される Tracker::TrailTracking_Start
1.3.特徴点1000個が検出※1される Tracker::TrailTracking_Start
1.4.特徴点周辺の画像を2Dのパッチにする Tracker::TrailTracking_Start
1.5.ユーザーがキーを押して、初期化終了 Tracker::GUICommandHandler
1.6.2つ目のキーフレームが決定される MapMaker::InitFromStereo
1.7.5点アルゴリズムで※2で、特徴点マップを3Dにする MapMaker::InitFromStereo
また概要になります、すいません。
各プロセスの詳細は、後々解説していこうと思います。
--------- < 処理プロセスについて > ---------
PTAMでの処理は、大きく分けて次のようなものがあります。
1.マップの初期化
2.トラッキング
3.マップの更新
○1のマップの初期化は、一番最初に行われる作業です。
PTAMの動画を見ていると分かりますが、最初にバッチ処理っぽいことを行っています。
この時の画像を元にマップが構築されて、これが基本のマップになります。
○2のトラッキングでは、このマップを元にカメラの位置・姿勢(方向)の推定が行われます。
この処理はスレッドで行われ、coarse-to-fineという手法が用いられます。
coarse-to-fine:最初に大まかなマッチングを行い、大体の位置を確定できたら、次に細かいマイッチングを行って計測を確定するといったような手法です。
○3のマップの更新も別のスレッドで実行され、そのループの先頭では新しいキーフレームを探します。
キーフレームとは、トラッキングがうまくいって、より正確な特徴点が取得できたフレームのことです。たキーフレームは、それぞれある程度離れたものが選択されます。
キーフレームが見つかったら、それを使ってマップを更新します。
マップ上の各特徴点を修正し、新しい特徴点が見つかったらマップに追加します。
キーフレームがない場合は、マップの調整を行います。
バッチ処理でマップ内の特定の範囲を調べて、複数の特徴点で整合性が取れるようにします。
各処理の説明を行います。
"Tracker::TrackFrame内の TrackForInitialMap()"
1.1.ユーザーがキーを押して、初期化スタート Tracker::GUICommandHandler
1.2.最初のキーフレームが決定される Tracker::TrailTracking_Start
1.3.特徴点1000個が検出※1される Tracker::TrailTracking_Start
1.4.特徴点周辺の画像を2Dのパッチにする Tracker::TrailTracking_Start
1.5.ユーザーがキーを押して、初期化終了 Tracker::GUICommandHandler
1.6.2つ目のキーフレームが決定される MapMaker::InitFromStereo
1.7.5点アルゴリズムで※2で、特徴点マップを3Dにする MapMaker::InitFromStereo
1.8.3Dマップに対し、束調整を行う。 MapMaker::BundleAdjustAll
http://www.ric.titech.ac.jp/saneken/stereocamera.htm
2.1.画像を取得する KeyFrame::MakeKeyFrame_Lite
2.2.仮のカメラ姿勢位置※4を計算 Tracker::ApplyMotionModel
2.3.それを使い、マップ上の点を画像に投影する TrackerData::Project
○大まかなマッチング Tracker::TrackMap()内の // ... coarse stage 以下
2.4.特徴が強い点50個を、画像から検索する
2.5.マップの点と50個の特徴点をマッチングする
2.6.マッチング結果からカメラの位置を修正
○詳細なマッチング Tracker::TrackMap()内の // ... fine tracking stage 以下
2.7.1000個の点をマップから画像に再度投影
2.8.画像内からも通常の特徴点を検出
2.9.1000個の点と、画像の特徴点をマッチングする
2.10.最終的なカメラ位置を計算する

再投影誤差は、特徴点追跡に基づく外部パラメータ推定手法で、一般的に用いられる誤差関数であり。再投影誤差の二乗和を最小にすることでカメラパラメータを推定する手法は、バンドル調整法と呼ばれている。
1.9.RANSAC※3で不適切な点を除去 MapMaker::CalcPlaneAligner
※1 徴点の検出:
特徴点の検出(corner detector)という方法がとられています。
特徴点の検出(corner detector)という方法がとられています。
※2 8点アルゴリズム(eight-point algorithm)(5点アルゴリズムは、まだ分かっていません)
・エピポーラ幾何:二つの画像間における幾何学的関係。
・エピポーラ拘束:2つのカメラ間の画像関係の条件、「基準カメラに写ったある点はもう一方の画像上のある直線(エピポーラライン)上に射影される」というもの
・8点アルゴリズム:2枚の画像の8組以上の対応点の組から画像間のエピポーラ拘束を表す行列を求める方法。
※3 RANSAC(RANdom SAmple Consensus):
特徴点の検出で得られた対応点は、間違っている場合(外れ値"outlier")もあるので、これを除去するための処理。
(外れ値の反対は正対応"inlier")
ランダムに幾つかのサンプルを抽出し, 最小二乗法に当てはめることを繰り返す。
抽出したサンプルに外れ値が含まれなければより確からしい推定が得られ, 且つ外れ値の数が全測定数に比べて少なければ推定される誤差範囲内により多くの測定値が含まれる。このことから,もっとも多くの測定値が範囲内に含まれるときの推定を正しい推定とみなす.
--------- < 2.トラッキング > ---------
"Tracker::TrackFrame内の TrackMap()等"
"Tracker::TrackFrame内の TrackMap()等"
2.1.画像を取得する KeyFrame::MakeKeyFrame_Lite
2.2.仮のカメラ姿勢位置※4を計算 Tracker::ApplyMotionModel
2.3.それを使い、マップ上の点を画像に投影する TrackerData::Project
○大まかなマッチング Tracker::TrackMap()内の // ... coarse stage 以下
2.4.特徴が強い点50個を、画像から検索する
2.5.マップの点と50個の特徴点をマッチングする
2.6.マッチング結果からカメラの位置を修正
○詳細なマッチング Tracker::TrackMap()内の // ... fine tracking stage 以下
2.7.1000個の点をマップから画像に再度投影
2.8.画像内からも通常の特徴点を検出
2.9.1000個の点と、画像の特徴点をマッチングする
2.10.最終的なカメラ位置を計算する
※4 仮のカメラの姿勢位置の計算には、運動モデルを用います。この運動モデルでは、カメラの動きが遅いという想定になっています。
--------- < 3.マップの更新 > ---------
MapMaker::run()
3.1.新しいキーフレームがあるかどうか調べる
○新しいキーフレームが見つからなかった場合 QueueSize() == 0
3.1.新しいキーフレームがあるかどうか調べる
○新しいキーフレームが見つからなかった場合 QueueSize() == 0
3.2.キーフレームが見つからなかったら、マップの調整を行う。
3.2.3.どちらもOKなら、データ間の関係を更新する。 MapMaker::ReFindFromFailureQueue
○新しいキーフレームが見つかった場合 QueueSize() > 0
3.2.1.マップが局所的でない場合は、局所的な束調整※5を行う。 MapMaker::BundleAdjustRecent
3.2.2.マップが全体的でない場合は、全体的な束調整を行う。 MapMaker::BundleAdjustAll3.2.3.どちらもOKなら、データ間の関係を更新する。 MapMaker::ReFindFromFailureQueue
○新しいキーフレームが見つかった場合 QueueSize() > 0
3.3.見つかったら、新しい特徴点追加する。 MapMaker::AddKeyFrameFromTopOfQueue
3.3.1.キーフレームのデータ関係を更新 MapMaker::ReFindInSingleKeyFrame
3.3.2.キーフレームを統合する MapMaker::ThinCandidates
3.3.3.新しい特徴点を追加する MapMaker::AddPointEpipolar
3.3.1.キーフレームのデータ関係を更新 MapMaker::ReFindInSingleKeyFrame
3.3.2.キーフレームを統合する MapMaker::ThinCandidates
3.3.3.新しい特徴点を追加する MapMaker::AddPointEpipolar

※5 束調整(bundle adjustment):
再投影誤差の平方和を最小化する方法
再投影誤差は、特徴点追跡に基づく外部パラメータ推定手法で、一般的に用いられる誤差関数であり。再投影誤差の二乗和を最小にすることでカメラパラメータを推定する手法は、バンドル調整法と呼ばれている。
PTAM(Parallel Tracking and Mapping for Small AR Workspaces)の解析を行っております。
正直言って非常に難しいです。
なので、とりあえず概要について説明したいと思います。
また資料として、以下のサイトを参考にさせていただきました。
masayashi:PTAMを15分でなんとなく理解する
Cagylogic:PTAMのアルゴリズムを理解するのに必要な用語
※非常に大雑把に翻訳しているので、誤りや不足があるはずです、ご注意ください。
※また、この内容は未完成で、修正される可能性があります。
○PTAMとは?
マーカーなしのARの手法です。
以下のような特徴があります。
○PTAMの概要
マーカーなしのトラッキングを行える手法は他にもありますが、
PTAMがその他の手法と異なる部分は、次のような処理を行っている点です。
こういった手法には、元々ロボットの研究分野で使われていたSLAM(Simultaneous Localisation and Mapping)という技術が使われています。
参考論文:Real-Time Simultaneous Localisation and Mapping with a Single Camera
ですが、ロボットのカメラを使ったトラッキングと、ARの人が手に持って使うカメラでのトラッキングでは、かなり勝手が違います。ロボットは、走行距離を返してくれたり、ゆっくり動いてもいいですが、人の場合はそうはいきません。
多くの場合、トラッキングとマップの更新は同時行われていますが、人を対象にしたARの場合はこれだと問題(data association errors)が起きてきます。そこで、トラッキングとマップの更新を分離しました。
この2つの処理を分離することにより、この問題を解決できるだけではなく、トラッキングの処理にかける時間を増やすことができます。
この論文では、coarse-to-fineという(高解像度と低解像度の複数の画像を用いる)手法を使うことで、トラッキングの性能を上げることができました。
さらに、フレーム毎にマップを処理するのではなく、うまく認識できたフレーム(キーフレーム)のみを対象にマップの更新を行うことで、ここに重いバッチ処理を使用することができます。
(マップの更新をリアルタイムに行う必要がなくなるので)
このバッチ処理には、"bundle adjustment"という手法を用います。
この手法を用いることで、マップ全体を最適化することができ、さらに安定したマップになります。
正直言って非常に難しいです。
なので、とりあえず概要について説明したいと思います。
また資料として、以下のサイトを参考にさせていただきました。
masayashi:PTAMを15分でなんとなく理解する
Cagylogic:PTAMのアルゴリズムを理解するのに必要な用語
※非常に大雑把に翻訳しているので、誤りや不足があるはずです、ご注意ください。
※また、この内容は未完成で、修正される可能性があります。
○PTAMとは?
マーカーなしのARの手法です。
以下のような特徴があります。
- 初めて映す場所でも実行できる(マーカーなどの目印いらず)
- 最初の場所から少し移動しても、トラッキングし続けることができる。(常にマップを更新)
- マップの更新とトラッキングを別スレッドに分けて処理をしている
- 狭い作業空間(机の上など)を想定している
- 他の手法と比べても、”高速”で”正確”で”安定”している
○PTAMの概要
マーカーなしのトラッキングを行える手法は他にもありますが、
PTAMがその他の手法と異なる部分は、次のような処理を行っている点です。
- トラッキングとマップの更新を分離して、2つのスレッドで実行する
- マップの更新はバッチ処理を使って、キーフレーム毎に行われる
- マップは最初に、ステレオ・ペア(5-Point Algorithm)で初期化される。
- マップの更新時には、エピポーラ幾何が使用される。
- 非常に多数(数千)の点がマップされる。
こういった手法には、元々ロボットの研究分野で使われていたSLAM(Simultaneous Localisation and Mapping)という技術が使われています。
参考論文:Real-Time Simultaneous Localisation and Mapping with a Single Camera
ですが、ロボットのカメラを使ったトラッキングと、ARの人が手に持って使うカメラでのトラッキングでは、かなり勝手が違います。ロボットは、走行距離を返してくれたり、ゆっくり動いてもいいですが、人の場合はそうはいきません。
多くの場合、トラッキングとマップの更新は同時行われていますが、人を対象にしたARの場合はこれだと問題(data association errors)が起きてきます。そこで、トラッキングとマップの更新を分離しました。
この2つの処理を分離することにより、この問題を解決できるだけではなく、トラッキングの処理にかける時間を増やすことができます。
この論文では、coarse-to-fineという(高解像度と低解像度の複数の画像を用いる)手法を使うことで、トラッキングの性能を上げることができました。
さらに、フレーム毎にマップを処理するのではなく、うまく認識できたフレーム(キーフレーム)のみを対象にマップの更新を行うことで、ここに重いバッチ処理を使用することができます。
(マップの更新をリアルタイムに行う必要がなくなるので)
このバッチ処理には、"bundle adjustment"という手法を用います。
この手法を用いることで、マップ全体を最適化することができ、さらに安定したマップになります。
