【Stable Diffusion 2.0】ローカルで動かして顔写真／風景写真をアニメ風に変換してみた【アバター生成】【img2img】

# やりたいこと

今年画像生成AIとして大注目された「Stable Diffusion」のバージョン2.0を使って何かできないかなと考えていました。
今回は「Stable Diffusion 2.0」をローカルで動かして、以下タスクの実験を行いました！

- **顔写真を入力し、アニメ風のアバターを生成する**
- **スナップ写真を入力し、アニメ風の風景写真に変換する**

:::note info
**この記事のポイント**
img2imgタスクを利用して、「Stable Diffusionでアニメ風の画像変換できるのか」確かめてみました。
:::

:::note warn
現時点では最新バージョンは2.1ですが、画像生成の不具合により2.0で検証しています。2.1でも同じ手順で生成できます。
:::

---

ローカルでStable Diffusion 2.0を動作させるにあたり、以下のサイトを参考にさせていただきました。

Stable Diffusion 2.0で追加された機能を試してみよう／＠IT

https://atmarkit.itmedia.co.jp/ait/articles/2212/02/news021.html


Google Colab で Stable Diffusion 2.1 を試す - diffusers版 ／npaka 

https://note.com/npaka/n/n1f4e2bcad037


---

# 動作確認環境
以下の環境で動作することを確認しました。

| 項目 |  |
|:-:|:--|
| OS  | Windows 10 ver 22H2 |
| CPU  | intel Core i7-7700  |
| GPU  | NVIDIA GeForce RTX 2080 Ti (VRAM 11GB) |
| メインメモリ | 16GB  |
| CUDA | 11.0 |
| Python  | WinPython 3.8.7  |
| Diffusers  |  0.10.2 |
| PyTorch  | 1.12.1+cu113 |

---

# 0. ライブラリのインストール

まずは、Stable Diffutionを動かすために必要なPythonのライブラリをインストール、更新します。

```bash
pip install --upgrade diffusers[torch]
pip install --upgrade git+https://github.com/huggingface/transformers/
```

:::note info
**diffusers**とは
既に学習された画像生成などの「拡散モデル」を簡単に呼び出し実行ができるライブラリです。HuggingFaceというサイトを通じて学習したモデルを配布することもできます。
画像生成だけであれば、ほんの数行で実行できます。
:::

---

# 1. 【txt2img】Stable Diffusion 2.0をローカルで動かすプログラム

## 1.1 実装

以下のコードを実行すると、好きな英文から画像を生成させることができます。
通常の写真と同じアスペクト比になるよう、`1024x768`のサイズで出力しています。

:::note info
**ポイント**
初めて実行するときは学習済みモデルをダウンロードするため、少し時間がかかります。
:::


```python
import torch
from diffusers import StableDiffusionPipeline, EulerDiscreteScheduler
from torch import autocast
 
MODEL_ID = "stabilityai/stable-diffusion-2" # HuggingFaceのモデルID
DEVICE = "cuda" # 利用するデバイス

scheduler = EulerDiscreteScheduler.from_pretrained(MODEL_ID, subfolder="scheduler")
pipe = StableDiffusionPipeline.from_pretrained(
    MODEL_ID,
    scheduler=scheduler,
    torch_dtype=torch.float16,
    ) # 推論のパイプライン

pipe = pipe.to(DEVICE) # GPUへ転送
pipe.enable_attention_slicing() # GPUのメモリ制限によるフローを回避

i = 0
with autocast(DEVICE):
    while True: # 中断するまで画像生成を繰り返すことができます
        prompt = input("input prompt: ") # 生成させたい画像の説明を入力
        # prompt = "a photo of an astronaut riding a horse on mars" # サンプル
        image = pipe(prompt, height=768, width=1024).images[0]
        image.save(f"test_{i}.png")
        i += 1

```


Diffusersには学習済みモデルで推論させるためのパイプラインが備わっているので、特別難しい処理は記述する必要がありません。

---

## 1.2 画像生成結果

サンプルの「a photo of an astronaut riding a horse on mars」（火星で馬に乗る宇宙飛行士の写真）を入力した結果です。

Stable Diffusion 1.0よりも非常にリアルに生成できているように感じます。
**もはや壁紙にしたいですね。**

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/399f9861-88b6-f648-2e7d-9b0ec5696dc2.png)

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/3c27efaa-137c-98c1-88ce-c1cdac241d77.png)

