はじめに
エンジニアの松原です。近年生成系AI、特にStableDiffusionの仕組みをベースとした生成系AIが目まぐるしい速度で進化しており、2023年の年間を通しても取り沙汰されない日のほうが少ないのでは、と思えるぐらい連日SNSでのニュースで見かけていました。
私自身も長いことAIのニュースを追いかけていなかったので、改めて追っていったところ、StableDiffusionの拡張機能として利用できる ControlNet の仕組みが面白く、2023年の夏ぐらいから調べていました。
今回は ControlNet でポーズの指示を扱うためのスケルトン情報(または Keypoints )を生成できるよう、Unity上でOpenPose風のアバターを表示するスクリプトを作ったことについて取り上げたいと思います。
本記事に入る前に
今回の記事は「生成系AIを使ってみた」、という内容ではなく、その前段階として、プロンプト指示に利用できるデータをUnityから生成できるようにするというのが記事の内容になります。
本記事に含まれる用語が分かっていると本記事の目的が分かりやすいので、超ざっくりですが以下に取り上げました。
ControlNetについて
StableDiffusion自体の基本的な解説に関しては、Qiitaでわかりやすくまとめてくださっている記事がありますので、そちらをご参考ください。
また、StableDiffusionの基本的な機能として、テキストを使ったプロンプト指示によって任意の生成画像を得られる仕組みが主な機能になっていますが、ControlNetを利用することにより、テキスト以外の情報をプロンプト指示に追加できるようになります。
ControlNetで利用できるバリエーションはいくつかありますが、今回はOpenPoseに着目しました。
OpenPoseについて
OpenPoseは人物を含む画像から抽象化されたボーン構造ベースの人体モデルを推定し、その人体モデルに含まれる各関節の情報を画像中の特徴点として書き出せるシステムです。この特徴点は三次元座標としても取り出せるため、他の目的にも利用できる技術になっています。
本記事の目的
今回はStableDiffusionの拡張機能であるControlNetを使ったプロンプト指示向けに、Unity上で表示するアバターに対してOpenPoseのボーン構造(18特徴点)を表示するスクリプトを作ってみました。
このスクリプトは近いうちに公開予定ですが、使い勝手を良くするために現在スクリプトの内容を整理しています。公開可能になったタイミングで記事に差し込みたいと思います。モデルはユニティちゃん 3Dモデルデータをお借りしております。
OpenPose風のアバタースケルトンを表示する仕組みの解説
以下今回作ったスクリプトについて解説していきます。
ボーン構造の対応付け
Unityには、モデリングソフトで作成したアバターに含まれるボーン構造を、Unity側のアバターシステムと紐づけを行う機能として、Humanoid というシステムがあります。この仕組みを応用して、OpenPoseのボーン構造に近い状態にマッピングします。
首から下ぐらいまでボーン構造が一致する箇所が多くあるため、Humanoidの関節情報をベースに親となるTransformを割り出しています。対応関係は以下のようになります。
index | OpenPoseキーポイント名 | Humanoidボーン名 |
---|---|---|
0 | Nose | HumanBodyBones.Head |
1 | Neck | HumanBodyBones.Neck |
2 | Right Shoulder | HumanBodyBones.RightUpperArm |
3 | Right Elbow | HumanBodyBones.RightLowerArm |
4 | Right Wrist | HumanBodyBones.RightHand |
5 | Left Shoulder | HumanBodyBones.LeftUpperArm |
6 | Left Elbow | HumanBodyBones.LeftLowerArm |
7 | Left Wrist | HumanBodyBones.LeftHand |
8 | Right Hip | HumanBodyBones.RightUpperLeg |
9 | Right Knee | HumanBodyBones.RightLowerLeg |
10 | Right Ankle | HumanBodyBones.RightFoot |
11 | Left Hip | HumanBodyBones.LeftUpperLeg |
12 | Left Knee | HumanBodyBones.LeftLowerLeg |
13 | Left Ankle | HumanBodyBones.LeftFoot |
14 | Right Eye | HumanBodyBones.RightEye |
15 | Left Eye | HumanBodyBones.LeftEye |
16 | Right Ear | HumanBodyBones.RightEye |
17 | Left Ear | HumanBodyBones.LeftEye |
Unityの HumanBodyBones はこちらで定義されています。
耳のTransformはUnity側のHumanoidにはないため、大まかな位置を仮決めします。また、モデルによっては目のTransform(RightEye、LeftEye)が無いケースがあり、その場合は頭のTransform(Head)から大まかな位置を割り当てます。
スクリーンへのボーン構造を投影して描画
OpenPoseの特徴点とボーンの線分を一種のアバターとして描画する方法もありますが、その場合はカメラ位置との関係によって特徴点が小さく描画する可能性があります。
特徴点が小さく書かれることを回避するため、特徴点を一度スクリーン(Canvas)上の座標系に変換し、キャンバス上のグラフィックとして特徴点と線分を描画します。
できたもの
終わりに
今回はControlNetで利用すること前提でOpenPose風のアバタースケルトンをUnity上で表示する仕組みを作りました。OpenPose以外にも画像生成系AIで利用するために、Unityから出力できるデータ表現について考えていければと思います。