ControlNet「Depth」の導入と使い方 ― SD1.5で奥行きや位置関係を再現する ~ 画像生成AI実験メモ ⑥

ControlNetのOpenPoseを使用して、プロンプトだけでは生成が難しい画像も生成できるようになりましたが、それだけではまだまだ難しい表現があります。それが、画像の奥行きと、モノとの位置関係・距離感です。
今回は、それらを克服するというControlNet Depth の機能を使ってみたいと思います。
本記事に掲載している人物画像は、すべて生成AIにより作成したものであり、特定の実在人物をモデルにしたものではありません。
Depth機能を使ってみる
Depthは、元画像から物体までの距離や前後関係を推定し、その奥行き情報を使って画像生成を制御するControlNetの機能になります。
OpenPoseが主に人物の骨格やポーズを指定するのに対し、Depthは人物だけでなく、机・壁・背景などを含めた画面全体の立体的な配置を反映しやすいのが特徴です。
そのため、「両手をテーブルにつく」「壁にもたれる」「手前に腕を伸ばす」といった、人物と周囲の物体との位置関係が重要な構図で効果を発揮する、とされています。
とはいえ、使ってみなければ役立つかどうかは判らないですから、まずはやってみましょう。
Depthの導入
Depthを使うには、以下の手順で導入する必要があります。
が、OpenPoseを使用した後ならControlNetは導入済みなので、Depth用モデルをダウンロードするところから、になります。
Stable Diffusion Web UI(AUTOMATIC1111版、以下A1111)の下の方にもControlNetが見当たらない、という場合は、まずはControlNetの導入から、ですね。こちらを参考にしていただければ、と思います。
Depth用ControlNetモデル(control_v11f1p_sd15_depth.yaml)は、例によって、Hugging Face から。
モデルの名前にもあります通り、今回もSD1.5をベースでやってみたいと思います。
https://huggingface.co/lllyasviel/ControlNet-v1-1
これは、OpnePoseのときと同じリポジトリですね。「Files and Versions」タブにあるファイル一覧から、control_v11f1p_sd15_depth.pthを選び、Downloadアイコン(↓)を押します。
ダウンロードしたファイルを下記のフォルダに格納します。
stable-diffusion-webui
└─ extensions
└─ sd-webui-controlnet
└─ models
└─ control_v11f1p_sd15_depth.pth
A1111のtxt2imgで、Generationにある「ControlNet」を展開します。
Contorl Type で「Depth」を選択。
すると、PreprocessorとModelの選択欄が見えますが、Preprocessorの方はデフォルトの設定が入っているものの、Modelは、何も選択できない状態となっているかと思います。
上記でファイルをフォルダに格納した直後なら、右側の回転するリフレッシュアイコンをクリックします。
リフレッシュすると選択肢が増えますね。
この中から、「contorl_v11f1p_sd15_depth」を選択します。
Preprocessorの方は、表示されている depth_midas のままで大丈夫です。
他のパラメータは後で設定するとして、いよいよ実践ですね。
テーブルに両手をついて前かがみ
Depthを使用するからには、前後に立体的な膨らみが欲しいですので、こんな構図を考えてみました。
テーブルに両手をついて前かがみ。って、頭の中にはイメージがあるんですが、どう説明すればいいんでしょうか。
そういう時は、作ってしまいましょう。
というわけで、OpenPoseのときの3例目のように、先行してSDXLでイメージ図を作成します。
・Model:sd_xl_base_1.0.safetensors
・Sampler:DPM++ 2M SDE
・Schedule type:Karras
・Sampring steps:30
・CFG Scale:6
・Seed:-1
・サイズ(Width x Height):768 x 1024
pompt
photo of a young Japanese woman standing at a kitchen counter,
facing the camera, front view, straight-on view,
both hands firmly placed flat on the countertop,
leaning forward noticeably,
body weight supported by both hands,
shoulders and chest extending forward over the counter,
upper torso clearly angled toward the countertop,
hips remaining back,
arms straight or slightly bent,
looking forward, centered composition, medium shot,
realistic photography, modern kitchen interior
Negative pompt
side view, profile, from the side, back view,
sitting, seated, chair, crouching, kneeling,
standing upright, standing straight,
leaning backward,
one hand, hands hidden, arms crossed,
holding utensils, holding food, cooking,
extra arms, extra hands, deformed hands, bad anatomy,
countertop not visible
正面を向いて欲しくてプロンプトを作成したんですが(見た目ではなく、奥行き感を出したかったため)、結果的に採用したのがこの画像。斜め向きなので、と、プロンプトを修正して真正面を向かせると今度は前傾感が全く感じられなくなったので、これくらいがいいかな、と。

