2023-05-21(更新)

「風景+小さい人」のAI絵を作る【Stable Diffusion】

AIは非常に美しい風景を出すことができるが、小さな人をそこに混ぜるのが苦手。少し手間だがこのお題をクリアしてみた。

Article Image

2023/05/21:Photoshopで行う場合のtipsを追加。その他部分的な修正。

前提条件

Stable Diffusion基礎に加えて次の3つの理解は必須

  • ControlNetTile
  • Inpaint機能
  • 外部の画像編集ソフト(無料のGimpでも出来るはず)

Tileについては次で詳しく解説しているので読んでいただければと思う。

【ControlNet(v1.1)】Tile Resampleの解説【Stable Diffusion】 | 謎の技術研究部

画力は無くてOK

実はこれを作る前にScribbleで自分でちょっとキャラを書く方法をやったのだが、下手すぎてキャラが描画できなかった。

少しでも絵心がある人はこちらのほうが早いだろう。

この記事では自分で書き足さなくてもキャラが出てくる方法を紹介する。

今回作る作例(人力タイル法)

今回は1枚の大きな風景の中に、小さいキャラクターを入れる方法を考える。

まずは完成品の例から。風景の左下で女の子が足を湖につけている絵を作った。

作例

このように全体に対してキャラクターの比率が小さい絵の作り方を考えていく。

やり方はこれから解説するが、私はこれを「人力タイル法」と名付けた。

今回は比較的キャラが大きい構図になったが、更に遠くにいる(小さい)キャラクターも作れると思う。

元となる背景に小さいキャラを合成

今回の記事は次の元絵にキャラを合成していく作業だ。

もととなる風景

こちらは次のプロンプトで用意したもの

scenery, silent lake, flower effects, lighting effects,
full color, masterpiece,
Negative prompt: easynegative badhandv4 verybadimagenegative_v1.3
Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 2050940031, Size: 1024x720, Model hash: 099e07547a, Denoising strength: 0.7, Hires upscale: 2, Hires upscaler: Latent

この時既に完成とするサイズまでアップスケールしておこう。

え、小さいキャラいれるの難しいの?

こうやって大きな風景に小さなキャラを入れる、これが結構難しい。

おそらく多くのユーザーがまず最初に考える方法が次

inpaintに任せる(うまくいかないことが多い)

次の方法だとなかなかうまくいかない。

左下をinpaintして(i2iタブにある) https://www.fashion-press.net/news/103344 inpaint

promptを変更。1girl等キャラが出るものにする。

すると

巨大な顔

なにぃこれー!

おおよそこういった良くわからない画像が出てくる。

そして運良くソレっぽいキャラを引けても顔が壊れているケースが殆ど(上の画像も顔がいまいち)

ガチャなので、この方法でも目的のものが出ることがある。

人力タイル法

そこで私は上の画像の一部を切り抜いてもう一度AIにかけていく手法を取っている。

名付けて「人力タイル法」

キャラを入れたい部分だけ切り抜く

まずは外部の画像処理ソフトでキャラを入れたい部分だけピンポイントで切り抜く。

今回はPhotoshopを使用したがGimpなどの無料ソフトでも十分できるはずだ。

切り抜く範囲

後ほどここに画像をはめ込むので、選択範囲の位置とサイズはメモしておく。

私はわかりやすく正方形にすることが多い。

今回元絵に対してかなり大きい範囲を切り抜いたが、場合によっては「表情だけ/手だけ」といった非常に小さい枠で切り抜いても上手くいく。

Photoshopのやり方Tips

Photoshopの場合はスライスツールを利用して書き出し >> Web用...機能によってスライスした部分を取り出せる。

またこのスライス自体が吸着のガイドとして機能するので、選択範囲をおぼえておかなくても画像をドラッグドロップし、そのまま自由変形でピタっとハマる。

もっと良いやり方があるかもしれないので参考程度に。

切り抜いた画像をAIでInpaintして再生成

上で切り抜いた画像をもう一度AIに投げてInpaintする。

inpaintするところ

注意点は2つ

  1. 四隅はinpaintしないこと:はめ込みが戻らなくなるので
  2. ControlNetのInpaintは使わないこと:塗ってない箇所まで色が変わるため

このケースなら元絵の左下のフチを含んで切り抜いているので、左と下の隅はinpaintで塗ってしまってもOK

ここで私はa girl is sitting and dipping her foot in the lakeというプロンプトに変えて足を水につけているキャラクターを生成した。

AIで生成する画像サイズは切り抜いたときと同じサイズ。

この時何度も繰り返して好みのキャラがでるようにする。

生成した画像

ひとまず目的のものが出力された。

顔が微妙かも?

よく見ると、顔の形が微妙によろしくない。

顔などが綺麗に描画できないのはそもそも生成する画像サイズが小さいのが原因

これは意外に知られていない。

というわけで、ある程度キャラが決まったらこれをさらに「大きくアップスケール」することで顔が良くなる。

このときもinpaintのマスクは同じものを利用してアップスケールする。

inpaintアップスケール

inpaintをそのまま引き継げば、四隅は維持されるのでサイズが大きくなっても元の絵にはめ込むことができる。

元のイメージを壊さないようにするにはControlNettileを使ってアップスケールすること。

ControlNet

