ADetailer・OpenPose・DepthはSDXLでも有効? 実際に試して確認 ~ 画像生成AI実験メモ ⑧

いろいろと機能を理解していくと、Stable Diffusion で画像を生成するにあたって、困っていたことが、かなり改善されてきました。

一つが、画像を小さくした際の顔の崩れ。これは ADetailer を使用することで劇的に改善できています。

次いで、「思ったとおりの構図にならない」という問題。

これは、「こんなポーズにしたい」という元画像をインプットすることで、骨格モデルを抽出し、作成する画像に適用する OpenPose や、遠近感を意識することで手前に飛び出すような画像を生成できる Depth などで、造りたい画像がかなり生成できるようになってきています。

とはいえ、これらは SD1.5 モデルでの話。

SDXLで試すとどうなるのか、ということを実際にやってみました。

というか、そもそもSDXLでも必要なの?というところから、ですかね。

本記事に掲載している人物画像は、すべて生成AIにより作成したものであり、特定の実在人物をモデルにしたものではありません。

ADetailer

まずは、ADetailer。SD1.5だと、512×512で最適化された学習画像での生成となるため、ちょっと視点を引いた画像で顔が小さくなったりすると、顔を構成するピクセル数が減るので、簡単に顔崩れが発生してしまいます。

このあたりの仕組みは、ここに記載しています。

一方で、SDXLはというと、1024×1024というSD1.5よりは広大なキャンバスになりますから、同じような大きさの顔でも、比較的崩れは起きにくいのかな、と思います。

実際に確認してみましょう。

プロンプトだけで生成

使用するプロンプトは、こちらに記載のある、最後に出力したものをそのまま使用します。LoRAだけは、その後に作成しなおした別物となります。

これで、1024×576という16:9の画像を12枚生成してみます。

LoRAの特徴を出しているかどうか(学習画像と似ているかどうか)は別とすると、明らかに顔が崩れている画像は無いんですね。

試しにあと3セット、36枚を同じプロンプトで生成してみましたが、顔のパーツの位置や向き、大きさがアンバランスなものは一つもありませんでした。

これはある意味、「SDXLはすごい」、ということかと思いますが、これでは記事が成り立たないので、意図的にもう少し顔を小さくしてみようと思います。

プロンプトの、「upper body」を「full body」に変えて、足先まで意識させるために「mountain climbing shoes」と追加してみました。

…が、なぜか途端に後ろ向きの画像が増えてしまって、顔が鮮明なものは足先まで写らないけれどもこちら向き、全身のものは向こう向きで顔が写らず、という参考にしにくい結果に。生成時に顔が小さいので顔の見えにくい向きに逃がす、ということが起こり得るのかも、というところです。

なので、

prompt
three-quarter view,
body turned slightly to the side,
face turned toward camera,

この3行を、

prompt
facing the viewer,
looking at the viewer,
front-facing face

としてみました。

プロンプトに追記した割に、意外と全身のものが少なかったんですが、ようやく期待していたものが出ました。

縦576ピクセルで全身ですから顔(髪を含まず顎まで)の高さが64ピクセルでした。ここに精細な顔の情報を載せるのは難しかったということでしょう。

というか、「オレたちひょうきん族」のキャラ、鬼瓦権蔵おにがわらごんぞうに見えてしまうのは、世代の問題でしょうか。

それはともかく、ようやく顔崩れの画像が出たので、ADetailerの出番です。

ADetailerを併用

設定すべき項目は、SD1.5のときとほぼ同じです。この記事内に記載しています。

検出モデルは、SDXLでもSD1.5と同じ「face_yolov8n.pt」でOKです。

自動検出された領域に対して再描画するためのプロンプト/ネガティブプロンプトも、SD1.5のときと同じ。もちろん、LoRAの指定はSDXL用のものに変更しています。

ADetaier prompt
<lora:ai_model_sdxl_b1-000180:0.9> ai_model_sdxl_b1,
same face, detailed face, natural eyes, gentle smile, realistic face

ADetaier negative prompt
bad face, deformed face, asymmetrical eyes, bad eyes, distorted mouth, blurry, low quality

Use separate width/height は、検出した領域を再描画するときの処理解像度ですが、せっかくのSDXLですし、1024×1024にしておきます。処理時間が厳しいようであれば、落としても構わないかと思います。

変更したのはこれくらいです。

で、同じSeed値で再度生成してみます。

…なんですが、生成された画像は、全く同じ鬼瓦権蔵の顔。

生成の様子をよく見ていると、顔検知の青枠表示の後、補正された画像が表示される領域が、真っ黒になっています。要は、補正後の画像が生成されていない、ということですね。

いろいろ試行錯誤して辿り着いたのがこちら。

デフォルトのチェックOFF「Use Same VAE」ではダメで、「sdxl_vae.safetensors」を指定して、ようやく解決できました。

使用しているLoRAは、この記事で作成したものです。

avr_loss=nan 問題の対策として、VAEに sdxl_vae.safetensors を指定して作成したLoRAですから、この問題が発生したのだろうと思います。

