MocapForAllというアプリがある。複数のWebCamでキャプチャできる。デモ動画を見る限りは,けっこう正確にサンプルできているような。本当だったらスゲーな!
・・・複数のカメラとCVを組み合わせるのは良いとして,各カメラの関係をどうやって測定するのか。それをARで解決してるのは賢いな!このひと多分日本人だね?もう1.5年くらい開発してるって言うし,アリじゃないのか!?


MocapForAllというアプリがある。複数のWebCamでキャプチャできる。デモ動画を見る限りは,けっこう正確にサンプルできているような。本当だったらスゲーな!
・・・複数のカメラとCVを組み合わせるのは良いとして,各カメラの関係をどうやって測定するのか。それをARで解決してるのは賢いな!このひと多分日本人だね?もう1.5年くらい開発してるって言うし,アリじゃないのか!?


AIエージェントに必要なノンバーバルコミュニケーション
GPTにチャットが加わったことで、大規模言語AIは爆発的に普及した。つまり偉大なテクノロジーもインターフェイス次第ということだ。AIエージェントにとって、ノンバーバルコミュニケーション能力はインターフェイスだ。これらを強化することで、GPT→ChatGPTのようなインパクトが生じうる・・・はず。
エージェントに実装されるノンバーバル技能は3種類だ。
・表情・・・文脈に応じて笑う、眉を潜めるなど。
・ジェスチャ・・・文脈に応じて頷く、首をふるなど。
・視線・・・自信のないときは目線をそらすなど。
これらを充実させてコミュニケーションに統合することで、やがて違和感は消失に近づく・・・と思われる。
前回のつづき
今回はMMDモデル、モーション、カメラの導入と操作方法について解説する。
MMDモデルの導入
※特段モデルが何でも良い場合は3.モーション・カメラモーションのダウンロードまで読み飛ばしてほしい。
MMD向けのキャラクターモデルのデータはPMXという拡張子の付いたデータが用いられている。ニコニコ立体やpixiv、YouTubeなどで無料公開されている者やboothで有料公開されているものなどもある。また、初期状態でもいくつかのMMDモデルがMMDに入っている。
1.モデルのダウンロード
上記の通り様々な媒体で公開されていることから検索エンジンにて「○○(キャラクター名など)、MMDモデル」という風に検索するのが最も手っ取り早い。動画サイトの場合は「○○(キャラクター名など)、MMDモデル 配布」などと入力するとよい。
今回はこのサイトよりShiniNet式 メジ〇マoクイーンをダウンロードする。
ダウンロードしたzipファイルを解凍し必要な場所に保存する。著作者によってはDL時に連絡やコメントを残してほしい人もいるため確認すること。
推奨:ダウンロードしたモデルはMikuMikuDanceファイル内のUserFileのModelファイルに入れると確認しやすい

2.モデルの使用
回答したファイルには以下のデータが入っている。※()内は本画像の場合
・画像データ (ファイル)
・使用方法の説明(license(WEB))
・利用規約 (read me)
・モデルデータ (pmdまたはpmxファイル)

ファイルの中身を確認し、利用規約や必要に応じ使用方法を確認する。
ここまで確認出来たらMMDからこのデータを呼び出す。
MMDを起動し、左下のモデル操作の「読込」をクリック。
展開したエクスプローラーから展開したいモデルデータであるpmdまたはpmxファイルを選択する。

「モデル情報」で「OK」を選択

