ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Create MLによる手のポーズや動作の識別
Create MLを使えば、人間の手の表現力をAppで理解することがこれまで以上に簡単になります。Create ML Appとフレームワークを使って、Visionによる手のポーズ検出のサポートをベースに、カスタムの手のポーズと手の動作の識別モデルをトレーニングする方法を紹介します。データの収集、モデルの学習、そしてVision、Camera、ARKitとのインテグレーションがいかに簡単にできるかを確認し、楽しくて面白いApp体験を創り出しましょう。 Create MLの詳細やモデルのトレーニングに関するコンセプトについては、WWDC20の「Create MLを使用したアクションクラシファイアの構築」をご確認ください。また、「Create MLフレームワークを使ったダイナミックなiOS Appの構築」では、App内からデバイス上でモデルをオンザフライ方式でトレーニングする方法を紹介していますので、ぜひご確認ください。
リソース
関連ビデオ
WWDC23
WWDC22
WWDC21
WWDC20
-
ダウンロード
♪ ♪ こんにちは 「Create MLによる手のポーズや動作の識別」 講座へようこそ 僕はワートマン•ネイサン 今日は僕の同僚である ウェイナート•ブリタニーと パーツィアレ•ジェピーにも 参加してもらいます 今日のテーマですが 手の動きをどのように分類 するかについてお話しします でもこれを話す前に まずは手そのものについて お話ししましょう 手には20以上の骨や関節 筋肉があり 工学的にも驚くべき存在です この複雑さにもかかわらず 手は 乳幼児が周りの世界に 触れるための 最初に使う 道具の一つなのです 赤ん坊は 言葉を発する前に 単純な手の動きで コミュニケーションの 基礎を学習します 喋れるようになっても 手は コミュニケーションで 使われ続け 強調や表現を付け加えるよう シフトしていきます この1年 人と人の距離を 縮めるために 手はこれまで以上に 重要になりました 2020年 Visionフレームワークで ハンドポーズ検出が導入され これにより開発者は フレーム内の手と 手に存在する21個の 関節のそれぞれを 識別することができます これは 手があるかどうか またはフレーム内のどこに 手があるかを識別するのには すばらしいツールですが 手が何をしているかを 分類するのは 困難です 手の表現力というのは 無限大ですが 今回は 片手の 短く動きのないポーズ 例えば 止まれ 静かに ピース そして片手の短いアクション バックして 向こうへ行け おいで などを紹介します 「ポーズ」と「アクション」 という言葉を使いましたが これらを より具体的に 定義してみましょう 1つ目はポーズ 静止していても 意味が分かります 例えばこの2つは 静止していますが 被写体の意図が 明確に表現されています ポーズは静止画像のような ものだと思ってください そしてもう1つは アクションです これは意味を十分に表現する ために動きが必要です 例えばこの画像2つ これだと意味が不明確ですね 1枚のフレームを見るだけでは 不十分なのです しかし動画や ライブフォトのように 一定時間内にフレームを 連続させることで アクションの意味が 明確になります 優しげな「こんにちは」と 「こっちに来て」ですね ここをクリアにしたところで ではいよいよ 今年のCreate MLの 新テンプレートである ハンドポーズ分類器と ハンドアクション分類器を 紹介したいと思います これらのテンプレートは Create ML appまたは Create MLフレームワークを使った 手のポーズ及びアクションの モデルトレーニングを 可能にします これらのモデルは macOS Big Sur以降や iOS及びiPadOS14以降に 対応しています
また Create MLフレームワークを使い iOS機器上で モデルをトレーニングする 新機能を今年追加しました これについては以下のセッションで 詳しく説明されています 「Create MLフレームワークを使った ダイナミックなiOS Appの構築」 まず ハンドポーズ分類器に ついてですが これを使うと Visionフレームワークで検出した 手の関節位置を分類して どのポーズかを推論する 機械学習モデルを 簡単に学習させる ことができます モデル学習の担当者は あなたなので Appがどのポーズを 分類すれば最適なのかを 必要に応じて 定義してください 学習したモデルがどのように 動作するか見てみましょう 単純な試作品のApp から始め 簡単に ハンドポーズ分類モデルを 組み込むことができました このAppでは 手のポーズを分類し 対応する絵文字を表示し 分類されたポーズの信頼度を パーセンテージで表示 できるようになりました 手のポーズを「1」や 「2」と分類します しかし 認識していない動きや ポーズはすべて 背景の一部として分類されて いるのが 分かりますね 手のひらを見せるポーズも こうなってしまうので ここは改善が必要ですね これを同僚のブリタニーに渡して ハンドポーズ分類モデルを Appに取り込む方法を 見てみましょう ですがその前に 手のひらの ポーズを認識させましょう すごく簡単なのですが でもまず モデルを どのようにトレーニングする のかを話す必要があります 他のCreate ML プロジェクトと同様 ハンドポーズ分類機能を あなたのAppに 取り込むのは とても簡単です 方法には3ステップあって トレーニングデータの 収集と分類 モデルのトレーニング そのモデルをあなたのApp に取り込む の3つです ではまずトレーニングデータ の収集について話しましょう ハンドポーズ分類をするため には画像が必要です ポーズは静止していても 十分に表現できるものでしたね これらの画像は そのポーズの名前のフォルダに 格納します ここに2つのポーズがあって これらを 「1」「2」または「背景」 に分類したいと思います
「背景」はAppが正確に 識別しなくてもいいポーズのための 「その他」のカテゴリーです 「1」や「2」以外の 様々な手の動きや位置が これに含まれます 「背景」をしっかりと定義 することで ユーザーが 重要なポーズをしていない ことをAppが把握できます この分類を構成する画像には 2種類あります まず Appに分類させたい 重要なポーズではない 手のポーズが ランダムに並んでいます これらのポーズには 多様な肌色や年齢 性別 照明条件が 含まれている必要があります 次にAppに分類させたい 表現によく似た 位置を含むポーズの セットがあります これは Appが分類したい ポーズを表すために 手を動かしている時に 実際は様々な位置を経て 移行するため起こるものです 手のひらを見せるポーズを するために手をあげる時 僕の手が様々な位置を経て 移行しているのが分かります これらは手のひらのポーズに 似てはいますが僕のAppでは 手のひらのポーズとして 分類してほしくはありません これと同じことが手を 下げる時にも起こります これは手のひらのポーズに 限ったことではなく このようなタイプの 移行時のポーズは 「2」のポーズをするために 腕を上げたり 下げたりする時にも 起こります これら移行時のポーズは全て その他ランダムなポーズと一緒に 「背景」に 追加しておく必要があります この組み合わせにより Appが分類すべきポーズと それ以外の背景のポーズを モデルがきちんと 区別できるようになります
トレーニングデータを収集 分類したら Create MLの Appを使ってモデルの トレーニングを 実際にやってみましょう まず既存のCreate ML プロジェクトから始めます 以前のデモでモデルの トレーニングをやりましたが トレーニング結果は 上々でしたので このモデルにはかなりの 性能が期待できると思います 幸運にも Create ML appでは モデルをAppに取り込む前に プレビューが可能です プレビューのタブのところを 見ると 今回のリリースで ハンドポーズ分類器用に ライブプレビュー機能が 追加されたのが分かります ライブプレビュー機能は FaceTimeのカメラを利用し リアルタイムで推論を 表示します プレビュー機能を使えば このモデルが「1」と 「2」のポーズを正しく分類 できるかを検証できます それから 先ほどの手のひらのポーズも 正確に分類して 欲しいのですが 現在は「背景」 の一部として 分類されています このモデルをトレーニング していたデータソースには 「手のひら」という分類は 含まれていません 「1」「2」「背景」 の分類だけですね では今から 「手のひら」にも対応する 新しいモデルを トレーニングしてみましょう まず これ用の新しい モデルソースを作成します
このトレーニングに使いたい 「手のひら」の分類を含む データセットがあります このデータセットを選びます
この新しいデータソースを 見てみると 以前のデータセットにあった 分類に加えて 「手のひら」の分類も 含まれています ではモデルソースに戻って トレーニングデータを拡張し モデルの堅牢性を高めるため いくつかの追加を しておきましょう
以上です トレーニング 開始ボタンをクリックします
トレーニングが始める前に Create MLでは特徴の抽出 のみでなく 事前に画像の 処理をする必要があります Create MLに反復学習を 80回するよう指示しました これは良いスタートですが データセットに応じて この数字を 微調整する必要があります この処理には 時間がかかります でも大丈夫 トレーニング したのものを用意したので そちらをお見せします ライブプレビューを見ると 新しくトレーニングした モデルでは「手のひら」が 正しく識別されています 念のため「1」と「2」が 同様に識別されるかも 確認してみましょう
簡単だったでしょう? ではこのモデルを私の同僚 ブリタニーに送って あとは彼女がAppへの 取り込みについて説明します ネイサン モデルありがとう こんにちは 私は ウェイナート•ブリタニー Visionフレームワークチーム のメンバーです ハンドポーズ分類器のことを 初めて知った時 手を使った 特殊効果を作れると すぐに思いました 手のポーズを分類する Core MLと 手を検出して 追跡するVisionは 一緒に使うのに ぴったりの技術です ヒーローみたいな特殊能力を 使ってみたくないですか? それを実現する デモの パイプライン第一稿を すでに作成してあります それでは見ていきましょう まずフレームのストリームを 提供するカメラを用意し 各フレームを Visionリクエストに使用して フレーム内の手の位置と キーポイントを検出します DetectHumanHandPoseRequest という リクエストを使用します フレーム内で見つかった 手のそれぞれに対し HumanHandPoseObservation が適用されます Core MLの ハンドポーズ分類モデルに 送るデータは MLMultiArrayと HumanHandPoseObservation のプロパティである keypointsMultiArrayです ハンドポーズ分類器は トップに推定された 手のアクションラベルと その信頼度スコアを 送ってくれるので これを使って アクションを 決定することができます さて Appの詳細な 内容を確認したところで コードを見てみましょう まず Visionを使って フレーム内の手を検出する 方法を見てみましょう これをするために VNDetectHumanHandPoseRequest のインスタンスが1つ必要で 手を1つだけ検出したいので これをmaximumHandCount として設定します
maximumHandCountを設定し フレーム内に 指定数以上の手がある場合 アルゴリズムは代わりに フレーム内で最も目立つ 中心的な手を検出します maximumHandCount のデフォルト値は2です ここでリビジョンを設定して おくと 後でリクエストの 更新があっても驚かずに 済むのでおすすめです しかし リンク先のSDKで サポートされている 最新のアルゴリズムを 常に選択したい場合は これを設定する必要は ありません 今回はARKitのARSessionで 取得したフレームを使って 検出を行いますが これはカメラフィードからフレームを 取得する方法の一つです 好きな方法を 使ってくださいね AVCaptureOutputも 有効な選択肢です 受け取ったすべての フレームに対して VNImageRequestHandlerを 作成する必要があり これは 指定された画像に関する 全てのリクエストを処理します 手のポーズリクエストの リザルトプロパティには 先ほどリクエストで 指定したように 手の数最大1までの VNHumanHandPoseObservations が入っています
リクエストで手のポーズが 検出されなかった場合は 現在表示されている エフェクトを 消去した方が いいかもしれません それ以外の場合 handObsevationが1つです
次にCore MLモデルを使って 手のポーズを 分類したいと思います エフェクトのレンダリングに 影響を与えたくないので 1フレームごとの 予測はしないでおきましょう 間隔を空けて予測を行うことで よりスムーズな ユーザー体験を提供できます 予測を行いたい場合は まずMLMultiArrayを ハンドポーズCore MLモデルに渡し 戻された1つの予測から トップのラベルと 信頼度を取得します ラベルが高い信頼度で 予測された場合にのみ 表示されるエフェクトの変更を トリガーしたいと思います これは エフェクトのオンと オフの切り替えが早すぎると 動作がギクシャクするのを 防ぐためにも重要です ここでは「背景」分類が 信頼性のしきい値を 非常に高く保つことを 可能にしてくれています
「1」と確信を持って予測された時 effectNodeをレンダリングするよう 設定します 「1」が確信を持って 予測されなかった場合 手の動きに合わせるために 画面のエフェクトを止めます ではこれを テストしてみましょう 手で「1」のポーズをすると ビーム光線が1本 出てくるはずです かっこいいでしょ 私が「1」のポーズをした事を モデルが検知して エフェクトを起動しました でもこのビームが指を追って きたらもっとカッコいいかも 指の特定の位置に レンダリングされると なお良いですね コードに戻って 変えてみましょう ここで必要なのは 手の キーポイントの位置を グラフィックアセットに 与えること つまり ビューを使って正規化された キーポイントを カメラのビュー空間に 変換するということです また 信頼度スコアを見て どのキーポイントを保存するかを 選択することも 検討してみてください ここでは 人差し指の 先っぽだけを対象とします Visionは正規化された 座標を使用しているので キーポイントを 座標空間に変換する 必要があります また Visionの原点は 画像の左下にありますので それを意識して 変換を行ってください 最後にインデックスの位置を 保存します キーポイントが見つからない場合は デフォルトでnilになります エフェクトの レンダリングをするコードと それを指に合わせて 調整する方法を 見てみましょう グラフィカル オブジェクトを 配置する 位置を知るために setLocationForEffectsは 毎フレーム 非同期に呼び出されます デフォルトとして ビューの中心に エフェクトが出るように 設定します これを先ほどの CGPoint の indexFingerTipLocation と 入れ替えることで 意図した効果を得ることができます
素晴らしいわ! これは良い感じですね もう一歩踏み込んで みましょう 特殊能力にまつわる ストーリーを より面白く 表現するために ハンドポーズ分類器を もう少し活用すると 良いと思います この場合 「2」「手のひら」の 分類を選択します この2つが検出された時に アクションを起こすように すでにAppを 拡張しています ここでは 「1」のポーズで さっき見たように ビーム光線が人差し指の 先端から現れるように 中央に設定しています 「2」のポーズでは 中指と 人差し指の先端から 2本のビーム光線が 出ています そして最後は「手のひら」 のポーズでビーム光線が 引き起こされ 中指の下にある キーポイントと 手首のキーポイントの間に 固定されています
さて ネイサンと私が今日 紹介したもの全ては あなたのハンドポーズ 分類モデルを完全に 統合するためのステップを 網羅しています Visionには もうひとつ 便利な新機能があります そこで このAppの機能を トリガーし コントロール するのに役立つ可能性のある APIをご紹介します Visionは VNHumanHandPoseObservation で 左手と右手を区別することができる 新しいプロパティ chiralityを導入します これは VNHumanHandPoseObservation が どちらの手である可能性が高いか を示すEnumで 左手 右手 不明 の 3つの値のうちの 1つになります 最初の2つの値の意味は 想像できると思いますが 不明 の値は 古いバージョンの HumanHandPoseObservation が デシリアライズされ そのプロパティが 一度も設定されていない 場合にのみ表示されます ネイサンも言っていましたが WWDC 2020の講座 「Visionによる人物、顔、ポーズの検出」 で Visionを使ったポーズ検出について より詳しく知ることができます 補足ですが フレーム内で検出された 各手に対して 基礎となる アルゴリズムは それぞれの手のchiralityを 個別に予測しようとします つまり 1つの手の予測は 他の手の予測に 影響しないということです chiralityを使ったコードが どんなものかを お見せしましょう VNDetectHumanHandPoseRequest の作成と実行のための セットアップについては すでに説明しました リクエストを実行した後 オブザベーションは Enumプロパティchirality を持ち それを使って Visionによる手のポーズの オブザベーションに対して アクションを起こしたり ソートしたりできます
これまでは ハンドポーズ分類器の 使い方を説明してきましたが ネイサンも言っていたように ハンドアクション分類器も 今年の新技術です ここからはジェピーに バトンタッチします ありがとうブリタニー こんにちは 僕の名前は パーツィアレ•ジェピーです Create MLチームの 機械学習エンジニアです ハンドポーズ分類器に加えて 今年 Create MLは ハンドアクション分類を 行うための新しい テンプレートを導入しました これをあなたのApp内で どう使うのかを説明します そのため 今回は ブリタニーの特殊能力デモに ハンドアクションを加え ハンドポーズと ハンドアクションの 重要な違いを紹介します
ハンドアクションと ボディアクションは 似たようなタスクなので 詳しい情報や比較のために WWDC 2020の講座 「Build an Action Classifier with Create ML」 を参照ください でも今はハンドアクションと は何かを説明させてください
ハンドアクションは 手の動きの中で MLモデルが解析する 必要のある 一連の手のポーズで 構成されています 1つのシーケンス内の ポーズの数は 最初から最後までの手の動き 全体を捉えるのに 十分な数である 必要があります
手の動きを見るために 動画を使いますよね ネイサンが説明したように ハンドアクション分類機能の トレーニングは ハンドポーズ分類機能のものと 同じですが いくつかの小さな 違いがあります
静止画は手のポーズを 表していますが 動画は手の動きをとらえ これを表すのに使われます ハンドアクション分類機能を トレーニングするには それぞれが手のアクションを 表現する短い動画を 使うことになります これらの動画は フォルダに格納し フォルダ名はそれぞれアクション分類 を表しています
そして分類機能に認識 させたいアクションとは 異なるアクションの 動画を含む 「背景」分類を 含めるようにしてください
別の表現として すべての サンプル動画ファイルを 1つのフォルダに まとめることもできます
その後CSVまたは JSON形式の アノテーションファイルを 追加します
アノテーションファイルの 各エントリは 動画ファイルの名前 関連する分類 手のアクションの開始時間と 終了時間を表しています
また この時「背景」分類の ものも含めましょう
これは大事なことなのですが モデルのトレーニングには 長さが大体同じ動画を 使うようにしましょう 実際 トレーニングの パラメータとして アクションの継続時間を指定 すると Create MLは 指定された値に応じて 連続したフレームを ランダムに サンプリングします 動画のフレームレートや トレーニングの反復回数を 指定することもできます 加えて このAppでは モデルの一般化を促進し その精度を高めるための 様々なタイプの データ補強を 提供しています 特に Time Interpolateと Frame Dropは ハンドアクション分類に追加 された2つの拡張機能で より実使用に近い映像 バリエーションを提供します
今回はデモ用に すでに ハンドアクション分類機能を トレーニングしたものを 見てみましょう 僕はスーパーヒーローなので 何かエネルギー源が必要です
僕の場合はこれ ここでは手のポーズを 使うことで エネルギー源を 可視化しています ではこれから僕の特殊能力を 使ってみましょう
この場合 僕は手の アクションを使っています すごいですね
そして今は ハンドポーズ分類機能と ハンドアクション分類機能が 並行して実行されています Visionの新機能である chiralityを利用して 手のポーズは左手で 手のアクションは右手で 行っています
素晴らしい このようなことが可能なのは Create MLが最適化を施し すべてのモデルに トレーニング時間を設けて Apple Neural Engineの力を 余すところなく 発揮させているからなのです
では現実世界に戻り どうやってCreate ML ハンドアクション分類機能を 僕のデモに組み込んだのかを 説明していきましょう
モデルのインプットを まずは見てみましょう ハンドアクション分類機能を Appに組み込む際には モデルに 予想される手の ポーズの数を 適切に提供する 必要があります 僕のモデルは Xcode プレビューで確認できるよう 45 x 3 x 21のサイズの MultiArrayを 想定しています ここでいう45は このアクションを認識するために 分類機能が分析する必要の あるポーズの数です 21はVisionフレームワーク によって与えられた 各手の関節の数です 最後に 3は各関節の xとy座標と信頼値です 45という数字はどこから 来ているのでしょうか? これは予測ウィンドウの サイズで トレーニング時に使用した 動画の長さと フレームレートに依存します
僕の場合は 30fps 1.5秒の動画でモデルを トレーニングさせる ことにしました これはモデルが1つの手の 動作につき45の 動画フレームでトレーニング され 推論時にモデルは 同じ数の手のポーズを期待 していることになります 推論時に辿り着く手の ポーズの頻度に関しては さらに考慮する必要があります 推論時にモデルに提示される 手のポーズの割合が モデルのトレーニングに 使用されたポーズの割合と 一致することが 非常に重要です 僕のデモではARKitを 使用しました ARKitは60fpsの フレームを提供しており 僕の分類機能は30fpsの動画 で学習していたので 各秒ごとに辿り着く ポーズの数を 半分にしなければ なりませんでした もしこうしなければ 分類機能は間違った 予測をする可能性があります
それではこれの実装方法を 紹介するために ソースコードを 見てみましょう まず カウンターを使って Visionから届くポーズの レートを60fpsから 30fpsに落とし モデルが期待する フレームレートに合わせて 正常に動作する ようにしています
これでシーン内の 各手の関節と chiralityを含む配列を 取得します 次に 私のデモでは右手を 使ってハンドアクションで 一部のエフェクトを 作動させているので 左手のキーポイントを 捨てます
さぁ あとは分類機能のために 手のポーズを蓄積します そのために FIFOキューを使い 45個の手のポーズを蓄積し キューには常に 最後の45個のポーズが 含まれるようにしています はじめキューは空です 新しい手のポーズが届くと キューに追加するという このステップをキューが満杯 になるまで繰り返します キューが満杯になると コンテンツ全体を 読み始めることができます Visionから新しい手の ポーズを受け取るたびに そのキューを 読むことができます ただ覚えておいて欲しいのが 僕は毎秒30フレームを 処理しているということです また ケースによっては これはリソースの 無駄遣いになりかねません
そこで フレーム数を 定義した後 キューを読むために別の カウンターを使用しています
キューのサンプリング レートは Appの 応答性と 取得したい 1秒あたりの予測数との間で トレードオフの関係に あるものとして 選択する必要があります
この時点で MLMultiArrayで 整理された45個の 手のポーズのシーケンス全体 を読み込んで 分類機能に入力し 手のアクションを予測します
そして 予測ラベルと信頼度の値を 抽出します 最後に 信頼度の値が 定義したしきい値よりも 大きければ パーティクルエフェクトを シーンに追加します そのため Create ML ハンドアクション分類機能を Appに組み込む際には モデルが想定している フレームレートで手の ポーズのシークエンスを 入力するように してください 分類機能のトレーニングに 使われた動画と 同じフレームレートに 合わせるようにしましょう 先入れ先出しの キューを使って モデル予測に対する 手のポーズを集めます 適切なフレームレートで キューを読みましょう Create MLで学習した 手のアクションモデルで どんな素晴らしい Appが 作られるのか楽しみです それでは最後の考察と おさらいを ネイサンにお願いします ありがとうジェピー ブリタニーもジェピーも 本当によく頑張ってくれたね 試すのが楽しみだよ でも 手に負えなくなる前に ユーザーに優れた体験を 提供するために 留意すべきことが いくつお話ししましょう 手とカメラの距離を 意識するようにしましょう ベストな結果を得るためには その距離を11フィート 3.5メートル以下に保つ 必要があります また 明るすぎや暗すぎなど 極端な照明は 避けるようにしましょう 分厚い手袋や大きすぎる手袋 カラフルな手袋はなどは 手のポーズを正確に検出する ことが難しく 分類のクオリティに影響を 与える可能性があります 他の機械学習のタスクと同様 トレーニングデータの 質と量が重要です この講座でお見せした ハンドポーズ分類機能には 1つの分類につき 500枚の画像を使いました ハンドアクション分類機能 には1つの分類につき 動画を100本使用しましたが これは各ケースによります 最も重要なのは モデルがApp内で 遭遇するであろうと予想 される変動を捉えるのに 十分なトレーニング データを集めることです ではおさらいを していきましょう 今日学んだことは? 2021年からは 人の手の表現を解釈する Appが作れるように なるということ 2種類の手の表現 ポーズとアクションの 違いについても 話し合いました Create ML appでモデルを トレーニングするために 「背景」分類などの トレーニングデータを 用意する方法に ついても説明しました トレーニング済モデルの Appへの組み込み方も見ました そして最後に 1つのAppに複数の モデルを組み込むこと chiralityを使って 右手左手を識別することに ついて話しました もちろん 今日のデモは ほんの一部です Visionフレームワークは 手の存在やポーズ chiralityを検出するための 強力な技術です Create MLは手のポーズや アクションを楽しく簡単に トレーニングし 分類することができます これらを一緒に使うことで 人類の最も強力で 表現力のあるツールの1つに 関する深い洞察が得られます 皆さんの今後の活躍を 楽しみにしています それでは [アップテンポな音楽]
-
-
9:31 - Detecting hands in a frame
func session(_ session: ARSession, didUpdate frame: ARFrame) { let pixelBuffer = frame.capturedImage let handPoseRequest = VNDetectHumanHandPoseRequest() handPoseRequest.maximumHandCount = 1 handPoseRequest.revision = VNDetectHumanHandPoseRequestRevision1 let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]) do { try handler.perform([humanBodyPoseRequest]) } catch { assertionFailure("Human Pose Request failed: \(error)") } guard let handPoses = request.results, !handPoses.isEmpty else { // No effects to draw, so clear out current graphics return } let handObservation = handPoses.first
-
11:03 - Predicting hand pose
if frameCounter % handPosePredictionInterval == 0 { guard let keypointsMultiArray = try? handObservation.keypointsMultiArray() else { fatalError() } let handPosePrediction = try model.prediction(poses: keypointsMultiArray) let confidence = handPosePrediction.labelProbabilities[handPosePrediction.label]! if confidence > 0.9 { renderHandPoseEffect(name: handPosePrediction.label) } } func renderHandPoseEffect(name: String) { switch name { case "One": if effectNode == nil { effectNode = addParticleNode(for: .one) } default: removeAllParticleNode() } }
-
12:25 - Getting tip of index finger to use as anchor
let landmarkConfidenceThreshold: Float = 0.2 let indexFingerName = VNHumanHandPoseObservation.JointName.indexTip let width = viewportSize.width let height = viewportSize.height if let indexFingerPoint = try? observation.recognizedPoint(indexFingerName), indexFingerPoint.confidence > landmarkConfidenceThreshold { let normalizedLocation = indexFingerPoint.location indexFingerTipLocation = CGPoint((x: normalizedLocation.x * width, y: normalizedLocation.y * height)) } else { indexFingerTipLocation = nil }
-
15:47 - Getting hand chirality
// Working with chirality let handPoseRequest = VNDetectHumanHandPoseRequest() try handler.perform([handPoseRequest]) let detectedHandPoses = handPoseRequest.results! for hand in detectedHandPoses where hand.chirality == .right { // Take action on every right hand, or prune the results }
-
22:16 - Hand action classification by accumulating queue of hand poses
var queue = [MLMultiArray]() // . . . frameCounter += 1 if frameCounter % 2 == 0 { let hands: [(MLMultiArray, VNHumanHandPoseObservation.Chirality)] = getHands() for (pose, chirality) in hands where chirality == .right { queue.append(pose) queue = Array(queue.suffix(queueSize)) queueSamplingCounter += 1 if queue.count == queueSize && queueSamplingCounter % queueSamplingCount == 0 { let poses = MLMultiArray(concatenating: queue, axis: 0, dataType: .float32) let prediction = try? handActionModel?.prediction(poses: poses) guard let label = prediction?.label, let confidence = prediction?.labelProbabilities[label] else { continue } if confidence > handActionConfidenceThreshold { DispatchQueue.main.async { self.renderer?.renderHandActionEffect(name: label) } } } } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。