見出し画像

Web会議でアバター参加するための最強ツールを作ったよ!REALITY Advent Calendar #8

8日目の記事は漫喫が担当します。日本一メタバースなREALITYのアドベントカレンダーをよろしくお願いします!

記事の内容

Macで動くREALITYを作ってWeb会議用にカスタマイズしつつ、MediaPipe使ってハンドトラッキングも動くようにした。というお話ですが、技術的な記事を書くのが苦手なのでコラムっぽい内容になっております。↓がタイトルで煽ったツールになりますが、割と最強でMac単体でさくっとWeb会議にアバター参加できる「Mac版REALITY for Web会議」です。

3秒でアバター参加!!


昨今増え行くWeb会議の時間

いきなり見出しが脱線気味で申し訳ないですが、最近Googleカレンダーに会議の時間の集計が表示される機能が付いたのはご存知でしょうか?以下が僕の11月のミーティングの実施状況みたいです。

子供に「なにをそんなに話してるの?」と聞かれました

仮に会議=Web会議の時間だとして計算すると僕の場合だと年間720時間はWeb会議やってみるみたいです。やばいですね。

ところでみなさん、Web会議中ってビデオオンにしてますか??

会社によってはオンを強制させているところもあるみたいですが、REALITY社では特にルールがありません。そうなるとオフにする人がほとんどなんですよね。オフなのはけしからん!みたいなことは全く思わないのですが、純粋な興味として「なぜ人はビデオオンにしたがらないのか?」というのが気になって考えてみました。

「部屋を写したくない」「化粧するのがめんどくさい」「部屋着のまま仕事したい」「会議中に耳かきしたい」などいろんな理由があるとは思いますが、僕は「自分の顔を見たくない!」という仮説を提唱したいと思います。試しに全員がビデオオンにしてるWeb会議で自分がどこを見ているのか意識してみてください。おそらく、他の人の顔じゃなくて自分の顔を見ている時間が多いことに気づくはずです。人は興味あるものに視線が行く傾向があるので、他人の顔より自分の顔を見ちゃうんですよね(個人の意見です)。
そして、僕は自分の顔を見続けることはっきり言ってストレスです。美意識が高い人やおしゃれな人には絶対共感してもらえないと思いますが、共感してくれる人向けに記事書いているので気にしないぞ!


アバターでWeb会議のすゝめ

Web会議中にとっさに出てしまうあくび!画面上に映る間抜けな顔した自分!想像するだけでいやですよね?

でもアバターならカワイイからセーフ!!

Q. どっちの顔見てミーティングしたいですか?

ということで、REALITYのアバターを使ってWeb会議にでればカワイイ自分を見ながらミーティングできるぞーというわけなんですが、REALITYはiOS/Androidアプリでしか動かないため、スマホをPCにつないでOBS経由で映す方法(下の記事でやり方が詳しく解説されています)しかなく、これだとWeb会議するたびにセッティングするのがだるいという問題点があります。

なのでMacのスタンドアロンアプリとしてREALITYを動かせるようにしてWeb会議用アプリとしての機能を合宿前にいくつか作りました。
Macアプリなのでいつでもすぐに起動できますし、Web会議中にマイクをさっと握ったり、「よろしく」などのスタンプを出して場を和ませることもできます。REALITYのギフトはすべて使えるので、Web会議中にクマさんを抱っこしたり、唐突に決め立ちを繰り出すこともできます。マルチタスクで気になりがちな負荷についても、右下のFPSを下げるモードが超便利でずっとアプリ立ち上げっぱなしでも気になりません。

これが「Mac版REALITY for Web会議」だ!

↑の画面だとUIがゴテゴテついてますが、Web会議中のビデオにはアバターしか映らないようになっており、こちらの技術を使うことで、Unity上のアバターしか映らないカメラの映像をCamTwistにアプリ間通信して送っております。ただ、Macアプリだと肝心のフェイストラッキングが動かないので、フェイストラッキングを合宿中に使えるようにする頑張って作りました。

せっかくなのでMediaPipe使ってみた

ようやく合宿でやった内容に入りますw
MediaPipeとはGoogle社が提供するオープンソースの画像認識ライブラリです。このライブラリを使うことで以下のような情報がカメラ画像から検出できます。

旅館の部屋でコーディングしてたときの様子