このように読み込めれば完了。最後にモデル操作の登録をクリックする。
以下どの操作でもそうだが、登録をクリックしないで他のモデルや他の設定を触ろうとするとそれまでのデータは保存されず、リセットさせられるので注意。
※青や赤の〇や🔲はボーンと呼ばれるもので後述する
3.モーション・カメラモーションのダウンロードと読み込み
モデルと同様に他のデータもダウンロードする。
今回は曲に合わせてモデルに踊ってもらいたいため、「曲名 MMD モーション」のように検索するとよい。 また、モーションに関しては動画サイトで検索すると確認にもなるので便利だと思う。
カメラモーションに関してはモーションと同時に配布している場合のほかに、個別でダウンロードする場合もある。個別の場合は出力の前に正しく動くか確認すること。
音楽とモーションのタイミングがずれることがある。
モデルと同様に利用規約を確認の上、zipファイルをDL、展開する。
この際、モーション、カメラモーションはUserFileのMotionに入れると展開しやすい。
今回、モデルには西沢さんPさんのチーズケーキクライシスを踊ってもらう。モーションはTarotaroさんが作成した • 【MMD】チーズケーキクライシス ダンスモーション【モーション配布】 のモーション、カメラモーションを利用する。展開先はMotionファイルとした。
MMD編集画面上での設定に移る。まず、キャラクターモーションを付けてみる。まず、「モデル操作」のプルダウンからモーションを付けたいキャラクターを選択する。次にその状態のまま左上の「ファイル」の「モーションデータ読込」をクリック。先ほど保存した、モーションの内ダンスモーションをクリックして指定する。



キャラクターの姿勢が変わっていれば、モーションを正しくダウンロードで来ている。登録も忘れずに。

本モーションはダンスモーション(体の動き)とリップシンク(口)が分かれていたためリップシンクのモーションも同様に付ける。
また、モーション読み込み時に画像のような警告が出ることがある。

これはMMDモデルとモーションのボーンが不一致の場合に出る警告で、このような場合動作チェックでおかしな動きをしている部分が無いか、チェックしておく事。(要はボーンが合ってないから、適応できるところだけモーションを付ける感じで良いか?と聞かれている)
次にカメラモーションの設定にうつる。
設定の仕方はほとんど同じで「モデル操作」のプルダウンから「カメラ・照明・アクセサリ」を選択。その状態のまま左上の「ファイル」の「モーションデータ読込」から今度はカメラモーションを選択する。

画面の表示が変わったら、これでモーション関連の設定は終了。
4.背景のダウンロード
背景を使用したい場合、背景もモデルとモデルと同様に利用規約を確認の上、zipファイルをDL、展開する。
使用できるファイルは様々で写真や黒一色といった画像ファイルの他、キャラクターと同じpmx形式のものも存在する。展開先であるが、pmx形式であればUserFile内のModelファイル、それ以外のAVIファイル、jpegなどはBackGroundファイルに保存するのがおすすめ。
今回はpmx形式のヨッシー式_トレセン学園ホームを使用した。pmx形式のためモデルと同様に「モデル操作」から「読込」で読み込む。
それ以外の画像ファイルを読み込む場合は左上の「背景(B)」から。