SD1.5で試してみる
それはそれでいい仕上がりなんで、SDXLならOK、ではあるんですが、これをSD1.5でやってみようとすると、こうなります。
同じプロンプトでの生成です。変更したのはこのあたりだけ。
・Model:v1-5-pruned-emaonly.safetensors
・サイズ(Width x Height):576 x 768
どうなったかというと。。

え?なに?人がいない。。
この理由はよく判らないんですが、SDXLでは問題の無いプロンプトでも、SD1.5には長すぎる、ということなんでしょうね。もう少しシンプルにして描き直した結果がこちら。

人は出ましたが、カウンターに手をついているのは皆無。イメージに最も近いのが右下のものですかね。
これが、Depthを使用するとどうなるか、というところです。
Depthの設定
設定そのものは簡単です。
ControlNetの「Enable」と「Pixel Perfect」をONに。もちろん、Control Typeは「Depth」です。
PreprocessorとModelは、初めに書いた通り、「depth_midas」「control_v11f1p_sd15_depth」です。
その他の設定は上記の通り。標準のままですね。
この設定の後、Single Image に元画像を設定します。
Enableのすぐ下にある、「Allow Preview」にチェックを入れると、設定した画像の右側にプレビュー画面表示領域が現れます。
これらの設定が終わったら、PreprocessorとModelの間にある小さいアイコン「Run preprocessor」をクリックします。

若干時間がかかりますが、プレビュー画面にDepthの陰影が表示されましたね。
手前ほど明るく、奥に行くほど暗くなる、グレースケール画像です。
左手の方が右手よりも明るい、というのが、きちんと認識できている証ですね。
では、画像生成用のメインのプロンプトとネガティブプロンプトを設定します。
pompt
young Japanese woman,
realistic, photo,
standing, leaning forward,
both hands on kitchen counter, upper body leaning forward,
looking at viewer, modern kitchen interior
Negative pompt
sitting, seated, standing straight,
upright posture, side view,
profile, one hand, hands hidden, crossed arms,
extra arms, extra hands, bad anatomy
Depthの設定があるので、メインのプロンプトはこれくらいのシンプルさで大丈夫。
Depthでの出力
画像サイズは 576×768 で12枚生成してみました。

正直、驚きました。
OpenPoseなみにポーズが固定されてますね。
LoRAの適用
ここまで出来るなら、LoRAも適用してみましょう。
プロンプトの1行目に、
<lora:ai_model_v6-000060:0.8>ai_model_v6,
を追加して、再び12枚を生成。
この時に作製したSD1.5用のLoRAです。
それなりに縦方向に大きな画像ですから、顔に崩れは無いんですが、ちょっとLoRAの効きが弱い感じがするので、ADetailerを有効にしてみました。

いい感じじゃないでしょうか。
元画像との比較のため、Hires.fixで 768×1024 に拡大。

やっぱり、手のあたりは違和感があるので完璧とは言えないんですが、SD1.5での生成と考えると上出来では無いでしょうか。
OpenPoseと、どう違うの?
Depthを使えば元画像を高精度で再現できそうです。
…って、OpenPoseとどう違うの?というところ。
ちょっと比較してみましょう。
骨格データは問題なく生成できているようなんですが。。
数多く作るので Hires.fix は外して、576×768 で12枚生成します。