:::note info
**画像生成時間の目安**
1024x768の生成には、RTX 2080 Tiで一枚当たり18秒ほどかかりました。
:::

---

# 2. 【img2img】Stable Diffusion 2.0で画像変換するプログラム

diffusersの最新版にはimg2imgタスクのパイプラインも同梱されています。上記のtxt2imgのプログラムを少し変えるだけで、画像変換できるようになります。


```python
import torch
from torch import autocast
import PIL
from PIL import Image
import numpy as np
import os
from diffusers import EulerDiscreteScheduler, StableDiffusionImg2ImgPipeline
import os
 
def preprocess(image): # 入力画像のデータ整形
    w, h = image.size
    w, h = map(lambda x: x - x % 32, (w, h))
    image = image.resize((w, h), resample=PIL.Image.LANCZOS)
    image = np.array(image).astype(np.float32) / 255.0
    image = image[None].transpose(0, 3, 1, 2)
    image = torch.from_numpy(image)
    return 2.0 * image - 1.0


MODEL_ID = "stabilityai/stable-diffusion-2"
DEVICE = "cuda"

scheduler = EulerDiscreteScheduler.from_pretrained(MODEL_ID, subfolder="scheduler")
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
    MODEL_ID,
    scheduler=scheduler,
    torch_dtype=torch.float16,
    )

pipe = pipe.to(DEVICE)
pipe.enable_attention_slicing() 

generator = torch.Generator(DEVICE).manual_seed(2022) 

i = 0

with autocast(DEVICE):
    while True:
        prompt = input("input prompt: ") # 変換後の画像の説明を入力
        init_image_file = input("input init-image file:") # 入力画像のパスを入力
        
        if not os.path.exists(init_image_file): continue
        
        init_image = Image.open(init_image_file).convert("RGB")
        init_image = init_image.resize((1024, 768))
        init_image = preprocess(init_image)

        strength = 0.75
        guidance_scale = 9
        num_generate = 3

        for _ in range(num_generate): # 同条件で複数枚生成する
            image = pipe(
                prompt=prompt,
                image=init_image,
                strength=strength,
                guidance_scale=guidance_scale,
                generator=generator,
            ).images[0]

            image.save(f"generated_{i}.jpg")
            i += 1
```

---

# 3. 本題：Stable Diffusionで顔写真からアニメ風のアバターを生成してみよう


今回も、おなじみ「ぱくたそ」さんから以下の方の顔写真を利用しました。
身に着けているものや、写真内の顔の大きさや角度をバラバラにしています。果たしてこの方たちをアニメ風のアバターに変換したらどうなるのか。。。Stable Diffusionは日本のアニメを知っているのか...？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/303753a2-c4a6-464a-9458-42ef10425a2e.png)

---

変換先の文章は、Stable Diffusion 2.0がその作品を知っているかどうかに限らず、 **「Face of Character in "アニメ作品(英語名)"」** （＜アニメ作品＞に登場するキャラクターの顔）というように、特定のアニメ作品を指定して画像変換させてみました。
もしStable Diffusion 2.0がその作品を知っていれば、その作品に出てくるキャラクターのような作画のアバターになるはずです。

**それでは、結果を見てみたいと思います！！その作風を反映できたものをいくつか紹介します。**

:::note warn
**記事の筆者（私）が作画・作風が分かる範囲内でのアニメ作品を指定して画像生成している**ため、ご存じない方や、他のアニメ、映画などで試したい場合はぜひ試してみてください。

:::

:::note info
**画像生成時間の目安**
アバター画像（512x512）の生成には、RTX 2080 Tiで一枚当たり5秒ほどかかりました。
:::

---

## 1)「進撃の巨人」

:::note info
何枚か同じ写真で生成し、うまく生成できたものを抜粋して掲載しています。

:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/d659c630-173b-28d1-8f33-71b9d2e86c7b.png)

ジェンダー平等を考慮し、性別などは文章で指定していないため見た目が変わる可能性もありますが、髪型や身に着けているもの、服の色をよく反映したキャラクターが生成できています。**サンタ帽も一応「赤い被り物」として認識しているようです。笑**
**普通にこの人たちが巨人と戦ってほしい。巨人側の見た目をしたアバターになることも...？**