5.動作チェック
ここまでくると一応キャラクターを踊らせることが出来る。
「モデル操作」が「カメラ・照明・アクセサリ」になっていることを確認し画面右端の「再生」をクリックすると、カメラモーション付き(つまり動画再生時と同様の状態)で確認できる。(逆に定点から確認したい場合はMMDモデルを選択した状態で再生)
また、右上の「座標軸」をオフにするとよい。
これを出力すればそれっぽい動画にはなるが、次回はさらにエフェクトを付け、最後に出力方法の解説まで行いたい。取り急ぎ今回はここまで。
phpMyAdmin・MySQLの使用
修論のアプリ開発で,Client_IDのみのログインだと安全性に欠けるため,ID・Password欄を設けることにした.GPTに相談したところ,「パスワードはハッシュ化して,phpMyAdmin・MySQLから確認すればいい」とのことだが,MySQLのログイン時にさくらサーバーの管理ID等が必要なため,一時保留にした(TeraTermからサーバーにSSH接続が可能だが,どのみちMySQLが必要らしい).
mysql -u your_username -p
.csvファイルに書き込む場合
MySQL以外の方法として,.csvに直接書き込む方法もあるが,こちらは「セキュリティの脆弱性や,DLの危険性,同時書き込みの衝突」がある.セキュリティ面の対策として,下記のコードを同ディレクトリ内に置く,つまり「.htaccess で外部アクセスを遮断」しておくことで,外部からのDLを回避できるようだ(.csvに直接パスワードを付けようと思いついたが,こちらはその都度解凍処理が求められる).
//.htaccess で外部アクセスを遮断
<Files "users.csv">
Require all denied
</Files>
さらに,public_html の外に置いて,外部に公開するようのディレクトリと,非公開用のディレクトリに分けることで,外部からのアクセスを拒否することが可能.
//public_html の外に置く
├── public_html/ ← 外部に公開するファイル専用
│ ├── Shigeta/
│ │ ├── register_users_csv.php ← CSVデータを操作するPHPスクリプト
│ │ └── (その他の公開ファイル)
├── secure_data/ ← 非公開ファイル専用
│ ├── users.csv ← 外部からアクセスを拒否
│ └─ .htaccess ← このファイルを作成
└── (その他のファイル)
当初開発予定だったもの
ログイン画面・新規登録用の2つに分けて,新規登録者はこちらからcsvにどんどん書き込んでもらおうと考えていた.しかし,同時書き込み衝突の危険と,実験者側で事前に決めるという路線に変更.これから開発するものとしては,「ID・Pass」の入力欄を設けて,それをクリアした場合にClient_IDでディレクトリから画像を取り出すという仕様に変更する予定.となると,Client_IDはやはり紐づけして,パスワードをどうにかしてハッシュ化できるようにしないとだ.
あ,そうだ.以前作成したupload.phpが,「①Fitbitグラフの保存,②新規のみClient_IDに応じたディレクトリの作成」の機能を加えていたんだ.これに加えて,users.csvにID・パスワード(ランダムで4文字ずつ),Client_IDの関連付けて書き込んで保存すればいいんだ.Unityは,users.csvを参照して,IDを拾ってくる.これで自動化?


思考が拡散するのはリラックスしてる証拠だろうか・・・。そもそもUDPで送るのならOpenCVにこだわる必要もないし,もっと使いやすい表情分析ソリューションはないのだろうか?
Py-Feat
Python用の表情認識ツールキット。7表情やAU,特徴点,頭部の姿勢もわかる。これ・・・GPTの作成するプログラムで直ぐに動きそうに思うが。
Py-Featを使って表情認識をやってみた 基本的な使い方がわかる。
表情分析OSS Py-Featをつかってみた 頭部の姿勢検出が強力とある。
FER(Facial Expression Recognition)
これがOpenCVの元ネタに思える。
Microsoft AZURE
顔認識のサービスがある
Affectiva
かなり昔からある感情評定サービス。Unity用SDKがあるらしい。ブラウザで動作するデモが秀逸。ああ,これくらいだと利用しやすいんだけどなぁ・・・
プロジェクトはWindowsネイティブアプリ用に
WebGLアプリはUDPで表情認識AIの情報受け取れないし・・・一体どうしたらよいのか。結局,WebGL版の模擬人格プロジェクトをコピーして,Windowsネイティブアプリにしてビルドしてみたら,意外に良い感じで動いたので,こちらで行くことにしました。プロジェクトの名前はNative6です。ビルドターゲットのスイッチは7分弱かかって,頻繁に行うのは現実的じゃないです。
表情データの送信方式
遅きに失した感もありますが,オープンCVで認識した感情データをudpで送る部分はすでにできていたので,後はAIの情報を受け取るプログラムをGPT4oに作成してもらい,そこから感情情報を抜き出し,コミュニケーションに加味できるように,調整してみました。
実際に動かしてみて
感想としては,感情認識のタイミングがOpenAIへの問い合わせ依存なので,ややテンポが遅いようにも感じる。しかし現実のコミュニケーションも案外こんなもんかもしれない。
1.リアルタイムで感情模倣が起こることが大切なのか
2.GPT4oにこちらの感情状態が伝わることが大切なのか
どちらにしても表情を合わせてくれるので,これらの要因が実際のコミュニケーションでどんな風に機能するのかまだよくわからない。生きた人間のコミュニケーションでは,相手の(時として細やかな)表情を瞬時に読み取り,相手の意図や,コミュニケーション内容の真偽を直感的に評定していたりする。こういったコミュニケーションがAIエージェントに果たして可能なのか,そもそも必要なのか,研究はまだ始まったばかりだから分からないことだらけだ。
PsychoPyと外部プログラムの連携
ここでは,下記のようなシンプルな実験プロジェクトに外部プログラムで測定した測定結果をUDPで送り込み保存してみる。プロジェクトは,Fixation(+)の後にTarget(□)が出るので,スペースキーを押すと,反応時間が記録されるというもの。