おやおや?
前回のテーマではOpenPoseを絶賛したのに、ちょっと良くないですね。
身体のラインと両手の「位置関係」は骨格モデル通りなんですが、妙なところから左手が出ているのが、12枚中3枚。
特に最初の1枚は、OpenPoseのウィークポイントをまともに表してしまってます。右と左が逆に反映されてるんですね。

それに、プロンプトの
both hands on kitchen counter,
キッチンカウンターに両手を置く、という指示が表現できているのが半分にも満たないんですね。
前回記事作成時の「ベンチに座る」というのが、まったく違和感なく生成できていたので、Depthなんて使わなくても大丈夫じゃないの?と思ってたんですが、「ベンチに座る」と「カウンターに手を置く」の違いが大きかったのが驚きです。
身体の姿勢の指定にはOpenPoseは強いですが、手がカウンターのどこに接触しているか、カウンターとの距離はどれくらいか、といった物体との立体的な位置関係は苦手。というか、そういう情報を持ち合わせていないので無理なんですよね。プロンプト次第というわけ。
ベンチに座る、というのはベースモデルでも多くの学習がされているので再現できるけれども、カウンターに両手を置く、というのは「こういうもの」という画像がないからでしょうね。
壁にもたれる
物体との距離感というところで、壁にもたれかかる姿を作成してみたいと思います。
まずは、SDXLでの元画像作成から。
pompt
photo of a young Japanese woman standing against a wall,
leaning her back and shoulders against the wall,
body weight lightly supported by the wall,
upper body slightly reclined,
looking forward, relaxed posture,
arms naturally at her sides or slightly bent,
front-facing composition, slightly angled stance,
medium full shot, realistic photography,
indoor interior, plain wall
Negative pompt
sitting, seated, crouching, kneeling, lying down,
floating, jumping, walking,
hands hidden, arms crossed behind back,
side view, back view,
extra arms, extra hands, deformed hands, bad anatomy,
wall not visible
SDXLといえども、プロンプトだけでは生成が難しく、数十枚生成して納得いくのはこれだけでした。

この画像を基にして、DepthによるSD1.5の画像を作ってみましょう。
pompt
<lora:ai_model_v6-000060:0.8>ai_model_v6,
young Japanese woman, solo,
realistic photo,
leaning against wall, arms crossed,
looking at viewer, upper body,
indoor, soft light
Negative pompt
multiple girls, multiple people, sitting,
seated, standing straight, away from wall,
hands hidden, extra arms, extra hands, bad anatomy, blurry
これでADetailerを効かせて12枚を生成したのがこちら。

これ、Seedは、-1です。ほぼ同じ画像に見えますけど。。
よく見ると左手の手首から先がおかしなものがいくつかあるものの、全体の姿勢や壁との密着度合いはほぼ同じです。
一方、SD1.5で「プロンプトだけ」で作成するとこうなります。
pompt
<lora:ai_model_v6-000060:0.80> ai_model_v6,
young Japanese woman, solo,
realistic photo, leaning against wall,
arms crossed, looking at viewer,
relaxed expression, indoor, soft lighting
Negative pompt
multiple girls, multiple people, sitting,
seated, standing straight, away from wall,
hands hidden, extra arms, extra hands, bad anatomy, blurry

全体のバランスが悪い画像は少ないものの、「壁に接している」と見えるものは少数ですね。プロンプトだけで期待する画像を生成するのは極めて難しい、と言えるかと思います。
OpenPoseではどうでしょうか。
左手の先が欠落しているのが気になるところですが。。
とはいえ、構造的には楽勝かと思ったんですけどね。

