MkItYs

MkItYs > AI・交渉・物語の自動生成 > 

images

AI で生成した<動くキャラ>と、VR/MR で対面する:ComfyUI, GIMP, Virtual Desktop, Quest

images

画像生成モデルで動画化したキャラを、ステレオグラムで立体化し、VR/MR で対面してみました:



※1
生成画像は、次のモデルを使用しています:
https://huggingface.co/WarriorMama777/OrangeMixs

関連


ComfyUI で画像生成 〜 なぜそこにつなぐのか:ComfyUI, Stable Diffusion
ComfyUI を、クラウドのコンテナに設置する:ComfyUI, Docker, GCP
ComfyUI の API を使う:ComfyUI, API, JSON, Python, Docker, GCP

検証


アプリ
画像生成:ComfyUI
画像編集:GIMP
VR/MR
PC〜HMD間ストリミーング:Virtual Desktop
HMD:Quest 2
クライアント
コンテナ:Docker Desktop
ホスト:macOS
ゲスト:Ubuntu 22.04
サーバ
クラウド:GCP
コンテナ:Docker
ホスト:Ubuntu 22.04
ゲスト:Ubuntu 22.04

概要


いまは、一枚の画像から深度を推定する技術が進歩し、立体視化もそれほど違和感のないレベルに達しています。また画像生成モデルだけでも、あるていどの動画生成は可能になっています。

ここでは、キャラの動画を立体視できるようにして、VR/MR(パススルー)で対面してみます。

前提


ComfyUI では、次のカスタムノード群を使います:


動画生成(AnimateDiff)
https://github.com/Kosinkadink/ComfyUI-AnimateDiff-Evolved

文章(プロンプト)から生成される画像を、さらに動画化します。


物体検出(Rembg/U2-Net)
https://github.com/Jcd1230/rembg-comfyui-node

動画のフレーム(画像)群から物体(キャラ)を検出し、背景と切り離しますーーこれで、目的の対象だけを表示できるようになります。[※1]


深度推定(ControlNet Auxiliary Preprocessors/MiDaS)
https://github.com/Fannovel16/comfyui_controlnet_aux

動画のフレーム(画像)群から奥行きを推定し、深度マップ群を作ります。[※2]


立体視化(NegiTools/Stereo Image Generator)
https://github.com/natto-maki/ComfyUI-NegiTools

動画のフレーム(画像)群とその深度マップ群から、ステレオグラムのフレーム群を作成しますーーこれで、VR/MR で、対象を立体視できるようになります。[※3]



※1
Rembg は、汎用の物体検出モデル U2-Net を使いますーーただし、キャラがフラットな塗りのアニメ調だと、誤検出も多い、という欠点がありますーーなのでここでは、厚塗り系と呼ばれるモデルを使い、より立体感を強調するキャラにしていますーーフラットな塗りのキャラを使うなら……たとえば、ここでの処理は深度マップを生成するので、GIMP などを使い、一定の深さの箇所(背景)を黒の画像と合成する、といったやり方などがあるかもしれません。
※2
ここでは深度マップの生成に、MiDaS / control_v11f1p_sd15_depth を使っていますーー生成は軽く速いものの、推定の精度はそれなりですーーキャラがリアル調なら Marigold、アニメ調ならLine2Depth (Line2Normalmap) などを使うと、より精度の高い深度マップが生成されます:
https://github.com/kijai/ComfyUI-Marigold
https://huggingface.co/toyxyz/Line2Depth_sd1.5
※3
このノードは、次の A1111 / Stable Diffusion web UI 向けプラグインのラッパですーーよく分からないのは、平行法(left-right)のステレオグラムを作成するのに、ノードでは交差法(R-L)を選択しないといけないことですーーコードをみるかぎり、ラッパ側の L-R がソース側の left-right に対応してるんですけどね……
https://github.com/thygate/stable-diffusion-webui-depthmap-script

設置


ここでは、物体検出と立体視化のノード群について、検証した設置手順を示します:

物体検出(Rembg/U2-Net)

対象のリボジトリからコード群を取得し、ComfyUI のカスタムノード向けフォルダに設置します:

$ cd ${directory_project}
$ git clone --depth=1 https://github.com/Jcd1230/rembg-comfyui-node.git
$ mv rembg-comfyui-node rembg-comfyui-node_ver_${yyyy_mm_dd_nnn}
$ cd ${yyyy_mm_dd_nnn}/ComfyUI/custom_nodes
$ ln -s ${directory_project}/rembg-comfyui-node_ver_${yyyy_mm_dd_nnn} rembg-comfyui-node

ComfyUI が動く環境で、必要なライブラリ群を設置します:[※1]

$ pip install rembg[gpu]
$ pip install kornia
立体視化(NegiTools/Stereo Image Generator)

必要なのは、立体視化のための次のノード群のみなので:

https://github.com/natto-maki/ComfyUI-NegiTools/blob/master/negi/stereo_image_generator.py
https://github.com/natto-maki/ComfyUI-NegiTools/blob/master/negi/noise_image_generator.py

ComfyUI のカスタムノード向けフォルダに、任意のフォルダを作り、次のファイルでマッピングを宣言します:

__init__.py
from .negi.stereo_image_generator import StereoImageGenerator

NODE_CLASS_MAPPINGS = {
  "NegiTools_StereoImageGenerator": StereoImageGenerator
}
NODE_DISPLAY_NAME_MAPPINGS = {
  "NegiTools_StereoImageGenerator": "Stereo Image Generator 🧅"
}

直下にフォルダを1コ作り、必要なノードのコード群を設置します:[※2]

> negi
  < stereo_image_generator.py
  < noise_image_generator.py