BuilderのPythonマーク(青と黄のヘビ)をクリックすると,Coderが起動する。ここでコードを改造すると,UnityやProcessingからのデータを受け取ることができる。ただし,Builderでコードを生成すると,改造部分はすべて消し飛ぶので注意が必要だ。

まず冒頭で,ライブラリを呼んで,グローバル変数とUDPでデータを受け取るサブルーチンを用意する。
############# NAGANO #################
import socket
import threading
# UDPソケット設定
UDP_IP = "127.0.0.1" # 受信するIPアドレス
UDP_PORT = 5005 # ポート番号
# グローバル変数に最新のUDPデータを格納
latest_udp_data = "No Data"
def udp_listener():
"""非同期でUDPデータを受信する関数"""
global latest_udp_data
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # 1024バイトまで受信
latest_udp_data = data.decode("utf-8") # デコードして文字列に
############# NAGANO #################
次にプログラム開始部分でスレッドをスタートする。
win = setupWindow(expInfo=expInfo)
setupDevices(expInfo=expInfo, thisExp=thisExp, win=win)
############# NAGANO #################
# UDPリスナーをスレッドで起動
udp_thread = threading.Thread(target=udp_listener, daemon=True)
udp_thread.start()
############# NAGANO #################
でさらに,UDPでうけとったデータを保存する。データの受取は,別スレッドが非同期で行ってくれる。
key_resp_target.duration = _key_resp_target_allKeys[-1].duration
############# NAGANO #################
# UDPデータをログに記録
thisExp.addData('UDP_Data', latest_udp_data)
thisExp.addData('KeyPress_Time', globalClock.getTime()) # キー押下時刻も記録
############# NAGANO #################
# a response ends the routine
continueRoutine = False
実行すると,以下のような感じでUDP経由で送られたデータが保存される。ちなみに,データ送信側は,ローカルホストの5005ポートにProcessingでCerry,Diamond,Sevenのどれかひとつの文字列を送るもの。もう一度いうが,Builderで更新するとこれらの改造部分は消し飛ぶので注意!

