ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
人をARに組み込む
ARKit 3では、実世界の人をARシーンに緊密に統合する革新的な機能を利用できます。Appでライブモーションキャプチャを使用して、バーチャルキャラクターをアニメーションさせたり、2Dおよび3Dシミュレーションに適用したりする方法についてご確認ください。また、バーチャルコンテンツが実世界の人の背後を通り過ぎるようにすることで、より臨場感あふれるAR体験を実現できる「ピープルオクルージョン」についても紹介します。
リソース
関連ビデオ
WWDC21
WWDC19
-
ダウンロード
(音楽)
こんにちは (拍手) ご来場ありがとう
本セッションでは AR体験を実現するARKitを紹介します
登壇者は私 エイドリアンと タンマイです
新発表した RealityKitフレームワークを使うと リアルな画像を作成できます AR開発向けにゼロから作られました
先日 ARKit 3のセッションでは ARKitに入った 多くの新機能を紹介しました 本日はそのうち2機能を説明します 私はPeople Occlusion機能 タンマイが Motion Capture機能の担当です
では始めます People Occlusionとは?
すでにARKitでは 仮想物体を現実の映像に合成できます でも この映像には違和感がありますね
本来なら レンダリングされた仮想物体より カメラに近い人が手前に見えるはずです
これを解決するのが People Occlusionです 仮想物体と人との間で 正確なオクルージョンを実現しました 構造を理解するため フレームを分解してみましょう
テーブルを挟んで 2人が立っている画像があります 仮想物体をテーブルに配置しましょう
既存のARKit 2で合成すると 物体がオーバーレイ表示されました オクルージョンが 正確に表現できていません 想定と違う結果です 何とか問題を解決したいですね カメラの近くにいる人の方が 仮想物体より手前にいるので 仮想物体を オクルージョンする必要があります
これは深度の順番の問題です 画像を分解して 理解を深めていきましょう
先ほどの画像を傾けました それぞれの物体について 深度面を見てみます 現実物体と仮想物体が混在していますね 2人が位置する深度面の間に 仮想物体が存在しています
仮想物体の情報は グラフィックスパイプラインの 深度バッファを利用します 現実物体に対しても同じ処理をして 深度を測る必要があります そのためバッファを2つ追加しました
ピクセルで人の位置を示す セグメンテーションバッファ それに対応する深度バッファには 位置の深度情報を持たせます
驚くべきことに この機能では A12チップを活用して これらのバッファを生成しました カメラ画像のみを使用し 機械学習で生成するのです
これら2つのバッファは ARFrameの新たな属性として 追加されました segmentationBufferと estimatedDepthDataです
People Occlusionに バッファを適用するには フレームレートを カメラに合わせる必要があります つまりカメラのフレームレートが 60fpsなら バッファを60fpsで 生成するようにしました
また解像度も カメラと合わせる必要があります しかしリアルタイムで調整する場合 ニューラルネットワークでは 小さな画像しか扱えません そのためニューラルネットワークの 出力を拡大すると 画像の詳細情報が欠けてしまうのです
この事象を補正するため 処理を追加しました
マット処理です segmentationBufferの情報を手掛かりに カメラ画像から欠けた詳細を探ります マット処理をすると 人を正しく抽出できるようになり estimatedDepthDataと合わせると 正確な深度が判明 深度の順番の問題が解決され 画像を再構成できます
多くの技術の融合ですが デベロッパが 簡単に扱えるようにしました この機能を使う方法は3つあります
1つは新フレームワーク RealityKitです すでにSceneKitをお使いなら ARSCNViewでPeople Occlusionを サポートしています 独自もしくは他社のレンダラを お使いなら People Occlusionを入れた ビルディングブロックが使えます Metalから ご利用ください では RealityKitから説明しましょう
新しくARアプリケーションを作るなら RealityKitを推奨します 新たなUI要素を持つARViewは リアルな物体を描写するAPIで 使い方も簡単です 現実と仮想物体の境界を 更に一体化しています
People Occlusionも入っています すでに新機能紹介のセッションでは People Occlusionを ARViewでデモしました 今回は要約して解説します コードをご覧ください
View Controllerに viewDidLoad関数を定義しました 最初にデバイスの機能を確認するため
ARWorldTrackingConfigurationを 使います そして新たな属性のframeSemanticsに personSegmentationWithDepthを 設定します デバイスでサポートされている場合は frameSemanticsを設定するだけです セッションが起動すると ARViewが自動で処理し People Occlusionが 使えるようになります
つまり設定を変更するだけです 新たな属性 frameSemanticsを使います 例で示したのは personSegmentationWithDepthですが 天気予報のCGなどでは personSegmentationも使えます
People Occlusionには ARViewを推奨します 強固なレンダラの統合があるので グラフィックスパイプライン全体で 人を認識可能です 更に透過オブジェクトを 扱うことが可能で 最適なパフォーマンスを実現しています ではPeople OcclusionとRealityKitで 実現できるAR体験を 映像でご覧ください
(音楽)
このSwiftStrikeは WWDCで見せているデモです まだ見ていない方は ぜひご覧ください それではSceneKitの場合は?
実現方法を説明しましょう
ARSCNViewを使えば RealityKitと ほぼ同様に People Occlusionを使えます frameSemanticsを設定することで ARSCNViewが機能を起動します SceneKitがRealityKitと違う点は ポストプロセッシングであることです つまりコードの書き方によって 透過オブジェクトが動きません
最後に独自のレンダラの場合でも People Occlusionを 使えるようにしました 他社のレンダラでも同様です
コンポジションを完全に制御しています
簡単に使えるAPIを提供しつつ 自由度も保つ形で 本機能を実装しています ここで少し復習しておきましょう セグメンテーションバッファでは ニューラルネットワークの 画像を補正します マット処理で 画像を詳細に復元するのです コンポジションを変更するため マット処理をするクラスを Metalで提供しました テクスチャとして パイプラインに組み込めます では例を見てみましょう
これがコンポジション関数です まずデバイスに機能を適用できるか 確認します その後generateMatteを呼び出します 引数は“frame”と “commandBuffer”です これでMetalのテクスチャを使えます 最後にGPUにスケジュールします
ARKitで呼び出すクラスは ARMatteGeneratorです commandBufferのARFrameを取得し MTLTextureを返します まだ続きますよ
segmentationBufferと estimatedDepthDataは低解像度でした それを単に拡大し マット処理した画像に重ねると 不適合が生じます マット処理後に アルファ値がなければ深度値を 深度値がなければ アルファ値を設定可能です
ここではマット処理したため アルファ値の修正はできません そこで深度バッファを修正します
先ほどの例に戻って見てみましょう この行を追記しました コンポジション変更に使うため マット処理を行います そしてgenerateDilatedDepth関数を 追記しました commandBufferのframeを取得し テクスチャを返します
APIを見ると マット処理の方法と似ています frameとcommandBufferを取り テクスチャを返します つまりマット処理で検出した アルファ値に対応する深度値が得られ コンポジションの実行で使えるのです
dilatedDepthとmatteの値が出たので 次はコンポジションです
フラグメントシェーダの GPU上で実行されます それでは例を挙げて説明しましょう
まずARで通常行うことをしましょう カメラ画像と レンダリングされたテクスチャ そしてレンダリングされた深度を サンプリングします
その後 通常のARの処理として アルファを用いて 仮想物体を現実の画像に重ねます People Occlusionのために 新たに行う処理は matteとdilatedDepthの サンプリングです dilatedDepthと renderedDepthの値を比較し dilatedDepthの方が小さければ 人がカメラに近いということです “mix(scene, camera, matte)”を 返します 仮想物体の方がカメラに近い場合は 通常の処理を行い 仮想物体を手前に出力します この処理により 独自のレンダラで People Occlusionを実現したのです
(拍手) この機能はNeural Engineと 機械学習を利用するため A12以降でサポートされます
また屋内での利用が最適です デモでは人が立っている状態でしたが この機能は自分の手足にも使えます 複数人がいる映像でも大丈夫です ではタンマイを呼ぶ前に これまでの復習をしましょう
People Occlusionで可能になるのは 仮想物体と人との 正確なオクルージョンです
新たにアプリケーションを作るなら RealityKitとARViewを推奨します 強固な統合があるからです SceneKitを使っている場合は ARSCNViewでサポートします 独自レンダラ用にAPIを提供しました ARMatteGeneratorです 独自のレンダラに 組み込むことができます ではタンマイを呼んで Motion Captureの説明を任せましょう (拍手) ありがとう エイドリアン こんにちは タンマイです これから我々が今年導入する 新技術をご紹介します Motion Captureです (拍手) Motion Captureとは― 人の動きをキャプチャするプロセスです 人がいますね 動きをキャプチャして その動きをする仮想キャラクターを 描きました キャラクターの動きと人の動きは 同期しています これをアプリケーションで 使えるようにしました では説明します ゴールはキャラクターが 人の動きをマネることですが まずは何をアニメートするのか 理解しましょう キャラクターに必要なのは? これは仮想キャラクターの例です 内部を見てみましょう
主要なコンポーネントは2つ メッシュと呼ばれる 外側のコーティングと 体の構造を決定づけるスケルトンです この2つを組み合わせると完成します スケルトンには重要な役割があり 動きに使う すべての手足が含まれています つまりスケルトンをアニメートして キャラクターを動かすのです 最初のステップは スケルトンに 人の動きをマネさせることです
こんな感じです スケルトンが動けば キャラクターも動きます
こうして仮想キャラクターが 人の動きと同期するのです
実現方法は?
スケルトンのアニメートには 機械学習の技術を使っていて 最初に人の姿勢を推定します そこから本格的で 忠実なスケルトンを構築
これをメッシュと組み合わせ キャラクターを作るのです ARKitがすべての インターフェイスとなります
では まとめます Motion CaptureはARKitの新機能です 自分のデバイスで人の動きを リアルタイムで追従できます RealityKitでシームレスに動き キャラクターのアニメーションを レンダリングできます 機械学習を行い AppleのNeural Engine上で実行されます 機能をサポートするのは A12以降のデバイスです さて この技術は何に使えて 何ができるのでしょうか?
まず仮想キャラクターで 人の動きを追えます AR上の自分のコピーです この機能は すぐに使えます それ以外にも 本機能の用途は多々あります 例えば 動きを検出する モデルを作るなど 拡張的な使い方もできます
これを使ったアプリケーションを作り ゴルフのスイングや構え 運動中の動きなども分析可能です
AR上に人のコピーが作れるので 仮想物体との インタラクションが可能です
どんな仮想物体でも対応します
画像や動画の分析にも 使うことができます 2Dのスケルトンも扱うことができるため 編集ツールの使用や セマンティック画像の理解に使えます
今 説明したことは リモートで実現できる可能性の すべてではありません その他にも いろいろできます
では Motion Captureの活用法を 説明しましょう ユースケースに応じて 3つの方法があります まずはRealityKitのMotion Captureです キャラクターをアニメートする時に この高レベルAPIが使えます 高度なユースケースにも対応し 動作の認識や 3Dオブジェクトとの インタラクションが可能 スケルトンの各要素を抽出する 低レベルAPIも使えます すべて利用可能です セマンティック画像の分析や 編集ツールなどに― 2Dのスケルトンが必要な場合も 問題ありません こちらも利用可能です
ではRealityKitのMotion Captureです
今年発表したRealityKitでは APIを提供しています 数行のコードで 人の動きを 模倣するキャラクターを追加できます
シンプルで使いやすいAPIが あるからです 例に基づく構造に従えば 独自キャラクターも追加できます つまりサンプルバンドルで 提供した構造に基づいていれば 任意のメッシュや キャラクターを使えるのです
人を追跡した情報は AnchorEntityで簡単に得られます これはシーンの基礎的要素です Motion Captureに必要な動きの変換も 自動的に収集します
詳しく見ましょう
ARViewで得られる Motion Captureの全要素は ARとRealityKitを組み合わせた 主なUI要素です ARBodyTrackingConfigurationにより 動作します これを有効化すると 人を含むアンカーの追加が始まり 全体がBodyTrackedEntityに カプセル化されます ではBodyTrackedEntityについて 説明します
これは1人の人間を表したもので スケルトンと位置情報が含まれます
動きはリアルタイムで追跡し フレームごとに更新 スケルトンを自動で リグ入りメッシュメッシュに結合し キャラクターを生成します
どれほど簡単なものか コードを見てみましょう たったの3ステップです まずキャラクターを読み込みます
追跡された人を 非同期で自動読み込みするには Entity.loadBodyTrackedAsync関数を 呼ぶだけです “.sinc”を使って エラーがあれば検知するか 正常であれば キャラクターを返すことができます このキャラクターは BodyTrackedEntityタイプです
サンプルコードバンドルに “robot.usdz”があります このファイルを使えば スケルトンが自動でメッシュに追加され キャラクターが表示されます
2つ目のステップは キャラクターを配置する位置の取得です
追跡している人の上に 配置するとしましょう “AnchorEntity(.body)”で 位置を得られます これは単なる例で 他の位置でも取得可能です 床でも机の上でもいいですよ 位置を含むアンカーを渡せばいいのです どの位置でも問題ありません
最後にキャラクターを配置すれば 完成です
キャラクターが動作します
ではこのロボットを 他のキャラクターに置き換える方法は どうでしょう?
先ほど“robot.usdz”を紹介しました これを見れば全体構造が分かります 同じ構造のモデルであれば そのまま利用可能です 提供されているスケルトンは 91のジョイントから成る 非常に忠実なものです ご参考までに― これが一覧です
多くありますが これらは 腕や脚にある通常のジョイントです
また命名規則が同じなら そのままRealityKitで使えます
人とキャラクターを読み込む 簡単な方法を紹介しました 次は低レベルAPIを見てみましょう ここではスケルトンの 各要素への接続を提供
非常に使いやすいAPIです
高度なユースケースを使えます つまり分析へのスケルトンデータ使用や モデルへの入力などです
またスケルトンは 新たなタイプのアンカーを含みます ARBodyAnchorです これは全データ構造への 入り口となっています これがデータ構造です
ARBodyAnchorを始点にし スケルトンの全要素を含みます
では構造を上から見ていきましょう
ARBodyAnchorは ジオメトリを持っています スケルトンはジオメトリそのもので これがイメージ図です 他のジオメトリと同様に ノードとエッジがあります 変換情報も含みます この変換情報は回転および平行移動での アンカーの位置です ではスケルトンに接続しましょう
このスケルトンは何でしょう? ノードで構成されたジオメトリで 緑色や黄色の点が ジョイントを示します エッジは白線で 骨にあたる部分です ジョイントでつながっていますね
すべてつながると ジオメトリを形成します これをARSkeletonと名付けました ARBodyAnchorを使えば接続可能です
ジオメトリ階層で最上位にある スケルトンのルートノードは ヒップジョイントです では構造定義を見てみましょう ここで言う定義はスケルトンの属性です コンポーネントを2つ含みます 全ジョイント名はスケルトンにあり ジョイント間を見ると 接続方法が分かります 両方の属性を見てみましょう
ジョイントの一部にラベルを貼りました 意味を示す名前になっていますね “左肩”“右肩” “左手”“右手”などです 人と似ています 緑色の点は我々が制御できるものです 人の動きから推定し位置が決まります 黄色の点は近くにある緑色の点を 親ノードとして追うだけです
右腕を拡大して見てみます ジョイントは3つ 右手 右肘 右肩です この3つには親子関係があります 手は 肘の子ノードで 肘は肩の子ノードです スケルトン全体が このような階層構造になっています
ジョイント名と接続方法は分かりました 位置情報の取得は? ジョイントの位置を知る方法は 2つあります 1つ目は親と比べる方法です 右手の位置を知るには 肘と比べます localTransform関数を使いましょう 引数には“.rightHand”を設定します
ルートのヒップジョイントから 変換したければ modelTransform関数に 引数で“.rightHand”を設定します
全ジョイントに個別接続するのではなく 全ジョイントのリストが 必要な場合は こうします localTransformsと modelTransformsを使うのです 全ジョイントが載ったリストを 取得することができます 親ノードに関するリストの場合は localTransformsを使い ルートに関するリストは modelTransformsです
スケルトンの構造が分かりました ではコードで要素の使い方を見ましょう
まずは全アンカーのループ処理です bodyAnchorを探します 存在する場合は 位置情報を知りたいでしょう ここで変換属性を使います
ここではヒップがルートなので “bodyAnchor.transform”で ヒップジョイントの位置が分かります アンカーの変換が完了したら “.skeleton”を使って ジオメトリに接続します
その後は全ジョイントの情報が必要です ジョイントの位置情報リストを得るには スケルトンの属性 jointModelTransformsを使います 次にこのリストに対して ループ処理を行うと 全ジョイントの変換に接続可能です 全ジョイントをループ処理し 各parentIndexに接続します 使うのは “.definition.parentIndices”です そして親ノードがルートではないことを 確認してください ルートでなければ 親ノードの位置情報に接続します jointTransformsを使います parentIndexでは インデックスの作成です これだけで 階層全体の親子情報が得られます つまりスケルトンの階層全体が 取得できたのです
これを自由に使えます ではこのコードを実行し スケルトンを描いてみましょう
こうなりました 階層全体を調べただけです すべての親子関係を調べ スケルトンを描きました 自動的に人の動きをマネています これは様々な機能の土台になります スケルトンの階層全体が分かると 他にも応用が利くのです 想像力を働かせ 自由に活用してみてください
これまで3Dオブジェクトについて 説明してきました 2Dのスケルトンを 使いたい場合もあるでしょう そのためのAPIも用意しました これを使うと2D空間の全要素に 密に接続できます
また全ジョイントを 正規化された画像座標として提供 非常に使いやすいAPIにしました
また画像分析や画像と動画の 編集ツールの構築にも使えます
この構造にはARBody2Dを介して 接続することが可能です これが可視化された ARBody2Dオブジェクトです スケルトン構造全体が含まれています
これが構造の全体像です 最上位にオブジェクトがあり 3Dと同様にオブジェクトの下に 全要素が存在します ではこの構造と要素を見ていきましょう
最上位はARBody2Dです
接続方法は2とおりあります すでに2D空間で作業しているなら デフォルトでは ARFrameのdetectedBodyが使えます 人はARBody2Dのインスタンスです
すでに3D空間で3Dスケルトンを 使っている場合を考えましょう その空間で2Dスケルトンを 使う必要がある場合は 直接つなぐ方法があります ARBodyAnchorのreferenceBodyです これでARBody2Dが得られます
skeleton属性を使えば スケルトンを抽出可能です これが可視化したものです このスケルトンは 正規化された画像空間にあります 左上が(0, 0)で右下が(1, 1)の 画像グリッド上では 図内の座標はX座標とY座標共に 0から1の範囲を取ります
緑色の点はランドマークです ジョイントとは呼びません 画像上のピクセル位置なので ランドマークと呼んでください
3Dと同様に定義オブジェクトがあり スケルトンのランドマーク名と 接続方法が定義されています
このスケルトンには 16のランドマークがあり 意味のある名前がつけられています “左肩”“右肩” “左手”“右手”などです ルートは3D同様に ヒップに位置しています
右腕に注目してみましょう 右手は右肘の子ノードで 右肘は右肩の子ノードですね これも3Dの時に見た親子関係と 非常に似ています 階層構造も同様です
今までの説明を踏まえて 構造をコードで見てみましょう まずARBody2Dを呼び出します
“frame.detectedBody”と書くだけです ARBody2Dを得ると スケルトン構造全体に接続できます “person.skelton”でジオメトリを抽出 personはARBody2Dオブジェクトです スケルトンの定義は ランドマークの名前と どのように接続するかという情報で 構成されています 定義属性にある情報です
次にランドマークの位置を 知る必要があります ここでjointLandmarksを用いると すべての緑色の点が含まれる 位置リストが得られます この情報は2Dであることに 注意しましょう 正規化されたピクセル座標です 次に全ランドマークをループ処理します 各ランドマークの親ノードに “definition.parentIndices”で 接続します ルートは階層の最上位にあるため 親はルートになりません ルートではない場合 jointLandmarksの配列から 位置情報を取り出します このようにスケルトンの階層内で すべての親子ノードの変換が行われます これを自由に使うことで 自分のアイデアを実現できます
では まとめましょう
ARの新機能 Motion Captureについて 説明しました
リアルタイムで人の動きに追従できます
自由に使えるスケルトンとして 3Dと2Dの両方を提供しています 人の動きとの インターフェイスとなります
すぐに使えるキャラクターの アニメーションは RealityKitでシームレスに実行できます
キャラクターを即座にアニメートする RealityKitのAPIを提供 もちろん独自のキャラクターも使えます 提供した例と 同じ構造であることが前提です
更に高度なユースケース向けに ARKitのAPIを提供しています 認知タスクや分析タスクなどです
これで説明を終わります 2つの新機能を紹介しました People OcclusionとMotion Captureです これらの機能を使うため APIを提供しています
更なる情報は Webサイトをご覧ください サンプルコードもありますよ 質問がある場合は 明日のラボでご回答します
(拍手) ありがとう (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。