🕶️

Nreal AirとA-Frameとfacemeshで疑似3dof

2022/08/11に公開

スマートグラスNreal Airを購入しました。

https://www.nreal.ai/air/

円安の影響で値上げしましたが、それでも値段のわりに画質がとてもキレイで発色もよいため気に入っています。
ですが難点として指定されたAndroid機種で同社の「Nebula」アプリを使わないと3dofの拡張現実機能(MR Space)が使用出来ません。
Nebulaを使わない場合は0dofとなり、常に目の前に映像が表示されます。
動画視聴などの場合はこれで問題ないのですが、やはりサングラス型のスマートグラスなので拡張現実を試してみたいです。
特にPCにつないだ場合、ミラーリングや拡張ディスプレイとしてデスクトップが見えるのはいいのですが、0dofに慣れないと酔いやすく、視線のみで画面の上下左右を確認する必要があるなど、使い勝手がよいものではありません。
なんとか既存技術で3dofが出来ないかと試行錯誤した結果、A-Frameとfacemeshでそれっぽいものが出来たので共有します。

先にサンプルを見たい方はこちら

必要な要素は以下になります。

  • Nreal Air
  • USB-CポートがあるPC or Mac (Nreal Airと接続するため)
  • Webカメラ (顔認識するため)
  • ブラウザ (Chromeなど)

私の環境は MacBook Pro(14インチ、2021) なのでこれを基準に書いています。

最近のMacBookはUSB-CポートがあるのでNreal Airを接続してミラーリングやサブディスプレイとして表示できますが、当然そのままだと0dofです。

Nreal Airから回転角度が取れないとしてもスマートグラスである以上は顔に掛けているため、顔の回転角度がわかれば疑似的に3dofを再現できそうです。

必要な技術は、

  • Webカメラから顔を認識して顔の向きを推定する
  • 3D空間を用意する
  • 3D空間で顔の回転角度に合わせて向きを変える

になります。

Webカメラから顔を認識して顔の向きを推定する

顔の認識にはtensorflowのfacemeshが使えそうです。
具体的には下記を参考にしました。
https://qiita.com/mbotsu/items/74b39160f519a1dd2f73

3D空間を用意する

A-Frameがそのまま使えそうでしたのでこれを使います。
https://aframe.io/

3D空間で顔の回転角度に合わせて向きを変える

facemeshから推定した顔の向きを3D空間上の回転角度に変えます。
顔の向きはyaw,pitch,rollとして数値が出せるので単純にラジアンを度に変換します。

let y_degree = pitch * ( 180 / Math.PI )

あとはこの角度をA-Frameのカメラに渡してやるだけです。

cameraWrapper.setAttribute("rotation", {
  x: x_degree,
  y: y_degree,
});

とりあえず以上を行うことで擬似3dofが実現出来ました。

サンプル

https://ansysait.github.io/nreal-air-a-frame-facemesh/

※カメラの起動にはブラウザの許可が必要です。
Nreal Airを接続し、Webカメラの前に顔が映るようにして、ブラウザの全画面モードで閲覧してください。

デスクトップ画面を浮かべたい

疑似3dofが出来ました。
でも3D空間上にあるのはただのオブジェクトです。
A-Frameでは3Dモデルも表示できるので、お気に入りのキャラクターを画面横に配置したりも出来ますね。

でもどうせならOculus Questの「Immersed」のようにデスクトップを空中に浮かせたいです。
https://immersed.com/

A-Frameはvideo再生に対応しているため、WebRTCの画面共有機能を使えば出来そうです。
https://zenn.dev/mima_ita/articles/c8d0b3f5e0e424

ただし画面共有の場合、すでに存在している画面しか共有できません。(当然ですが)
メインモニタを画面共有してもいいですが、目の前に座っているのに共有する必要はありません。
Nreal Airがサブディスプレイ扱いになりますが、こちらは全画面でA-Frameを表示しているので使えません。

そこでダミーのデスクトップを用意します。
ちょうどいい感じに今年4月に「BetterDummy」というアプリが安定版でリリースされました。
https://applech2.com/archives/20220422-betterdummy-v1-1-for-mac-stable-release.html

一見使い道がなさそうなアプリですが、今回の用途にはぴったりです。
BetterDummyでダミーのデスクトップを作成し、画面共有でA-Frameのvideoに再生することで、デスクトップを3D空間に浮かべる事ができました。

画面共有を使ったサンプルは下記で試すことができます。

https://ansysait.github.io/nreal-air-a-frame-facemesh/webrtc.html

画面下の「Start Capture」を押すと画面共有の設定画面が表示されます。

ソースは下記にあります。改変するなりご自由にお使いください。
https://github.com/ansysait/nreal-air-a-frame-facemesh

htmlファイル1枚だけでここまで出来るのはなかなかおもしろいですね。

雑感

とりあえず既存の技術を集めて作ってみました。
Reactも使ってないしTypeScriptでもないのでモダンな感じはしないですが、とりあえずこんなことが出来そうですよという意味を込めて公開しています。
まだまだ精度も低く使い勝手も悪いものですが、そのへんは頭のよい人たちによって改善されることを願います。

今回の手法だとWebカメラを使用して顔を認識する必要があるため、歩きながらの使用は出来ません。
Webカメラを部屋の四隅にでもぶら下げれば動けるようになるかもしれませんが。。

WebカメラがあればNreal Airじゃなくても動くので、他のスマートグラスにも流用できそうです。

スマートグラスは用途すらまだ模索段階だと思うので、とりあえず色々試してみるのがよいかと思っています。
デファクトスタンダードとまではいかなくとも、スマートグラスの明るい未来に貢献出来れば嬉しいです。

ちなみに

一応NrealからSDKが提供されているため、Nreal Air側からサングラスの回転角度を取得出来れば3dofを実現できそうですが、現在提供されているSDKはAndroid用なのでまだデスクトップアプリは作れないのかな?(SDK触っていないのでよく知りませんが)

mac版のNebulaが出るそうです。

記事を書いてる途中にこんな情報を見つけました。
https://twitter.com/mrfareplay/status/1556515345598451713

こちらを待ったほうが良さそう??

Discussion