VoiceVOXやCoeiroInkのSpeakerIDが必要になるときがある。・・・あるんだってば。VoiceVOXに関してはここから参照。
| キャラクター名 | スタイル | ID |
|---|---|---|
| 四国めたん | ノーマル | 2 |
| あまあま | 0 | |
| ツンツン | 6 | |
| セクシー | 4 | |
| ささやき | 36 | |
| ヒソヒソ | 37 | |
| ずんだもん | ノーマル | 3 |
| あまあま | 1 | |
| ツンツン | 7 | |
| セクシー | 5 | |
| ささやき | 22 | |
| ヒソヒソ | 38 | |
| 春日部つむぎ | ノーマル | 8 |
| 雨晴はう | ノーマル | 10 |
| 波音リツ | ノーマル | 9 |
| 玄野武宏 | ノーマル | 11 |
| 喜び | 39 | |
| ツンギレ | 40 | |
| 悲しみ | 41 | |
| 白上虎太郎 | ふつう | 12 |
| わーい | 32 | |
| びくびく | 33 | |
| おこ | 34 | |
| びえーん | 35 | |
| 青山龍星 | ノーマル | 13 |
| 冥鳴ひまり | ノーマル | 14 |
| 九州そら | ノーマル | 16 |
| あまあま | 15 | |
| ツンツン | 18 | |
| セクシー | 17 | |
| ささやき | 19 | |
| もち子さん | ノーマル | 20 |
| 剣崎雌雄 | ノーマル | 21 |
| WhiteCUL | ノーマル | 23 |
| たのしい | 24 | |
| かなしい | 25 | |
| びえーん | 26 | |
| 後鬼 | 人間ver. | 27 |
| ぬいぐるみver. | 28 | |
| No.7 | ノーマル | 29 |
| アナウンス | 30 | |
| 読み聞かせ | 31 | |
| ちび式じい | ノーマル | 42 |
| 櫻歌ミコ | ノーマル | 43 |
| 第二形態 | 44 | |
| ロリ | 45 | |
| 小夜/SAYO | ノーマル | 46 |
| ナースロボ_タイプT | ノーマル | 47 |
| 楽々 | 48 | |
| 恐怖 | 49 | |
| 内緒話 | 50 |
CoeiroINKは下記のような感じ
//つくよみちゃん(れいせい) 0
//つくよみちゃん(おしとやか) 5
//つくよみちゃん(元気) 6
//KANA(のーまる) 30
//KANA(えんげき) 31
//KANA(ほうかご) 32
//リリンちゃん(ノーマル) 90
//リリンちゃん(ささやき) 91
//モモイヒナ-A 1737595468
//KAKU_N 259
//KAKU_W 260
Python編
Anacondaをインストールし、環境をつくるところまでは一緒。新しいライブラリ(1.0.0以降)に対応したコードがなかなか見つからない。今回はここを参考にした。Pythonのバージョンは3.10.15、OPENAIライブラリのバージョンは1.57.0。
追加予定コンテンツ:GPT4Vによる画像解析、Voicevoxとの連携