顔部分の再描画にはこのVAEの明示指定が必要だった、ということですね。恐らく、多くの方は、fp16対策が行われているモデル(チェックポイント)でLoRAを作成されているかと思いますので、今回のようなADetailer が効かない、という問題は発生しないかもしれません。発生の際は、このあたりをチェックしてみてください。

というわけで ADetailer を効かせた画像がこちら。

お見事です。

もう1枚くらい、確認しておきましょうか。

この写真も、よく見るとかなり崩れています。

同じように、ADetailerを有効にして再生成。

これは、ADetailer denoising strength を 0.4 のまま実行した結果です。まだ、左目の崩れが残ってますね。そういう時は、このパラメータを少し増やします。0.5 で実行しました。

こんな感じで、補正ができます。

顔の小さい画像には、SDXLであってもADetailerは有効ですね。

OpenPose

続いては、OpenPose。

後で紹介するDepthもそうですが、OpenPose用の元画像を、このSDXLで生成しているものがあるんですね。つまりは、OpenPoseを使わなくても出せるんじゃないか、と。

とはいえ、狙ったポーズの画像を、「安定して何枚も」出せるかというと、OpenPoseを使用しないと厳しいはず。

というわけで、OpenPoseとDepthに関しては、何枚出せるか、という観点から見ていきたいと思います。

プロンプトだけで生成

使用する題材は、

この中で使用した最後(4例目)のもの。

プロンプト(ネガティブも)は使用したものをそのまま使用します。LoRAの指定だけは変えています。

パラメータ類はSDXL用に、
・Model:sd_xl_base_1.0.safetensors
・Sampler:DPM++ 2M SDE
・Schedule type:Karras
・Sampring steps:30
・CFG Scale:5
・Seed:-1
・サイズ(Width x Height):1024 x 576
としました。

まずは、プロンプトだけで生成。Seed値をランダムにしてますので、12枚を一気に生成します。

概ね予想通りではあるんですが、さすがはSDXLですね。

SD1.5ではプロンプトだけではしゃがむ姿勢の生成が3割も出来なかったんですが、SDXLでは半数強がしゃんでいます。膝を立てて座る、いわゆる三角座りになるものが一定数出てくるのはSD1.5と同じですね。

イメージした「しゃがむ」ポーズを生成するには、やっぱりOpenPoseが有効なんでしょうか。

では、OpenPoseを使用してみましょう。

OpenPoseを併用

SDXLの場合も、基本的な設定はSD1.5と同様です。

但し、Preprocessorは dw_openpose_full で同じですが、OpenPoseのモデルは SD1.5 用ではなく SDXL用を使用する必要があります。

controlnet-openpose-sdxl-1.0 を使用することになるのですが、Hugging Face からダウンロードできます。

https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0

「Files and Versions」タブにあるファイル一覧から、diffusion_pytorch_model.safetensors を選び、Downloadアイコン(↓)を押します。

ファイル名が、controlnet-openpose-sdxl-1.0 ではありませんので、注意が必要ですかね。

取得したファイルを下記のフォルダに格納します。

stable-diffusion-webui
└─ extensions
   └─ sd-webui-controlnet
      └─ models
         └─ diffusion_pytorch_model.safetensors

OpenPoseに関するパラメータは、SD1.5と同様です。モデルだけをSDXLに差し替えただけですね。

骨格モデルに使用したのは、SD1.5のときのと同じ、Pexelsから頂いた画像。

ポーズ参考画像:Pexels

では、同じく12枚を生成してみましょう。メインのプロンプト・パラメータは OpenPose を使用しないときと同じものにしました。

いくつか足の造りがおかしなものがあったり、手の出方がおかしかったりするんですが、概ねOpenPoseの骨格モデル通りとなっています。SD1.5とは違い、画像サイズが大きいこともあって大きな顔の崩れはなく、ADetailerの併用は行っていません。

ただ、全身のポーズを見ると悪くは無いんですが、手の位置・向き等は、再現が難しい骨格モデルだったかもしれないですね。

とはいえ、身体の向き、画像内での位置、しゃがむというポーズは、元画像を忠実に再現できているのではないでしょうか。

SDXLだけあって顔の崩れは無いものの、LoRAの効きがちょっと弱いかな、ということで、最後にADetailerを効かせた12枚を生成してみました。

全ての画像で、若干の強弱はありますが、LoRAが効いていると言えるかと思います。

この中から代表して1枚。

しゃがんだ姿勢と手の位置、顔の表情もベストなものになったのではないでしょうか。

こんな感じで、元に出来る画像があれば、SDXLでもOpenPoseは十分に有効だと言えると思います。

Depth

最後はDepthです。

これも、なかなか「どう活用すればいいの?」と思われる方が多いのではないかと思いますが、手を「前に出す」とか、奥にもたれかかるとか、奥行きのある画像の生成には役立つものです。

プロンプトだけで生成

SD1.5での実験はこちらですね。

