AR進捗報告

 Boltzmanです。最近、にゃとらん様のNyARToolkit(http://nyatla.jp/nyartoolkit/wp/)を使って、UnityでARをやりたいなぁとか考えています。その進捗報告を少し。

 まず、NyARToolkitのsample内にあるARCameraBehaviourが、固定されたカメラに対してオブジェクトを再配置する仕組みだったので、これを少し書き換えて、”ARMarker”という名前の空のゲームオブジェクトに対してカメラの位置を再配置する方式に変えた、”ARCamera”を作成しました。この際、初めはNyARUnityUtils.NyARUnityMarkerSystem内にあるsetMarkerTransformにおいて、NyARUnityUtil.toCameraViewRHに渡されている、getMarkerMatrix(i_id)をいったん受け取って、これを逆行列にしてからtoCameraViewRHに渡して、帰ってきた位置pと姿勢rをカメラのlocalPosition,localRotationに突っ込んでみたのですがこれがうまくいきませんでした。そのあとtoCameraViewRHの中身をよくよく覗いてみたところ、行列の(1,1)(2,2)(2,3)(3,1)成分に負符号がついているのがわかりました。マーカー検出関係のところまで潜ってちゃんとこの負符号の意味を明らかにしようと思いましたが、平行移動量計算機にセットしたあたりで読むのをやめました…。というのも、ちょうどこの辺でプログラムがうまくいってしまったためです。結局どうやったらうまくいったのかというと、

1.getMarkerMatrix(i_id)で座標変換行列を取得する。
2.その行列を、先ほどのものとは引数の違うtoCameraViewRHに渡して、元の行列の(1,1)(2,2)(2,3)(3,1)成分に負符号をつけた行列をもらう。
3.もらった行列の逆行列を取って、NyARUnityUtil.mat2UnityVecRotという関数に渡して、位置pと姿勢rを受け取る。
4.pとrをカメラのlocalPositionとlocalRotationに渡す。

といった感じです。本当は背景平面の位置を90度動かす処理もしましたが割愛。
要するに、初めのやり方では「逆行列に変換->負符号をつける->位置と姿勢を抽出する」という順番だったものを、「負符号をつける->逆行列に変換->位置と姿勢を抽出する」という順番にしたらうまくいったという話です。この際、元のtoCameraViewRHでは「負符号をつける」処理と「位置と姿勢を抽出する」処理が一緒になってしまっていたので、これをtoCameraViewRHとmat2UnityVecRotに分けたというわけです。なお負符号の理由は分からなかった模様。

 こういう、根本的でない解決って私は割とやってしまうのですが、良くないなぁとも思います。実際、この問題を解決しているときも、そういう場当たり的な解決がよくないと思ったから平行移動計算機まで遡りました。今は正直原因究明を放置してしまっていますが、現在ちょっとNyARMarkerSystemを自分で一通り書き下しておりまして、その際にNyARMarkerSystem内の処理を一つ一つ理解していっています。現在はまだ二値化の閾値決定のところですが…。まあそもそも画像処理系の部分に今までタッチしてこなっかため(それでARやってるとか大きな声では言えない)、ほとんどが初見で非常に勉強になります。こういうのも、既存のコードを使う良いところだと思います。将来的にはすべて自分で実装しようと考えています。で、話が飛んでしまったのですが、こうしてNyARToolkitを解析する中で、負符号の意味にも気付けたらなどと考えています。

 P.S. NyARToolkitってなかなか面白いのでぜひ見てみてください。何が面白いのかはソースコード見てみればたぶんわかります。

Posted on