copainterのAIペン入れ機能を妨害するフィルター作ってみた

# はじめに
copainterとはRADIUS5社が提供するイラスト制作に便利なAIツールサービスです。
同社は2024年6月24日にイラストのペイン入れツールの提供を開始しました。

::: note
ここでいうペン入れとは、イラストや漫画のラフスケッチを清書することです。
:::

https://www.copainter.ai/ja

早速眼鏡のお姉さんを描いて、copainterに通してみました。設定は画像の矢印部分に記載しています。

![スクリーンショット 2024-06-26 23.35.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/424b47d1-9c92-5507-8650-a41a3c965986.png)

<font color=red>元々のイラストほぼそのままに、余計な線が消えてアニメ風のイラストに変換されました！</font>イラストを急いで書きたい人には便利そうですね。

# なぜAIペン入れ機能を妨害するのか

copainterのAIペン入れツールがリリースされると、Xで[ゆあꙬ꙳](https://x.com/yuuuua_2522)さんの下記ポストが話題になりました。

https://x.com/miyata_ta_tan/status/1805569569144422505

ゆあꙬ꙳さんの投稿は、copainterのペン入れ機能の**元画像に猫の写真を重ねて入力するとラフスケッチとは全く違う画像が生成される**という内容です。
なぜゆあꙬ꙳さんはせっかくリリースされたAIペン入れツールを妨害する方法を発明したのでしょう。
それは、ポスト本文にもあるように<font color=red>『絵描き界隈を守るため』</font>のようです。

::: note warn
copainterのようなAIペン入れツールを使用すると

1. <font color=blue>悪意のある依頼者</font>が絵師にイラストの作成を依頼
1. 絵師が依頼者にラフスケッチを確認してもらう(これは結構一般的なことのようです)
1. 依頼者はこのタイミングで依頼を取り下げる(この場合報酬は満額支払われない契約条件であることを想定)
1. 依頼者は無料or廉価で手にいれたラフスケッチをもとにAIペン入れツールで清書

というような手順を踏むことで**正当な報酬を支払わずに望みのイラストを手に入れる**ことが懸念されています。

:::

これを防ぐために、ゆあꙬ꙳さんは絵師が依頼者にラフスケッチを確認してもらう際にAIペン入れツールの使用を妨害するような方法を考案されたようです。

# ゆあꙬ꙳さん考案の方法を試してみる
イラストと無関係の猫の画像を重ねることで全然違う画像が生成されるというのは、前述のような事情が無くてもとても面白い事象だと思います。実際に再現するのを見てみたくて私も早速試してみました。

しかし、私が試すと、やり方が悪かったのか画像の相性があるのか**綺麗なペン入れが完成してしまいました。** どんな面白い画像が生成されるのかワクワクしていましたが、ゆあꙬ꙳さんのような事象を引き起こすことは出来ませんでした。

![スクリーンショット 2024-06-26 23.04.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/45b9d4d7-dfbe-7170-95ad-0813b8ac2f17.png)

# 妨害フィルターを作る
<font color=red>私もAIペン入れを妨害したい！</font>
ということで、妨害フィルターを作成しました。生成後画像は**元画像と大分違う印象にすることが出来ています。**

![スクリーンショット 2024-06-26 23.14.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/4b6d271d-8388-53a2-9697-90c897d299ca.png)

# 妨害フィルターの解説

発想としてはシンプルで無数の波線を追加するだけのフィルターです。
実現方法は[誤差拡散法](https://zenn.dev/baroqueengine/books/a19140f2d9fc1a/viewer/531f1d)を参考にしていて、全てのピクセルに対して

1. そのピクセルの明るさが閾値より大きければそのピクセルを白、小さければ黒にする
1. 元の明るさから白または黒にするのにピクセルに足し引きした明るさを誤差として記録する
1. 次のピクセル（右隣）では、元々の明るさに一つ前の手順で取得した誤差を足す

という操作を繰り返すだけです。これによって、**色味が明るいエリアでは波線の間隔が広くなり、暗いエリアでは波線の感覚が狭くなります。** 漫画で使うトーンのように、線だけで明るさを表現できるようになります。

明るさの違いを波線の間隔に置き換えることで、**人間の目には元々のイラストの印象を損なわずに伝えることが出来ますが、実際には画像に大量の波線を追加することが出来ます。**

# フィルターの使い方
AIペン入れツールを妨害してみたい方は、下記の手順でご自由にご利用下さい。
## 【手順1】pythonの実行環境を用意
下記のサイトに従ってpythonの実行環境を用意します。

https://prog-8.com/docs/python-env-win

## 【手順2】必要なライブラリをインストール
ターミナルで下記のコマンドを実行します。
```bash
pip install numpy
pip install opencv-python
```

## 【手順3】フィルターをかけるプログラムを実行する
下記のpythonファイルを実行します。

 ::: note warn
その際、5行目の`'./image/sample.jpg'`はフィルターをかけたい画像のパスに書き換えてください。
:::

```python filter.py
import cv2
import numpy as np

# 画像の読み込み（グレースケールで読み込む）
image = cv2.imread('./image/sample.jpg', cv2.IMREAD_GRAYSCALE)

# 画像の高さと幅を取得
height, width = image.shape[:2]

# 閾値
threshold = 128

# 誤差
error_list = np.zeros((height, width), dtype=np.int32)

# 全てのピクセルでループ
for i in range(height):
    for j in range(width):
        # 元の値に他のピクセルから伝えられた誤差を足した値
        pixel_val = image[i, j] + error_list[i, j]

        # 閾値より大きければそのピクセルを白にする
        if pixel_val > threshold:
            image[i, j] = 255
            # 白(255)とpixcel_valとの差を誤差とする
            error = pixel_val - 255
        # 閾値より大きければそのピクセルを黒にする
        else:
            image[i, j] = 0
            # 黒(0)とpixcel_valとの差を誤差とする
            error = pixel_val

        # 一つ右のピクセルに誤差を伝搬
        if j < width - 1:
            error_list[i, j + 1] += error

# 画像の表示
cv2.imshow('Modified Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

# おわりに
本記事は、生成AIに対して肯定的な立場でも、否定的な立場でもありません。単純に「フィルター作ってみたらペン入れを妨害できたよ」という内容の記事です。楽しんでいただけますと幸いです。