これだけ見ると簡単にアバターに適用できそうな雰囲気ですよね。。。後述しますが、MediaPipeで取れるのは全て特徴点の座標で、これをアバターの姿勢に変換するにはそれなりの苦労がいります。というかそれを頑張ってやっているアプリがREALITYなわけで、冷静に考えてそれを2泊3日の合宿でやりきるの無理じゃね?と今なら思うのですが、せめて今のREALITYにないハンドトラッキング部分のつなぎ込みがなんとなくできると良いな、という風には合宿中に考えていました。






そして!ついに完成!!!







↓デモ動画がこちら↓






デデンッ!!





ビミョーーーだぁぁーーーー!!!!







ほんとはメタルポーズをしたかったんですけどね、、、精度が悪くてアロハポーズになりました。。。え、そういうことではない?
まぁこれはMediaPipeの精度が悪いのではなく、自分の実装が悪いですね。詳細については以降の技術パートで説明していきたいと思いますが、2泊3日の合宿の成果としてはこのぐらいが限界でした。


技術的なこと

Unity + Mediapipe + Macスタンドアロン + アバター操作という割と特殊なことやったのでかなり苦戦したんですが、技術ブログなので簡単に紹介しておきます。

1. UnityでMediaPipeを動かす

こちらのプラグインを使わせてもらいました。

既存のUnityプロジェクトにMediaPipeをざっくりと以下の手順を行いました。

  1. 上記のプラグインをExportしたUnityパッケージを既存プロジェクトにインポートする

  2. MediaPipeのビルド環境の準備

  3. 上のプラグインのREADMEに従ってMediaPipeをビルド
    (このときOpenCVを含めたビルドを行わないと、OpenCVをインストールしてないPCでは動かなくなる。下図参照)

  4. その成果物のPackageを既存プロジェクトのPackageにコピペ(下図参照)

2. MediaPipeの結果でアバターを動かす

アバターを動かすために使ったMediaPipeの機能はFaceMeshHandsです。
(Poseも一緒に使った方が良い気がしますが間に合わず)
MediaPipeから上手く値がとれると検出結果としてランドマークとなる座標が↓のように取得できます。

これらの座標をアバターに適用していくには以下のコードを参考にさせていただきました。MediaPipeの値を表情のBlendShap値や関節のtransformに変換する計算をしてくれるライブラリです。

非常に分かりやすいコードでめちゃくちゃ感謝しながら、このTypeScriptのコードをC#に移植作業に近いことをやった、というのが合宿中の実態ですw
すこしだけ解説するとここが手のランドマーク座標から指の関節のrotationを計算するコードです。以下のコードは薬指の第一関節の角度を計算している場所です。

hand[side + "RingProximal"] = { x: 0, y: 0, z: Vector.angleBetween3DCoords(lm[0], lm[13], lm[14]) };

lm[*]というのが手のランドマークの各特徴点にアクセスしているコードで、3点の特徴点から角度を計算している、的なコードになります。こんなノリでランドマーク座標からアバターの姿勢を決めていくわけですが、乗り越えるべき試練は主に以下の6項目あって、今回の合宿では半分も終わりませんでした。。。

なお体全体の姿勢を決めるのはIKのアセット使いました


ぶっちゃけハンドトラッキングどうなの

テーマ的に面白いので手と指に注力しましたが、やってみた感想として「ハンドトラッキングない方が良さそう」。最近Web会議をずっとアバターで出るようになって気づいたのですが、正確にリアルアバターをトラッキングする必要性よりなんとなくそれっぽく動いている方がよっぽど重要だなと。MediaPipeのハンドトラッキングは誤検出が多くて、このままだと機能としてオフにした方がマシそうです。配信アプリだと配信者の表情をより豊かに/より多くの情報を伝えるために精度が必要なんですが、Web会議はそうではなさそうです。配信アプリとしての要件とWeb会議の要件が違うというのも面白い発見でした。
…気を取り直して顔の部分だけ作っていこう。


終わりなき挑戦を楽しむ

まだ半分も実装終わってないですが、社内のWeb会議がアバターで溢れるように引き続き時間を見つけて実装を進めたいと思います。そしてゆくゆくは正式リリースして世界中のWeb会議をアバターで溢れさせたいという野望に向かって挑戦していきたいと思います。(※リリースの予定は一切ありません)

明日の記事は

合宿前日に大きめの障害を起こして「明日合宿行けません…」と顔面蒼白だったサーバーエンジニアのうすぎぬです。テーマは「機械学習 in REALITY」。お楽しみに!