GPT01/最低限のコード
文章作成を行うための最低限のコード。Temperatureが指定できる。
#GPT01.py
#GPT4を使って文章生成を行う最低限のコード
from openai import OpenAI
client = OpenAI(api_key="sk-hogehoge")
completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "あなたは大学図書館の優秀な受付です"},
{"role": "user", "content": "初めて図書館に来た大学生に、図書館の魅力を200文字で伝えてください。"}
],
#temperature=0.1文章が一貫性の高い回答
#temperature=0.9より創造的で予想外な回答
temperature=0.7
)
# 日本語の文字列部分だけを取得
response_text = completion.choices[0].message.content
print(response_text)
GPT02/使用したトークンの取得
文章生成に使用したトークンの数を表示してくれる
#GPT02.py
#GPT4を使って文章生成を行い消費したトークンを表示
from openai import OpenAI
client = OpenAI(api_key="sk-hogehoge")
completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "あなたは大学図書館の優秀な受付です"},
{"role": "user", "content": "初めて図書館に来た大学生に、図書館の魅力を200文字で伝えてください。"}
],
temperature=0.7
)
# 日本語の文字列部分だけを取得
response_text = completion.choices[0].message.content
print(response_text)
# 消費したトークン数を表示
total_tokens = completion.usage.total_tokens
prompt_tokens = completion.usage.prompt_tokens
completion_tokens = completion.usage.completion_tokens
print(f"消費したトークン数: 合計 {total_tokens}, プロンプト {prompt_tokens}, 応答 {completion_tokens}")
Chat01/チャット用スクリプト
人格を設定して会話を行うことができる。
#Chat01.py
#設定した人格に基づいて、チャットを行うスクリプト。
from openai import OpenAI
client = OpenAI(api_key="sk-hogehoge")
personality = "あなたは、埼玉県内の大学に通う男子大学2年生です。所属学科は心理学科です。一人称は「僕」、二人称は「きみ」を使います。明るく気さくな感じで話します。「〇〇だよな」「〇〇だな」「〇〇だろ?」「〇〇だと思う」などの語尾を使って話します。"
# 初期設定
messages = [
{"role": "system", "content": personality}
]
print("模擬人格と会話を始めます。'終了'と入力すると終了します。")
while True:
# ユーザーの入力を受け取る
user_input = input("user: ")
# 終了コマンド
if user_input.strip() == "終了":
print("会話を終了します。")
break
# ユーザー発言を保存
messages.append({"role": "user", "content": user_input})
# 会話履歴を最新20件に制限
if len(messages) > 21: # 21 = systemメッセージ + 過去20回の履歴
messages.pop(1) # 最初のユーザーかアシスタントの履歴を削除
# OpenAI APIにリクエスト
completion = client.chat.completions.create( # 修正箇所
model="gpt-4o",
messages=messages,
temperature=0.7
)
# アシスタントの応答を取得
assistant_response = completion.choices[0].message.content
print(f"assistant: {assistant_response}")
# アシスタントの応答を保存
messages.append({"role": "assistant", "content": assistant_response})
VVOX01/合成音声を作成する最低限のスクリプト
ローカルで実行中のvoicevoxにむかってテキストを送り込み、合成音声として再生してもらいます。voicevoxのspeakerIDはこちらを参照。
#VVOX01.py
#ローカルで起動したvoicevoxに、pythonから文字を送って合成音声を再生するスクリプト。
import requests
import json
from pydub import AudioSegment, playback
HOSTNAME='http://localhost:50021'
speaker = 3 #ずんだもん
msg="こんにちは、ずんだもんです!"
def playsound(text):
# audio_query (音声合成用のクエリを作成するAPI)
res1 = requests.post(HOSTNAME + '/audio_query',
params={'text': text, 'speaker': speaker})
# synthesis (音声合成するAPI)
res2 = requests.post(HOSTNAME + '/synthesis',
params={'speaker': speaker},
data=json.dumps(res1.json()))
# wavの音声を再生
playback.play(AudioSegment(res2.content,
sample_width=2, frame_rate=22050, channels=1))
playsound(msg)
Chat02/合成音声でAIとチャットを行うスクリプト
チャットスクリプトと合成音声スクリプトを統合したもの
#Chat02.py
#設定した人格に基づいて、チャットを行い、AIの返答を合成音声で返答するスクリプト。
from openai import OpenAI
import requests
import json
from pydub import AudioSegment, playback
# OpenAI API設定
client = OpenAI(api_key="sk-hogehoge")
# VoiceVox設定
HOSTNAME = 'http://localhost:50021'
speaker = 13 # 青山龍星
def playsound(text):
"""VoiceVoxで音声合成して再生する"""
# audio_query (音声合成用のクエリを作成するAPI)
res1 = requests.post(HOSTNAME + '/audio_query',
params={'text': text, 'speaker': speaker})
# synthesis (音声合成するAPI)
res2 = requests.post(HOSTNAME + '/synthesis',
params={'speaker': speaker},
data=json.dumps(res1.json()))
# wavの音声を再生
playback.play(AudioSegment(res2.content,
sample_width=2, frame_rate=24000, channels=1))
# AIの人格設定
personality = "あなたは、アイオワ州在住の陸軍兵士です。一人称は「おれ」、二人称は「おまえ」を使います。「〇〇だよな」「〇〇だな」「〇〇だろ?」「〇〇だと思う」などの語尾を使って話します。ぶっきらぼうだけど、本当は優しい性格で、ユーザーの会話を掘り下げ、悩み相談にのってくれる。"
# 初期設定
messages = [
{"role": "system", "content": personality}
]
print("模擬人格と会話を始めます。'終了'と入力すると終了します。")
while True:
# ユーザーの入力を受け取る
user_input = input("user: ")
# 終了コマンド
if user_input.strip() == "終了":
print("会話を終了します。")
break
# ユーザー発言を保存
messages.append({"role": "user", "content": user_input})
# 会話履歴を最新20件に制限
if len(messages) > 21:
messages.pop(1)
# OpenAI APIにリクエスト
completion = client.chat.completions.create(
model="gpt-4o",
messages=messages,
temperature=0.7
)
# アシスタントの応答を取得
assistant_response = completion.choices[0].message.content
print(f"assistant: {assistant_response}")
# アシスタントの応答を保存
messages.append({"role": "assistant", "content": assistant_response})
# VoiceVoxで音声合成&再生
playsound(assistant_response)
GPT4V/画像を読み込み解釈する
指定したファイル名の画像を、プロンプトに従って解釈し、説明します。
#GPT4V.py
#画像を読み込んで、説明を行うスクリプト。
import base64
from pathlib import Path
from openai import OpenAI
client = OpenAI(api_key="sk-hogehoge")
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
image_path = "picture1.jpg"
base64_image = encode_image(image_path)
file_extension = Path(image_path).suffix
file_extension_without_dot = file_extension[1:]
url = f"data:image/{file_extension_without_dot};base64,{base64_image}"
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "どのような状況か300文字くらいで説明してください。季節も推測してください。",
},
{
"type": "image_url",
"image_url": {
"url": url,
},
},
],
}
],
max_tokens=1000,
)
print(response.choices[0].message.content)
FacialExpressionRecognitionAI
UnityのOpenCVで表情判定を行い、その結果をさらにUDPでProcessingに送る。詳しくは動画に。
Regardless of Outcome. Cosmic Evolutionなど
Solar SonarのSoaring
Sur Sagano How to Heal
MMDとは「MikuMikuDance」の略称で樋口優氏によるフリーの軽快な3DPV作成ツールである(pixiv百科事典)。
元々は初音ミクを踊らせる3Dアニメーション制作ツールであり、現在ではその他キャラクターにも幅広く対応し、自作PVやキャラクターのダンス動画などがニコニコ、YouTubeに多数投稿されている。
・・・というか、キャラクター以外のアセットやモデルも多数存在し、その汎用性は幅広い。
現長野ゼミでは主にunityを用いてアニメーションや3D空間の作成を行っているが、キャラクターを踊らせる程度であれば、このソフトウェアも使えるかもしれない。
ということで、MMDの導入から簡単な3Dアニメーションの作成までの雑感をまとめておこうと思う(建前)。
以下導入に当たり、以下のサイトや動画を参考に進めていく。詳細はこちらを参照されたし。
MMDの導入を紹介している動画:
https://youtube.com/playlist?list=PL7Jbc_YxpkriO7nb-QzvDFwozgc1O3s0F&feature=shared
同作者による導入ブログ(他にもAIやDTMなど多数紹介):
https://how-to-use-music-video.com/
自作でモーションを作る方法の説明をしているブログ
https://note.com/tareire/n/n22d17c2a4c4b
初心者向けの解説動画
https://www.youtube.com/watch?v=Jp7wf4TNcA0
同じように初心者向けの動画
https://www.youtube.com/watch?v=G2vLiDWKMgY
また、使用したPCのスペックは以下の通り
プロセッサ Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 2.59 GHz
実装 RAM 16.0 GB (15.8 GB 使用可能)
システムの種類 64 ビット オペレーティング システム、x64 ベース プロセッサ
GPU NVIDIA GeForce MX250
前置きが長くなりましたが、本題に入ります
まず、
https://sites.google.com/view/vpvp/
のサイトにアクセスし64bit版Windows用をダウンロード(ZIPファイルでDLすることになる)する。
note:ほかに32bit版も存在する。この辺りは自分のPCスペックを参照のこと。