このときも、元画像の生成にSDXLでのプロンプトだけでの画像を使用しましたので、SDXLならDepthはいらないんじゃないの?という感じもするんですが、この記事を作成した時のプロンプト・ネガティブプロンプトにLoRAの設定を追加して、パラメータはOpenPoseのときと同じもので12枚生成。

あれ?こんなに自撮り画像って出なかったでしたっけ?

12枚のセットを何度か生成してみるも、自撮りをしているかのように腕を上げているものは皆無。

プロンプトの効きを強めるためにCFG Scaleを上げてみても改善の兆しなし。

おかしいなぁ、と思ってこのテーマを書いたときの生成画像を見てみると、元画像を生成するのが目的なのでLoRA設定はなかったんですね。それでプロンプトからLoRAの指定を外してみると、こんな感じに。

12枚中、理想とするものは最上段2枚目のもくらいですね。12枚中1枚だけ。

当時の陰影画像生成時の画像(下に掲示)を見返してみると、12枚中4枚くらいが使えるかな?というものだったので、ここまで低頻度だと思ってなかったんですね。結構偶然だったのかもしれないです。使用したのは最上段左の画像でした。

LoRAの作り方次第かとは思いますが、プロンプトだけでの自撮り再現が難しい以上、Depthは使えるかも、という気がしてきました。

というわけで、Depthを使用してみます。

Depthを併用

SDXLの場合も、基本的な設定はSD1.5と同様です。

Preprocessorは depth_midas で同じですが、Depthのモデルは SD1.5 用ではなく SDXL用を使用する必要があります。

diffusers_xl_depth_full.safetensors を使用することになるのですが、このファイルも Hugging Face からダウンロードできます。

https://huggingface.co/lllyasviel/sd_control_collection/blob/main/diffusers_xl_depth_full.safetensors

「Files and Versions」タブにあるファイル一覧から、diffusers_xl_depth_full.safetensors を選び、Downloadアイコン(↓)を押します。

こちらはOpenPoseと違って、同名のファイルですね。

取得したファイルを下記のフォルダに格納します。

stable-diffusion-webui
└─ extensions
   └─ sd-webui-controlnet
      └─ models
         └─ diffusers_xl_depth_full.safetensor

Depthに関するパラメータは、SD1.5と同様です。モデルだけをSDXLに差し替えただけですね。

陰影画像に使用したのはSD1.5のときと同じもの。

これで12枚を生成してみます。

何となく、おや?という結果に。

まず、背景が揺らめいてしまってます。それと、LoRAを効かせているのに、顔も元画像から引っ張られ過ぎですね。

SD1.5と違って、Depthの効きが強すぎるんでしょうか。袖のしわまでが忠実に表れてますからね。

というわけで、ControlNetの Control Weight を 1から0.5にまで下げてみました。

ほどよく抑えられたのではないでしょうか。

0.4や0.3にすると、右腕の飛び出し感が落ちてきたので、元画像にも依るでしょうが、この画像なら0.5くらいが程よい感じになりました。

ただ、これだけ顔が大きいのに、なんとなくLoRAと違う感があって、このあたりが元画像に引っ張られてるのかな、と。

なので、画像生成の終盤(顔の細部が詰まる頃)にまでControlNetの影響を引っ張らないように、Ending Control Step を 0.6 に下げてみます。

顔の表情は先ほどのものよりはLoRAの効果が上がっているのではないでしょうか。

とはいえ、それを確実にするには、ということで、ADetailerでの仕上げを追加して再生成してみました。パラメータは前述と同じものを使用しています。

画像生成後の顔補正ですからDepthの陰影画像にも直接の影響を受けずに(元がDepthによって影響を受けた顔ですので、ゼロからのスタートではありません)、安定した顔になりましたね。

では、この中から代表して1枚。

Depthの重みを下げたことで、右肩が下がって見えてしまうものも出てきましたが、そのあたりは何度か試行錯誤してもらえらば良いかと思います。それでこそのローカル生成ですからね。

というわけで、意外にもSDXLでは惨敗だったLoRAありの自撮り画像もDepthを使うことで、無事に生成できました。

これまで、SD1.5での生成に関するテーマをいくつか書いて来ましたが、実際のところプロンプトへの追従性や画質の面からも、SDXLを使用する機会が増えてきています。

とはいうものの、ADetailerやControlNetのOpenPose、DepthがSDXLでどれくらい有効なのかを、これまできちんと検証したことはありませんでした。そこで今回は、それらをテーマとして試してみました。

顔つぶれにADetailerが有効であることはよく判りましたし、OpenPoseやDepthについても、それぞれの得意分野を理解して使えば、SDXLでも十分に有用であることが確認できました。

プロンプトだけで完結させるのが楽ではあるんですが、思い描いた画像を生成するためには、ちょっとした手間も必要になります。プロンプトだけで何度も生成を繰り返し、その中から使える、あるいは思い描いたものに近い画像を探すよりは、こうしたツールを使った方が近道になることも多いと思います。ぜひ必要に応じて活用してみてください。