ControlNet側にも上の絵を放り込んでやることを忘れずに

アップスケール後

大きく変わった訳では無いが、いくらかよくなった。ディティールも増した。

戻したら完成

あとは出来上がった画像を元の画像の位置に戻してやれば完成だ。

作例

inpaintのマスク塗りに失敗していなければ、アップスケールしてサイズが変わってしまった切り抜きパーツも縮小してはめればピタっといく。

記事の最後に更に一歩進んだ作り方も研究

そもそもなんで切り抜いた?

なぜわざわざ切り抜く必要があったのか。

理由は2つある。

画像の中にキャラは大きく描かれる

AIは1枚の画像の中にキャラクターを大きく描こうとする傾向がある。

つまり、風景の中に小さいキャラクターを描かせようとしても大きなキャラクターが出てきてしまう。

これをあえて人力で画像を切り抜くことで「この中に大きくキャラを大きく書いてくれたら良いよ」というのを明示する意味がある。

顔(キャラ)を綺麗に描画したい

上で切り抜かずにinpaintだけで再描画すると、キャラの顔が壊れやすいと書いた。

これはあまり知られていないが、顔を良く描画しようと思うとバストアップだけでも500x500ピクセルぐらいのサイズが必要(これでも細部が足らない顔になる)

1発で風景の中に小さな人を入れようと思ったら風景自体を4kぐらいのサイズで作らないと、そもそも人を美しく描くためのピクセル数が足りない。

ピクセル不足

おそらくこれがキャラクターが綺麗に描かれない原因だ。

かといって最初から4kにしてしまうと処理時間が膨大になるデメリットだけでなく、背景の書き込みが細かすぎてカオスになるというデメリットすらある。

切り抜いて一部だけAIに再描画させるほうが色々と都合が良い。

アップスケールしてもサイズ戻すなら意味ないんじゃ?

このワークフローでは「切り抜き>アップスケールして再生成>画像サイズを小さくして戻す」という手順を踏んでいる。

そもそも大きくしたものを小さく戻すのなら始めから小さいサイズでいいんじゃ?という疑問があるが、試してみるとそうはならない。

始めから小さいサイズで生成したものと、大きいサイズで作った画像を縮小したものを比べると明らかに後者のほうが書き込みが多くなる。

もうちょっと絵を良くしたい

完成絵を見てなにか違和感があった人はツワモノ。

背景とキャラクターを別々で描画したので筆のタッチが合っておらず、別の画家がコラボして1つのイラストを作ったような絵になっている。

もうちょっとなじませる方法が欲しい

ここからは私も研究段階。

全体の絵を馴染ませる方法が二種類あるのでテストも兼ねて掲載する。

ControlNetのInpaintを何も入れずに使う

ControlNetにもInpaint機能があるが、実はこれはマスクが何も入力されていなくても全体をなじませる効果がある。

ControlNetの設定

上で完成となっている画像を更に放り込んで再生成する。

この時、元絵と同じ生成サイズでInpaintを通しただけだと結局顔が壊れてしまうので、少しサイズを大きくする。

今回は1.5倍。Tiled Diffusion+Tiled VAEを使ってVRAMの限界を突破する。

この時Weight=1だと線が壊れる印象があったので0.5に設定

inpaint例

キャラクターを含め塗りが一新され、全体的に統一感が出た。

ただし画風が変わって、少し荒いタッチになったのでこれをヨシとするかどうかが分かれそうだ。

ControlNetのTile Resampleを使う

上とは別にControlNetTile Resampleを使っても全体をなじませる効果がある。

今度はさらに約4kまでのサイズにして実験。

4k tile

Weight=0.8で生成。

これはこれで馴染んだが、大きくしたことにより細部が細かすぎる現象が起きてしまった。

一部の雲が樹木になったり、水の反射が鮮明になりすぎたりという不具合も。

AIにしかできない細かすぎる書き込みの絵と考えれば、好みによってはこちらの方が良いと感じる人もいるだろう。

エクステンションの可能性

実はこの人力タイル法をStable Diffusion内で完結できそうなLLuLというエクステンションがある。

GitHub - hnmr293/sd-webui-llul: LLuL - Local Latent upscaLer

が、現時点でバグ?があるようでマスクの設定ができない。しばらく更新もされていない模様。

Stable Diffusion側の更新でUIが描画できてないように思う。

もしかしたら今後この記事の内容が上でできるかもしれないのでメモとして残しておく。

さいごに

ひとまず目的の小さいキャラクターを入れることはできたと思う。

これはこれで非常に面倒で、他にも答えがあるかもしれない。

引き続き研究していきたい。

何を見せたいかを考えたい

目的は達成したが、今回の作例はキャラを見せたいのか背景を見せたいのか良くわからない構図になってしまった。

特にキャラを端に寄せすぎた。

この例なら真ん中にボートを浮かべてキャラを入れるなどのほうが良かったかもしれない。

ということで、この絵ならいっそ上はクロップしてしまって次のようにしたほうがまだマシかもしれない。

クロップした例

クロップ+夕日の明かりを手塗り+さくらの不自然な映り込み消し等を手で補正して別のバージョン完成。

まだ色々不自然なところはあるが、このへんで。



この記事をシェア


謎の技術研究部 (謎技研)