どうしてそうなるの?というくらい、12枚中11枚が、頭部を複数持つ異常な画像でした。
骨格モデルの頭部と身体のバランスが極端に悪いとも思えないので、解釈の破綻が起こるとは考えにくいのですが、プロンプトの1行目(LoRA指定)を削除すると、複数の頭部を持つ画像生成の比率は減りましたので、LoRAが影響を与えていることの可能性は高そうです。
はっきりとした理由は判らなかったのですが、これらの問題を生じさせることなく安定的に意図したポーズの画像が生成できるDepthって思ったよりも使えるんじゃない?と改めて思いましたね。
スマホで自撮り
遠近感をしっかりと出せる、ということを利用して、ちょっと面白い画像を生成してみようと思います。
それは、右腕を前方に伸ばして自撮りをしている画像です。
同じようにSDXLで元画像を生成します。
pompt
selfie photo of a young Japanese woman,
taken with a smartphone held at arm’s length,
one arm extended toward the camera and partially out of frame,
looking directly into the camera,
natural smile, upper body,
slightly wide-angle perspective, close camera distance, realistic photography,
indoor setting, soft natural light, wide horizontal composition,
landscape orientation
Negative pompt
smartphone visible, phone visible, holding visible phone,
mirror selfie, third-person view,
multiple people, extra arms, extra hands,
deformed hands, bad anatomy,
cropped face, blurry
サイズは16:9の横長画像。1280×720での作成です。
SDXLなのでプロンプトが効きやすいこともあるとはいえ、試行錯誤でこんな長いプロンプトとなったんですが、何とか数枚、いい感じの元画像が出来ました。

では、これでSD1.5の画像を生成してみます。
先の2例より、若干不安になる陰影画像ですね。両方の画像を見比べたら、「あぁ、そうか」と思えるものの、陰影画像だけだと、なんだこれ?と。
使用するプロンプトはこちら。
pompt
<lora:ai_model_v6-000060:1>ai_model_v6,
young Japanese woman, solo,
realistic photo, selfie, looking at viewer, smiling,
one arm extended toward camera, upper body,
outdoor, natural light
Negative pompt
multiple people, two girls, smartphone visible,
phone visible, extra arms, extra hands, extra fingers,
deformed hands, duplicate face, extra face, bad anatomy, blurry
このプロンプトで、ADetailerを効かせて12枚を生成したのがこちらになります。

陰影画像での不安が吹っ飛ぶ出来となりました。
プロンプトだけではどうかと、いろいろと試行錯誤してみたんですが、SD1.5では、片手を手前に突き出す、ということ自体が実現できず。全滅でした。
ならばOpenPoseでは?と、こちらに挑戦。
…ですが。
もう、嫌な予感しかしません。
結果はご想像の通り。1枚たりとも腕を前に上げたものは生成できませんでした。
骨格モデルに無いものは、生成AIが補完する、というわけです。

念のために、と、Editで右肘までの骨格を追加してみたものの、この右腕のラインは、肩から左下に向けて伸びる、という平面上の解釈となるため、このようにこちらに向かって伸ばされた腕とはなりません。

このあたりの位置関係の解釈は、Depthに完敗ですね。
というわけで、今回のベストショットはこの1枚に。
Depth使用・ADetailer使用・Hires.fix使用(640×360 → 1280×720)・LoRA使用と、いろいろと盛り込んだ結果です。

右腕が手前に伸びている(スマホで自撮りしている)感が出てるんじゃないでしょうか。
始めるまでは、Depthのありがたみがそれほど判ってなかったんですが、実際に使ってみると、物体の前後関係など、位置関係を適切に再現するには「これが欲しかった」と思えるほど強力な機能でした。
今回は、全て元画像をSDXLから生成しましたが Pexels などで公開されている写真でも問題ありません。というか、実写を元画像にするならさらに現実度が増すと思いますし、いろいろと楽しめそうですね。
Stable Diffusionの環境構築からLoRA作成、SDXLでの検証など、画像生成に関する記事一覧は、以下のまとめページに整理しています。



