※1
物体検知のモデル U2-Net は、ホームディレクトリに配置されます:
${HOME}/.u2net/u2net.onnx
※2
ノードが最初に使われるときに、ラッパするライブラリを取得するため、次のリポジトリからフォルダ内に、コード群が配置されます:
https://github.com/thygate/stable-diffusion-webui-depthmap-script

作成


次の手順で、動画のステレオグラム群を作成します:

まず、動画のフレーム群を生成しますーー最初は、Save Image ノードは無効にしておいた方がいいかもしれません。

生成結果を動画(GIF )で確認しつつ、プロンプトやシードを決めていきます。決まったら、履歴からその状態に戻り、Save Image ノードを有効にします。ふたたび生成を実行すると、動画のフレームになる画像群が、output フォルダに保存されます:

${directory_development}/cnf/try004_workflow_animatediff.json
images

フォルダ output に生成されたフレーム群を、フォルダ input に移します:

$ cd ${directory_comfyui}/input
$ mv ${directory_comfyui}/output/??????_???_?????_.png .

ComfyUI の API を使って、動画のフレーム群をステレオグラムのフレーム群に変換します。

元になるワークフローは、画像1枚ごとに、[1]背景を抜く〜[2]深度マップを作る〜[3]ステレオグラムのフレームを作る、ように構成します(なお、Rembg ノードが出力する背景は透過状態(アルファチャネルでの指定)になるので、Split Image with Alpha ノードを介して(Stable Diffusion があつかえる)通常の画像のマスクに変換します)。

このワークフローを、フレームの枚数分だけ繰り返すよう、スクリプトを作成します。このスクリプトを、Python を実行できる環境から、ComfyUI が動く環境に対し、実行します:[※1]

${directory_development}/cnf/try004_workflow_api_stereogram.json
images
${directory_development}/bin/try004.py
import sys
import time
import json
from urllib import request

def reqcmf(dctflw):
  prompt = {'prompt': dctflw}
  conweb = json.dumps(prompt).encode('utf-8')
  reqweb = request.Request(f"{urltgt}prompt", data=conweb)
  request.urlopen(reqweb)

urltgt = sys.argv[1]
strflw = sys.stdin.read()
dctflw = json.loads(strflw)

l = list(range(1,17)) 
for i in l:
  dctflw['2']['inputs']['image'] = 'try004_frm_' + f'{i:05}' + '_.png'
  reqcmf(dctflw)
  time.sleep(1)
$ cat ${directory_development}/cnf/try004_workflow_api_stereogram.json | python ${directory_development}/bin/try004.py http://${server}:${port}/

作成されたステレオグラムのフレーム群を取得します:

$ cd ${directory_working}
$ scp ${user}@${server}:${directory_comfyui}/output/'??????_???_?????_.png' .

画像編集アプリの GIMP で、フレーム群から動画ファイル(GIF)を作ります:[※2]

> file open: <image_1>.png
> open as layers: <image_2>.png, ..., <image_N>.png # 一括での選択可

> filters > animation > 
  > optimize (for gif)
  > playback # 再生を確認

> file > export as
  > select file type (by extension)
    > <image>.gif
    > [export]
      > as animation: <yes>
images

※1
ここのカスタムノードの”Image batch To Image List”を使えば、ComfyUI の標準とは違う画像リストを作り、ワークフロー上で反復実行してくれるかもしれません(試していませんが):
https://github.com/ltdrdata/ComfyUI-Impact-Pack
※2
このステレオグラムは、平行法でみることができますーー連続した画像でも、統一した立体感が与えられていることを確認できると思います(統一感はあるものの、右足の遠近感が微妙ですね……ただこの生成画像だとこうするしかなさそうで、深度推定はがんばってると思います)。

利用


動画ファイル(GIF)を、Virtual Desktop Streamer が動く環境に移します。

HMDで Virtual Desktop を実行し、動画ファイル(GIF)を画像ビューアで開きますーーデスクトップ画面のモードを、SBS (Side-by-Side) + Transparency にすることで、生成した動くキャラと MR で対面できます:[※1][※2][※3]

> menu (bottom) > full sbs
> menu (top) > transparency

※1
動画の上下がはみ出すときは、ディスプレの向きの設定を縦にするなどし、表示できる領域を確保します。
※2
Windows の既定の画像ビューアだと、上下に灰色の枠がつくので、そういった枠をつけないビューアがいいかもしれません(IrfanView, ...)。
※3
ここでクロマキーが使えればいいんですけどねーーVirtual Desktop のデスクトップ画面は、黒色を透過させるだけですーーSteamVR のメディアプレイヤなら(Virtual Desktop のゲーム内になるので)SBS でもクロマキーが使えますが、画面の位置調整が煩雑など、使い勝手がよくありませんしーー一長一短です……

感想


目の前にいるキャラは、奥行きがあり動いてもいるので、じっさいにその場にいるように感じられますーーこれがたった数文字のプロンプトから生まれた存在だと考えると、感慨深いものがありますね。[※1][※2]


※1
いまのところただの動画なので、触れてもスカスカな状態ですーーただ深度マップはもっているので、HMDの深度センサと組み合わせれば、<触れる>感触を得ることも可能ですーーこれがリアルタイムに生成できるようになれば、インタラクティブ性をもたせることもできるでしょうし、物理演算をふくめた多彩な反応が得られそうです。
※2
もちろんその数文字のプロンプトの背後には、膨大な数の創作者(絵画〜写真)の熱意と努力の成果がありますーー生成モデルの普及で、それらの利用のしかたが、<個別の作品を鑑賞・体験する>というかたちから、<作品の集合を融合・体験する>というかたちに変わってきていますーー問題のひとつは、もともとあった<出典>(作家と作品など)という構造が、フラットになってしまっている、という点です。ここをどう解決していくかが、技術側の課題といえそうです。