AR

二値化を実装しました。

Boltzmanです. テスト期間中だろうが活動をやめないKCSです. (余裕の記事投稿だ. 馬力が違いますよ. )

今回は「魚眼 de AR」の第二回です. 続きましたね. (“ドゥ”ではなく”デ”と読んでください. Moi, je suis japonais. )今回は画像の二値化をUnityで実装してみました.

そういえば初めて投稿した記事で画像解析なんてしないみたいなことを言った気がしますが, あれは嘘です. まあその道の人になるつもりはありませんが, 必要とあらば首を突っ込むのも辞さないというスタンスでやっております.

 

自分で二値化をやったことがないと, 二値化の閾値自動決定アルゴリズムを作るときにイメージが湧きづらいので良い経験になりました. 以下に結果の画像だけ先に提示します.

th1 th2

なんかTwitterにあふれる自撮りみたいになってしまって甚だ悲しいですが, おかげでいい感じに二値化できているのがわかると思います. 結果を見やすくするための致し方ない犠牲です.

実行速度は目に見えて遅いです. 映像がカクつきます.

 

方法としては, まずWebカメラの画像をWebCamTextureで受け取り, forループ(iとjの二重)でWebCamTextureのGetPixcel(i,j).grayscaleと閾値を比較し(比較対象はgrayscaleであってるのか…?), 結果をColor32[]に突っ込んで, ループが終わったらColor32[]を別に用意したTexture2DのSetPixcels32()に突っ込んでApply()で適用するといった感じです(伝われ). 上の画像では閾値=0.3でやっています.

他の部員に見てもらって手直しします. 果たして原型は残るのだろうか.

つづけ.

 

魚眼レンズを買いました

Boltzmanです. 魚眼レンズを買いました.

160121_1934

TAO TRONICSの「CLIP-ON LENS SET」というやつです.

以前から(具体的には昨年の秋ごろから)魚眼レンズを用いたARというものをぼんやりと考えており, ついに重たい腰を上げました.

魚眼でARをするモチベーションは, 視野が広いことです.

以前, 物理演算を適用したARを作った際に, カメラで仮想動体を追いかけようとして, 途中でカメラからマーカーが外れて表示されなくなってしまう, というのを経験して, なんとなく物足りない気分でいました. そんなとき, 研究室の方がRICOHのTHETAを使って写真撮影するのを見て初めて魚眼レンズというものを体験し, これならカメラがどこを向いていてもマーカーをロストしないのではないか, と思い立ち, 魚眼でARをやってみようかなと考えました.

で, 今回はとりあえず, 特にプログラムを書き換えずにカメラだけ変えてみたという回です.

続編があるかどうかは分からない.

 

FE2 FE1

顔を消すための雑な加工には触れない方向で….

これはARToolkitのSimpleLite.exeです. 二つの写真でマーカーとカメラは同じ位置に配置しています. 魚眼レンズによってかなり広い視野が獲得できているのがわかります.

中央付近でマーカーを動かしたところ, 魚眼をつけたときはつけない時と比べて検出率が低下しました. 中央付近では歪みが少ないため, 検出率はそんなに落ちないかと思ったのですが, 意外と目に見えて落ちました. 上の写真でも, なしの時は検知しているのにありの時は検知できていません.

FE7

魚眼アリでも検出できるときはあります.

 

FE3 FE4

こちらはもう少しカメラに寄ったものです. カメラに寄っても, 中央だとあまり検知してくれない印象を受けました. これもカメラの位置とマーカーの位置は二つの画像で同じです.

 

FE5 FE6

魚眼だと, 普通のカメラだと映らないところも映ります. この二つの写真もやはり, カメラの位置とマーカーの位置は同じで, 違いはレンズの有無だけです. 意外だったのは, 中央よりも隅のほうが検出率が高く安定していたことです. 歪が大きいのになぜだろう….

 

FE8 FE9

NyARToolkitのSimpleLiteでもやってみました. こちらは中央でも良く検出してくれました.

 