ZIPファイルを適当な場所に展開しその中にある「MikuMikuDance.exe」をクリックし、起動する。
note:その下にあるreadme.txtに開発者からの説明やバージョン情報などが書きこまれている


時折見る編集画面が出てきた。
導入自体はこれで完了。感想としてはひたすらに軽い。

プロパティを開くと18.2MBくらいしかない。
unityと比べるとだいぶ軽いなぁ・・・
今回はこの辺りで。
Unity用のDlibライブラリ,結構速かったように思う。フルバージョンでなく17ポイントバージョンなどを使えば高速化が期待できる。最新版に更新して試してみると,「sp_human_face_68_for_mobile」などのモバイル版モデルが入っていた(前から?)。ということは,WebGLでも高速な笑顔検出ができるのでは??試してみると普通に30FPS(おそらく内部的にはもっと?)出てる。ARHeadでは,頭部の姿勢推定も可能となっているはず。。。こちらもEnableDownscaleで30FPS出るようになった。笑顔推定をDlibで行えばAffectiveGamesも実運用可能と思われる。


あらためて冷静に見ると,WebCamで画面との距離や頭の姿勢,表情判定に使用可能な68特徴点を連続的に取得できるのは,かなりお得じゃないか?しかもWebGLでって。お手軽データ測定にこれを導入してみるのも良いかもしんない。
導入
いただきました,その名前。今日,諸先生がたと立ち話した収穫として,「クソゲー連発案は有用であること」,「感情把握アプリは老人業界にも有用」などのこと。FaceAnalyzerはよく見るとWebGL未対応のようで,そうなるとOpenGLでやるしかない。WebGLだとブラウザ立ち上げるだけで,AffectiveComputing技術ベースのアプリが利用できる可能性がある。
善は急げでビルドしてみる・・・
OpenCV4Unityはサポートバージョンが上がっていたので,いっそUnity6にしてみるが・・・ビルドできず(泣)。マニュアルを読むと,バージョンによってWebGLのプラグインが異なるらしいので,2023.2.20にしてみる。ビルドは通るが公式DEMOより明らかに遅い!何故だ!!MultiThredとSIMDを有効にしてみる・・・「ブラウザはマルチスレッドをサポートしてません(FirefoxもChromeも)」で起動すらせず。SIMDのみにしてみる。無事に動作した! これで表情利用したWebGLアプリをリリースできそうだ。・・・動作が13fpsなのが気になる。解像度を320x240にすると22FPSに。もう少し速くなるといいんだけどなぁ。科学技術のげ限界っ!



遅い・・・
どうも純粋にCPUを使っており、かつシングルスレッドのためか、かなり遅い。Corei5_9600kで6.7FPSは衝撃の遅さだ(Ryzen7_6800Uの方が速い)。AIアプリの実行環境はPCネイティブ環境しかダメということか・・・。いっそAndroidに行くというのは?手持ちで一番速そうなHelioG99にAndroidネイティブアプリを入れてみると、19~22FPS程度。WebGLよりは速いけど、ちょっと・・・なぁ。



マルチスレッド対応の効果見られず
WebGLはUnity2022あたりからマルチスレッドに対応しているという。そこでマルチスレッド対応バージョンをビルドしてみた。ブラウザが「マルチスレッドに対応していません」と言う場合は,下記のヘッダを.htaccessで設置すれば動くようになる。アプリがロード中に止まるのはメモリ不足なので,使用可能メモリを倍にすればロードするようになる。結果として,フレームレート変わらねぇ・・(怒)。プログラムがマルチスレッド対応してないと意味ないということか?
<IfModule mod_headers.c>
Header set Cross-Origin-Opener-Policy "same-origin"
Header set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>