Stable Diffusionを使ったイラスト作成の記録(4) ~ 透過PNGによるimage to image ~
前回の記事
シリーズ一覧
Layered Diffusion Pipelineを使うためのリンク集
ライブラリの入手先と使用法(英語) : Githubリポジトリ
日本語での使用方法の解説 : Noteの記事
イラストが白っぽい?
これまで生成した画像を見返して、画像が全体的に白っぽいことに気づきました。例えば校庭が白かったり、制服の下半分が白くなったりというパターンが多く見られました。
その理由を考えるに、下絵自体に白い部分が多く含まれているため、それが生成画像に影響を与えているのではないかと思いました。むしろ、白だけが無視されるはずがないので、確実に影響を与えているはずです。
対策として、背景色を白以外にするのは、どんな背景色を選んでも、その色に生成画像が影響されるので、根本的な解決にはなりません。かといって、背景色が残らないように全部塗りつぶすのは、下絵を描く手間が増えるので望ましくありません。
透過色の利用
それならば、いっそのこと背景色に何か指定する代わりに透過色にして、透過PNGとして下絵を保存してしまえばどうでしょうか?
残念ながら、通常のimage to imageは、透過色をサポートしていません。そこで、新たに透過色を取り扱えるように下のような変更を加えました。
画像のαチャンネルを、マスク画像として読み込む
色の設定されていない部分(透過部分)は、乱数初期化する
複数の下絵の重ね合わせを可能にする
透過色を有効にした下絵
下絵の背景色を透過色に変更すると、次のようになりました。
これを読み込むと、次のような入力画像とマスク画像として処理されます。
画像生成の結果
スクリプトは、2回目のスクリプト(2-1)と基本的に同じですが、パイプラインのパラメータが変更された部分だけ変更されています。
# スクリプト(4-1)
images = pipe(
initialize=ByImage(
image="schoolgirl.png",
strength=0.9,
),
iterate=[
Layer(
prompt=("high school, school ground, school building, cherry tree, "
"blue sky"),
negative_prompt="1girl",
),
Layer(
prompt="1girl, solo, high school, school uniform",
negative_prompt="",
mask_by="schoolgirl_mask.png",
),
],
num_steps=30,
size=(512, 512),
)
生成された画像はこちら。
全体として、白っぽい部分が少なくなり、画像の書き込みもより細かくなったようです。
下絵のブレンドも試す
さらに、透過PNG下絵を使って、前回おこなった下絵のブレンドを試してみました。使用したスクリプトは前回のスクリプト(3-1)とほぼ同じですが、パラメータが少しだけ違います。
# スクリプト(4-2)
images = pipe(
initialize=ByImage(
image="schoolgirl.png",
strength=[strg(0.9, level=1.0), strg(0.7, level=0.4)],
),
iterate=[
Layer(
prompt=("high school, school ground, school building, cherry tree, "
"blue sky"),
negative_prompt="1girl",
),
Layer(
prompt="1girl, solo, high school, school uniform",
negative_prompt="",
mask_by="schoolgirl_mask.png",
),
],
num_steps=30,
size=(512, 512),
)
生成された画像はこちら。
先ほどと同様に、画像の白っぽさが少なくなり、主に背景の書き込みも細かくなったようです。しかし、女子学生の絵の質はあまり大きな変化はないようです。下絵に人物部分の透過が少ないため、影響が少なかったのかもしれません。
まとめ
手書きの下絵を使ってimage to imageで画像生成を行う場合、背景色の選択が生成画像に強い影響を与えます。
これを避けるため、背景色を透過色にして下絵を透過PNGとして保存し、透過部分を乱数初期化することで、背景色の生成画像への影響をなくすことができました。