---

## 2) 「鬼滅の刃」


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/9c204147-8fd6-689f-6bc9-866aecbd18ce.png)

特に一番左の方のアバターは鬼滅の刃に出てきそうですね。サンタ帽の方は鬼側のキャラクターでしょうか？

---

## 3) 「名探偵コナン」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/7b69be1d-1a54-089b-5cd1-618210a31db4.png)

コナンの影響を受けすぎているようですが、アニメで登場しても違和感ありません。

---

## 4) 「ドラゴンボール」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/89c0e2ec-5b08-6825-4974-db913e22c873.png)

違和感がなさ過ぎて笑ってしまいました。毎度、サンタ帽が「そのアニメで出てきそうな被り物」になっているのがおもしろいです。
**強そう。**

---

## 5) 「ジョジョの奇妙な冒険」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/ea980aae-cf54-7423-3f06-0b49c16af567.png)

ジョジョらしい特徴的なキャラクターのアバターになっています。**いかつい。**

---

## 6) 「新世紀エヴァンゲリオン」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/b19c68f6-d2c8-cd4d-579e-2a4ed60973f7.png)

特に黄色のメイド服の方や魔女コスプレの方のアバターはアニメに出てきそうです。映画で重要なキー人物らしき見た目をしています。

---

## 7) 「ワンピース」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/9d052e67-e5cb-d6be-0c6c-ea83ac12ceec.png)

こちらも映画に出てきそうなキャラクターのアバターが生成されました。**被っているそれは何だ？？**

---

## 8) 「ラブライブ！」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/c0c2f104-bc22-a0f5-b4ff-2fc63f6aec80.png)

あまりラブライブ感はありませんが、**「女性キャラクターがメインとなっているアニメ」ということは理解しているようです**。一番右の方や黄色のメイド服の方のアバターが綺麗ですが、特にメイド服の方のアバターは「アイドルマスター」シリーズで出てきそうな作画になっています。

---

## 9) 「BLEACH」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/87025baf-3e08-1b92-a55d-88147aa4fc82.png)

こちらもあまり違和感のないアバターが生成されました。**笑っている、真顔などの表情も反映できています**。

---

## 10) 番外編：映画「アバター」

「アバター」にちなんで、映画「アバター」に出てきそうなアバターにしたらどうなるのか検証してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/5b7a65b0-8a7a-1622-4ef6-bf5954e96009.png)

**アニメにかかわらず、映画やゲームの世界観を反映できている**のもすごいところです。3Dの質感がとてもリアルです。


---

# 4. 写真をアニメ風に変換してみよう

今回は、顔写真ではなく通常の風景写真を入力とし、アニメ風に変換させてみました。
今年も「すずめの戸締まり」で人気になっている新海誠監督風の写真にさせてみました。


:::note info
入力写真はすべて私が沖縄旅行に行ったとき撮影した写真です。変換後の文章は「新海誠監督のアニメに登場する飛んでいるイルカ」のように簡単な状況説明を入力しています。
:::

---

## 1) 美ら海水族館のイルカショー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/e03c783d-5faa-a9e0-5e70-856a1083f762.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/33cc7d79-9012-d372-c1f4-1dc4eaa872bd.png)

:::note info
イルカの向きが変わっていたりと多少違う構図になっていますが、写真の雰囲気を維持してアニメ風の画像が生成されています！
:::

---
## 2) 美ら海水族館のウミガメ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/9f8ee014-8a7f-a348-75b6-51b4d68968cc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/28345a8d-a66d-8144-fb2a-45b58bb30f24.png)

---
## 3) トンネル出口から見える夕焼け

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/72285474-fed7-9bb8-3391-0e028a80b7c8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/a92848c1-91f1-f236-592d-d6c31c3abd3d.png)

---
## 4) 古宇利島（こうりじま）にある展望台の鐘

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/9df861b8-e749-ddcc-62af-96b8b68dca39.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/46a9d971-6808-36c4-3f9a-f093034b2844.png)

---
# おわりに

今回はStable Diffusion 2.0を利用して顔写真、風景写真をアニメ風に変換してみました。まだまだ楽しめる要素がありそうです。
皆様もぜひお試しください。