本来ならば検出率を定量的に比べるべきですが, 今回は完全に感覚なので信頼度は低いです. 気力があれば定量的な測定をするかもしれませんが, それをやるならまず閾値決定アルゴリズムを変える必要がありますね. 検出できていないのが明るさのためなのかレンズの歪のためなのかがわからないので…. NyARToolkitには複数の閾値決定アルゴリズムが実装されているので, そちらに切り替えるのもよいかもしれません.

ではまた.

【年末特番】ARの作る未来

Boltzmanです. いつも通りの戯言を垂れ流していきます.
こう, 大雑把な話題を取り上げるたびに, 己が具体的な進捗を生めていないという現実を痛感して, 非常に悲しい気持ちになります. 全く進捗がないというわけではないのですが, 具体的には, ARCameraというコンポーネントを作ってインスペクタからマーカーとして使うテクスチャのパスや, マーカーの尺などの要素を設定できるようにしようと思ったのですが, やっているうちにここはこうしたほうがいいという点がいろいろ見つかって, 気づいたらARMarkerの中にARMarkerSystemの内容を書き下していて, updateまで書き下したのはいいものの, コールバック関数隠蔽用のクラスなるOnSquareDetectも書き下さないといけないことがわかり, _(:3」∠)_ばたんきゅーといった感じです. それくらいがんばれよ自分! ただ書き下すだけならコピペでいいのですが, 写しながら内容を理解してその都度仕様を考えているので, なかなかこう, やりがいがありますね!!!

ということで今回のメインは私の考えるARの未来です. 自分の分野によって未来の世界がどのように変わっていくかを考えることは, 一つには自分のモチベーションにつながりますし, 他人に「それってどう役に立つの?」と尋ねられた場合の答えに窮しなくなりますし(これが非常によく問われる質問です. 必ず二言目に尋ねられます), また一つの責任でもあると考えています. 自分の生み出した技術の行く末くらい, 見守っていきたいものです. さて本来はこれはどちらかといえば文学者の仕事ですね. 文学者は往々にしてこのような未来予想図を描くのに非常に長けた人種であるように思います. 本当に頭が下がります. 一昔前は, 困ったことがあったら文学者に問うていたそうです. たぶんサルトルあたりの時代. 森博嗣様や時雨沢恵一様の作品は特にこういった色を感じるように思います. ですから, 私個人が未来予想することに一切の普遍的価値はないのですが, 先述した理由のために, 自分なりの予測をしたいと考えます. 続きを読む

なぜUnityでARなのか、という話

 Boltzmanです。相変わらずnは一つです。
 前回の記事で、なぜわざわざUnityでARをやるのか、という点を書いていなかったため、それについて今回は言及していきたいと思います。

 そもそも、私にとってのARの本質は、画像処理ではなく、いかに物をリアルに見せるか、ということです。どのようなものがリアルに見えるのか、という問いに対する答えは様々あるように思います。光源の位置を現実の光源の位置に合わせる、物理シミュレーションを適用する、立体視できるようにする、触れるようにする…。上げ始めたらきりがないのではと思います。当HPでMMD実写合成の記事を投稿しているIntenさんも、目指すところはリアリティーといえるのではないでしょうか。
 純粋なAR、つまり画像処理によって現実の空間を把握し、その上に仮想オブジェクトを配置するというだけなら、Unityなんていう冗長なものを使う必要はありませんが、先述したリアルの要素のうち、少なくとも「物理シミュレーション」と「光源の位置を現実のものに合わせる」という2点において、Unityは便利なのではと考えたので、Unityに移行しました。実際に使ってみると、一番有用なのはsceneビューですね。オブジェクトや光源のレイアウトがやりやすいです。また、いままで使っていたのがCなので、オブジェクト指向というものにも初めてあてられました。とても勉強になります。

 実は(?)物理シミュレーションだけならUnity以前にも適用したことがあります。具体的には、ARToolkitとOpenDynamicsEngineを組み合わせました。なかなかうまくいったように思います。
 多くの情強の皆さんは「光源も自分でいじれks」とお思いになるかもしれません。し、まあド正論なのですが…。一応、サークルに、Unityを使って気軽にARゲームが作れるようなパッケージを遺したいという意図もあったりします。後輩に少しでも自分のやったことを遺せるといいです。
 Unityへの移行がつつがなく終わったら、自分の研究と並行して、デモンストレーションとしてゲームを一本、三田祭に向けて作りたいなぁとも考えています。前回の記事にも書きましたが、NyARToolkitからもぼちぼち卒業しなくては、と思っています。

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ってなかなか面白いのでぜひ見てみてください。何が面白いのかはソースコード見てみればたぶんわかります。

