最近、AIに絵を描かせることにはまっています。自宅のパソコンにStable Diffusionというツールをインストールして、画像を生成しています。
AIを使うと大量の画像を生成することができますが、常に思い通りの画像が生成されるわけではありません。たくさんの画像の中から、たまに「これならいいかも」と思える画像が生成される程度です。
生成される画像を意図した通りに誘導する方法として、Stable Diffusionでは「ControlNet」という拡張機能がよく使われています。最近、このControlNetがバージョンアップしてv1.1になり、一気に機能が増えてしまいました。そのため、どれがどのような効果を持つのかよく分からなくなってしまったので、一通り試してみることにしました。
検証方法
落書き画像を元画像にして、ControlNetで画像を生成させる作業を想定しています。
検証は、以下のように行うことにしました。
- 落書き画像を4パターン用意する。
落書き線画
落書き線画にグレー着色したもの
グレー着色したものに手を書き加えたもの
カラー着色したもの - ControlNetの各機能で9枚づつ画像を生成する。
- 生成された画像を評価する。
評価基準は私個人の主観による独断です。反証不能です。
以下の4段階評価としました。
◎: 大変効果がある。3点
○: 効果がある。2点
△: 効果がないこともない。1点
×:効果がない。0点
以下の8つのControlNetモデルについて検証を行いました。openpose, mlsd, shuffleは今回の検証で想定している落書き絵には使えそうにないので、対象から除外しました。
- canny (Preprocessor: canny, Model: control_v11p_sd15_canny)
輪郭線 - depth (Preprocessor: depth leres++, Model: control_v11f1p_sd15_depth)
奥行き
画像に描かれているものを立体として推測するってことでいいですか? - lineart (Preprocessor: lineart_realistic, Model: control_v11p_sd15_lineart)
輪郭線 - nomal (Preprocessor: normal_bea, Model: control_v11p_sd15_normalbae)
法線抽出
画像に描かれているものの凸凹を推測するということですかね。 - scribble (Preprocessor: scribble_xdog, Model: control_v11p_sd15_scribble)
落書き
落書きのような絵を元にして画像を生成してくれます。 - seg (Preprocessor: seg_ofcoco, Model: control_v11p_sd15_seg)
画像に描かれている物体の領域を推測する。 - softedge (Preprocessor: softedge_hedsafe, Model: control_v11p_sd15_softedge)
輪郭線 - tile (Preprocessor: tile_resample, Model: control_v11f1e_sd15_tile)
画像の描き込みを増やす。
画像を格子状に分割して各格子ごとに処理し、処理した格子を統合することで全体の描き込みを増やすということをやっているようです。格子に分割するので「tile」ってこと?
生成パラメータは以下の内容で固定しました。Control WeightとEnding Control Stepは変更すると絵柄が大きく変わってしまうのですが、経験的にうまく動いてくれている値に設定しました。
- モデル: Counterfeit-V3.0
- プロンプト: 1 girl
- ネガティブプロンプト: EasyNegativeV2
- ContorolNet
Control Weight: 0.6
Starting Control Step: 0
Ending Control Step: 0.5
結論
落書きから画像を生成させる場合、softedge, tile, scribble を使うと良さそう。
(検証1) 落書き線画
まず、こんな画像を用意しました。
お地蔵さんじゃありません。これは「girl」です。こんなお地蔵さんの一体どこが「girl」なんだなどと疑いを持ってはいけません。「girl」なんです。
検証1では、人物の大きさ、顔の向きが生成された画像に反映されるかどうかをポイントに評価していくことにします。
(検証1生成結果) canny
× | × | ◎ |
△ | × | × |
× | ◎ | × |
評価: 7点
(検証1生成結果) depth
× | △ | △ |
× | △ | ◎ |
× | ○ | ◎ |
評価: 11点
(検証1生成結果) lineart
◎ | △ | × |
△ | × | × |
◎ | △ | △ |
評価: 10点
(検証1生成結果) nomal
normalはこういう落書き線画には合ってないっぽいですね。
× | × | × |
△ | × | × |
× | × | △ |
評価: 2点
(検証1生成結果) scribble
結構いい感じに生成されていると思います。
◎ | △ | × |
◎ | ◎ | × |
◎ | × | ◎ |
評価: 16点
(検証1生成結果) seg
予想はしていたのですが、やはりsegはこういう落書き線画にはあまり合わないようです。
× | × | × |
× | × | × |
× | △ | × |
評価: 1点
(検証1生成結果) softedge
元画像の線を忠実に拾っているようです。
◎ | △ | △ |
× | × | × |
◎ | △ | ◎ |
評価: 12点
(検証1生成結果) tile
元画像が認識できているような、いないような。よく分からないですね。
× | × | ◎ |
× | × | △ |
× | × | ◎ |
評価: 7点
(検証1まとめ)
落書き線画では、1位 scribble、2位 softedge、3位 depthという結果となりました。
(検証2) 落書き線画をグレー着色
グレーに着色し、ちょっと書き込みを増やしてみました。
頭部に増やしたものは髪の毛です。髪だと思ってください。AIだってきっと髪だと思ってくれるはずです。
検証2では、人物の大きさ、顔の向きに加えて、視線の向きと髪の造形も加味して評価していくことにします。
(検証2生成結果) canny
○ | × | ○ |
△ | × | ○ |
◎ | ◎ | △ |
評価: 14点
(検証2生成結果) depth
◎ | ○ | × |
◎ | × | × |
◎ | △ | △ |
評価: 13点
(検証2生成結果) lineart
なかなかいいんじゃないでしょうか。
○ | ○ | ○ |
○ | ◎ | × |
△ | × | × |
評価: 12点
(検証2生成結果) normal
なんか関係ない絵になっています。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証2生成結果) scribble
これもなかなかいいと思います。
△ | × | △ |
◎ | × | × |
○ | △ | ◎ |
評価: 11点
(検証2生成結果) seg
やっぱりsegはこういう元画像に向いてないみたいですね。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証2生成結果) softedge
元画像が強く反映されています。
○ | ○ | ○ |
◎ | ○ | ◎ |
○ | ○ | ○ |
評価: 20点
(検証2生成結果) tile
検証1ではイマイチだったtileですが、検証2の中では一番いいですね。
○ | ◎ | ◎ |
○ | ○ | ○ |
◎ | ◎ | ◎ |
評価: 23点
(検証2まとめ)
今回は1位 tile、2位 softedge、3位 cannyとなりました。
グレーに着色するだけで、どのモデルも画像の認識度が上がったような気がします。(normalとsegは除く。)
視線と口の形状については、あまり反映されませんね。このあたりはプロンプトで指定したほうがいいかもしれません。
(検証3) 落書き線画に手と服を追加
AIが苦手とする指を描き込みました。
検証3では、指の造形も評価の対象に加えることにします。
(検証3生成結果) canny
手がうまく生成できていると思います。
○ | × | ○ |
○ | ◎ | ○ |
○ | △ | △ |
評価: 15点
(検証3生成結果) depth
元画像をあまり認識できていないようです。
× | × | △ |
× | △ | △ |
× | △ | × |
評価: 4点
(検証3生成結果) lineart
手がうまく生成できていると思います。
○ | ○ | ○ |
○ | ○ | ○ |
△ | ◎ | ◎ |
評価: 18点
(検証3生成結果) normal
元画像がうまく認識できていないようです。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証3生成結果) scribble
全体的にいい感じです。
○ | ○ | △ |
○ | × | ◎ |
○ | △ | ◎ |
評価: 16点
(検証3生成結果) sed
元画像が認識できていないようです。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証3生成結果) softedge
かなりいいですね。
◎ | ○ | ○ |
○ | ○ | ○ |
○ | ○ | ◎ |
評価: 20点
(検証3生成結果) tile
安定していい感じです。
○ | ○ | ○ |
○ | △ | ○ |
△ | ○ | ○ |
評価: 16点
(検証3まとめ)
今回は1位 softedge、2位 lineart、3位 scribbleとtileになりました。
指の造形については、canny, lineart, softedge の輪郭線系がいいですね。輪郭線系ではないscribbleとtileも結構うまく生成してくれています。
(検証4) 落書き線画をカラー着色
色を付けました。
検証4では、色が反映されるかどうかも評価の対象に加えることにします。
(検証4生成結果) canny
造形については元画像を強く反映している思います。元画像の色は反映されていません。元画像から輪郭線情報しかとっていないので仕方ないですね。
× | × | ○ |
○ | ○ | ○ |
○ | × | △ |
評価: 11点
(検証4生成結果) depth
元画像が認識できなくなってしまったようです。プロプロセッサをdepth leres++以外のものにした方がよかったのかな?
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証4生成結果) lineart
造形については元画像を強く反映していると思います。canny同様、元画像の輪郭線情報しかとっていないので、色は反映されていません。
○ | ○ | ○ |
○ | ○ | ○ |
○ | ○ | ○ |
評価: 18点
(検証4生成結果) normal
元画像がきちんと認識できているように見えません。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証4生成結果) scribble
造形はいいと思います。scribbleも元画像の色は取得していないんですね。
○ | ○ | ○ |
○ | ○ | ○ |
○ | ○ | ○ |
評価: 18点
(検証4生成結果) seg
元画像が全く認識できていないようです。
× | × | × |
× | × | × |
× | × | × |
評価: 0点
(検証4生成結果) softedge
造形は非常にいいと思います。softedgeも元画像から色情報を取得していないので色は反映されていません。
○ | ○ | ○ |
○ | ○ | ○ |
○ | ○ | ○ |
評価: 18点
(検証4生成結果) tile
髪色がピンクになっちゃいましたが、元画像の色の反映がされているようです。造形もいいですね。
○ | ○ | ○ |
○ | ◎ | ○ |
○ | ○ | ○ |
評価:19点
(検証4まとめ)
1位は元画像の色が反映されるtileとなりました。lineart、scribble、softedgeの3つが同率2位です。
総評
(検証1) | (検証2) | (検証3) | (検証4) | ||
落書き線画 | グレー着色 | 手を追加 | カラー着色 | 合計 | |
cany | 7 | 14 | 15 | 11 | 47 |
depth | 11 | 13 | 4 | 0 | 28 |
lineart | 10 | 12 | 19 | 18 | 59 |
normal | 2 | 0 | 0 | 0 | 2 |
scribble | 16 | 11 | 16 | 18 | 61 |
seg | 1 | 0 | 0 | 0 | 1 |
softedge | 12 | 20 | 20 | 18 | 70 |
tile | 7 | 23 | 16 | 19 | 65 |
全体1位はsoftedge、2位 tile、3位はscribble、僅差でlineartが4位となりました。
softedgeは元画像の形状を正確に反映して画像を生成してくれるので、清書に向いていると思います。
tileは形状だけでなく色も反映してくれるので、今回検証に使用したような落書き線画に対しては、総合的に一番向いているのではないかと思いました。
scribbleは元画像の意図を推し量ったかのように、いい感じの画像を生成してくれるので、なかなか面白いと思いました。アイデアを広げるのにいいかもしれません。
lineartとcannyは線画着色用と考えた方がいいかもしれません。元画像の輪郭を忠実に取得してくれるので、きちんと書き込まれた線画に着色する場合や色を変更する場合に向いているかもしれません。
depthはもっと効果があるのではないかと思っていたのですが、途中で失速してしまいました。プロプロセッサのdepth leres++が元画像に合わなかったのかもしれません。これについては再検証してみたいですね。
normalとsegは今回のような落書き線画には向かないようです。
Multi ControlNetという、複数のControlNetを同時に組み合わせて使う方法もありますので、元画像に合わせていろいろな組み合わせを試してみるのも良いかもしれません。
おまけ
Multi ControlNetでtileとlineartを使って、画像の解像度を上げてみます。
検証4のtileで生成されたこの画像を使うことにします。
解像度を上げたものがこちらです。視線と口はプロンプトで指定しています。
こっ、これは……
完全に一致! (おいおい!)
それでは。