準備的考察-仮想世界の保有すべき情報量-(投稿テスト)

  • 導入

 これからするのは、自分が今後研究しておくことに対する準備的考察であって、別段公にする必要はないのかもしれない。しかしながら、こういった、自分が他者の知らぬ間に前提としていることは、往々にして研究を大きく色づける。工学の道は広く、一つの問題を解決するのに数多くの手段が存在するのは言うまでもないが、そのどれを選ぶがということは、研究をする者のもつバックグラウンドを大きく反映する。よって私が準備的考察をここに書くのは、今後私の研究を受け取るかもしれない人々に私の持つ背景を伝えることによって、アプローチを合理的に感じてもらおうと、そういうことである。

  • “バーチャルな”金魚の例

 これから私が議論しようとしていることに関して、一つ例を挙げてみよう。

 ここに一つの水槽がある。あなたは金魚を飼いたくて、とりあえず水槽を買ったはいいものの、どうにも自分が生き物をすぐにダメにしてしまうタチだと心得ている。そこで、「現実の金魚を飼うのではなく”バーチャルな”金魚を飼おう」と思いついた。(ここの発想の飛躍は認めるものとせよ)。さて、あなたが飼う”バーチャルな”金魚の持つべき情報量はいったいどれくらいであるか、というのが私の問いである。

 例を続けよう。あなたは適当なAR(拡張現実)の知識を手に入れて、さらには金魚のふるまい(アニメーション)もうまく作れた。ディスプレイを通して見ると、彼はあなたの買った水槽の中で、悠々と泳いでいる。さて、ここであなたは「ちょっと水槽の中が寂しいな」と考える。あなたは水槽しか買っていなかったから、中身はからっぽのままだった。これは自然な発想かと思う。さて、あなたは人工的な水草の模型を買ってきた。これを水槽に落とし込む。しかし、このままだと金魚が水草をすり抜けてしまう。これでは具合が悪い。金魚は水草をさけるべきだ。そのためには、金魚は「そこに水草があること」を”知って”いなければならない。”知って”いなければ、彼は水草をよけることはできない。”見えない”ものをよけるのは無理があるだろう。そこであなたはこう考えた。「人間の目みたいに、カメラを二つ用意すれば、コンピュータも立体的にものを見れるに違いない!」。そして、「カメラ2つで作ったコンピュータの”目”で水槽を見れば、『どこにどんな形のものがあるか』が”バーチャルな”金魚にもわかるはずだ」。

 ここで明記しておきたいのは、このカメラの”目”は、あなたの視点であるということである。ARとはそういう技術である。ARは、あなたが見るであろう物を、いったんカメラで”見て”、”バーチャルな”ものを上書きしてから、あなたに見せる。3人称視点も可能だが、あなたの視点としよう。それが一番自然なように思われる。なぜこの点を言及したかということは後にわかる。

 さて、あなたは再び、適切な知識を得てそれを実現することができた。できたとしよう。コンピュータはカメラの”目”で水槽を見て、水草の形状を”バーチャルな”金魚に伝え、金魚はそれをよけることができるようになった。ここまで来ればしめたものである。もうあなたが水槽の中に何を置こうと、カメラの”目”によって形状を把握し、金魚はそれを知ることができる。さあ色々なものを置いてみよう。手にした技術を様々に適用するのは良いことである。ふと考えた。「金魚の隠れ家がほしいな」。あなたは植木鉢を伏せた状態で水槽に沈めた。

 どうにもおかしい、ということにあなたは気づくであろう。金魚が隠れ家の中に入ってくれないのである。せっかく用意したのにこれでは台無しだ。なぜだろう。考えてみればこれは当然のことである。今、金魚は「カメラの目」を通して水槽を見ている。しかし「カメラの目」では、伏せてある植木鉢の内部を見ることはできない。”バーチャルな”金魚は、植木鉢の内部に空間があることを知らないから、入っていくことができないのだ。

 ここにきて、さきに明記したことが利いてくる。現実の金魚が「金魚自身の視点」をもっているのに対して、ここで”バーチャルな”金魚が持っているのは「あなたの視点」である。”バーチャルな”金魚がよりリアルに振る舞うためには、金魚自身の視点が不可欠なのである。さらに、金魚が複数いたらどうか。それぞれの金魚が自然に振る舞うためには、それぞれの視点を持っていなければならないであろう。ここに、仮想世界の持つべき情報量は膨れ上がる。と、私は考える。

  • まとめ

 こんなに長々と文章を書いておいて、私が結局何を伝えたかったのかというと、それは「私が画像処理による空間把握をしない理由」である。前述したように、画像処理による現実空間の形状取得は、情報源をカメラ映像にしているため、そのカメラから見える範囲の情報しか取得できない。空間の部分的な形状を知ることしかできない。しかし、私は仮想的な物体やキャラクターが自然に振る舞うために、彼らの視点も取得したい。あるいは「彼らが見るであろう物」を知りたい、とも言い換えられる。それには、自分が考えたい一定の領域(例えばある一室)のすべての物体の位置情報を取得して、ようやく足りるように思われる。そうなってくると、カメラを一つ一つ敷設してカメラの死角を埋めるやり方はいささか冗長に思えてくる。

 加えて、これは前述しなかったが、画像処理では物体と物体の境目を見分けるのが困難である。我々は知らず知らずに「机」の上にある「本」を分離された、別々の物体としてとらえているが、視覚情報だけでコンピュータにそれをさせるのは困難である。人間の持つ「経験則」だとか「先入観」というものを、コンピュータは持ち合わせない。さらに、画像処理では物体の持つ諸特性を把握できない。これは当然のことであるし、画像処理畑でそれをできる必要はないだろう。単に「”私は”物体の持つ諸特性を知りたい」というだけの話である。私は仮想的な物体やキャラクターが「見るであろう物」に加えて「体験するであろうこと」までもを知りたいのである。

 そこで私が考えているのは、「現実の物体に、その物体に関するいくつかの情報を持つ固有のチップのようなものを内蔵させ、その情報を通信によってコンピュータに伝える」というやり方である。物体の情報としては、形状情報、ボーン、重さ、などに加えて「位置と姿勢」も持たせたいと考えている。(この、位置と姿勢の情報は、各物体が逐次、何かしらの方法——たとえばLocal Positioning System——によって、外部との相対関係を取得する必要がある。)

 このやり方の難点は、チップを持たない物体をコンピュータは認識できないという点である。この手法を限られた空間内以外でも適用しようと思うと、チップの普及が不可欠である。しかしながら、その点も私はうまくいくのではないかと考えている。幸いにして、現在産業界ではIoT(Internet of Things)のブームが来ている。このブームに乗っかって、うまく一般に普及させられるのではないか、と希望的観測をしてる。私の目標の一つは、「AR + IoT」といえるかもしれない。

 私は、仮想世界をよりリアルにするために、コンピュータは人間が知覚する以上の情報を持っている必要があると考える。空間的な情報や特性的な情報を持つのはもちろん、物理エンジンなどのシミュレーションによってある程度の未来(体験されるであろうこと)を知ることも必要になってくると考える。仮想世界を真に実現するためには、仮想世界が文字通りの”世界“である必要があるのだ。”Virtual” RealityをRealityにするとはそのような作業である。Virtualが”仮想”と訳されてしまったのは実に惜しいことである。

 

以上のように私は考えるのだが、皆さんはどうだろうか。

この記事を通して、私の持つバックグラウンド(知識、偏見などを含む)の一部を理解していただけたなら幸いである。