■ 0.はじめに
「人物等のオブジェクト切り抜き」をする場合、かつてはチマチマ画像を拡大し選択範囲を指定するなど、作業がとても大変でかつ職人芸でした。ところが、昨今、AI技術を使うことでこの作業をしなくても「ボタン1発」で切り抜きができるようになってきました。
これらはあとで紹介する「webツールサイト」などでも実施可能ですが、費用がかかるサイトが多いのが現状です…お金が無い貧乏人としては、自分でなんとかするしかありません。その昔、おもちゃが買ってもらえず、しかたなく、家にあった割り箸と輪ゴムで、ゴム鉄砲を作って遊んだことを思い出してしまいました😭。
そんな訳で、フリープログラムを使っての「人物切り抜き」、いってみましょう!
■ 1.やること
■ 2.切り抜きの仕組み
Githubでそれらしいツールを検索して、起動すれば「オブジェクト切り抜き」は簡単にできてしまうんですが、それではせっかくプログラムで実行している意味がないので、簡単に仕組みも調べておきます。
Alpha Mattingとは
今回実施するオブジェクト切り抜きは「Alpha Matting」という手法を使います。
画像から前景のAlpha値を抽出し、背景と分離することをAlpha Mattingと呼びます。Alpha値とは、各画素での不透明度を表すパラメータです。Alpha Mattingでは、「ソース写真」と「Trimap」と呼ばれる中間データを用いて処理を行います。
Trimapとは
Trimapとは、前景であろう領域に白色、背景であろう領域に黒色、どちらか判断できない、または細かくて白と黒では塗り分けられない領域を灰色で塗り分けたものです。「T・R・I」とTrimapを作ってみました。いかがでしょうか😁?
ツール整理
今回使用するツールについても整理しておきます。本記事ではrembgを使用します。rembgからu2net、pymattingのツールを使用しているようですので、そちらも参考になります。
No. | ツール名 | 説明 | ライセンス |
---|---|---|---|
1 | u2net | Trimapを生成するツール | Apache License 2.0 |
2 | pymatting | Alpha Mattingを処理するツール | MIT License |
3 | rembg | 「u2net」と「pymatting」を実行し、オブジェクト切り抜きをするツール | MIT License |
■ 3.Google Colabで実行
今回は、我らの学び屋「Google Colab」で実行したいと思います。実行環境は、もちろんGoogle Colabでなくても結構です。Google Colabで実行する場合、プログラムを改造した箇所やGoogle Colabへアップロードした画像は、時間が経つと揮発してしまうので注意が必要です。
Google Colabで実施したログは、こちらを参照してください。
https://github.com/PoodleMaster/Qiita_rembg/blob/main/rembg.ipynb
(1)画像切り抜きプログラムの準備
●インストール
pipコマンドでpypiからインストール可能です。まずは、pip自身をupdateしておきましょう。
!pip install -U pip
rembgの「Requirements」通りに下記ライブラリをインストール
!pip install torch==1.7.1+cpu torchvision==0.8.2+cpu -f https://download.pytorch.org/whl/torch_stable.html
次にrembgをインストールしましょう。
!pip install rembg
インストール後、次のようにランタイムの再起動を促されたら、実施してください。
Collecting rembg
Downloading rembg-1.0.14.tar.gz (13 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
︙
WARNING: The following packages were previously imported in this runtime:
[PIL,numpy]
You must restart the runtime in order to use newly installed versions.
[
Restart Runtime
]ボタンを押下するか、[ランタイム
] - [ランタイムを再起動
]を押下
●切り抜き画像アップロード
切り抜き画像として、「sample.png」をアップロードします。
手元にある画像ファイルを「/content」配下にドラッグアンドドロップして、GoogleColabへアップロードしてください。
きちんとアップロードされたか確認します。
from IPython.display import Image, display_png
display_png(Image('sample.png'))
●rembg実行
それではrembgを起動して切り抜きを行います!
from rembg.bg import remove
import numpy as np
import io
from PIL import Image
input_path = 'sample.png'
output_path = 'cutout.png'
f = np.fromfile(input_path)
result = remove(f,
alpha_matting=True,
alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10,
alpha_matting_erode_structure_size=6)
img = Image.open(io.BytesIO(result)).convert("RGBA")
img.save(output_path)
●rembg実行結果
あれ?エラーだ😓………
Google Colabからpipインストールするとなぜか
rembg 1.0.14
がインストールされてしまいます。2021/04/14時点
で、最新版はrembg 1.0.26
となっています。最新版では、このエラーは発生しません。rembg 1.0.26
が要求するpythonバージョンはpython 3.8以上~4未満
となっていますが、Google ColabのPythonバージョンは現時点でPython 3.7.10
なので、それが原因かと思います。
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-64027dc30014> in <module>()
----> 1 from rembg.bg import remove
2 import numpy as np
3 import io
4 from PIL import Image
5
1 frames
/usr/lib/python3.7/functools.py in lru_cache(maxsize, typed)
488 maxsize = 0
489 elif maxsize is not None:
--> 490 raise TypeError('Expected maxsize to be an integer or None')
491
492 def decorating_function(user_function):
TypeError: Expected maxsize to be an integer or None
●プログラム変更1
とりあえず、ソースコードを修正して先に進みます………
上記エラーの場合、以下のプログラムを修正すれば動くようになります。
/usr/local/lib/python3.7/dist-packages/rembg/bg.py
bg.py, line 67
@functools.lru_cache
↓↓↓↓
@functools.lru_cache(maxsize=None)
●プログラム変更2
rembgでは、Trimap画像は保存されないので、ついでに「trimap.png」として画像を保存するように修正してしまいましょう!ちなみにTrimap画像はu2netの学習サイズである320x320で検出されるので、元の画像サイズへリサイズしています。
※「プログラム変更2」は必須ではありません。割愛してもOKです。
/usr/local/lib/python3.7/dist-packages/rembg/bg.py
bg.py, Line85mask = detect.predict(model, np.array(img)).convert("L")
上記処理のすぐ下に、以下の処理(3行)を追加
output_path = '/content/trimap.png'
mask = mask.resize(img.size)
mask.save(output_path)
def remove(
data,
model_name="u2net",
alpha_matting=False,
alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10,
alpha_matting_erode_structure_size=10,
):
model = get_model(model_name)
img = Image.open(io.BytesIO(data)).convert("RGB")
mask = detect.predict(model, np.array(img)).convert("L")
output_path = '/content/trimap.png' # ← ここの処理を追加
mask = mask.resize(img.size) # ← ここの処理を追加
mask.save(output_path) # ← ここの処理を追加
●ランタイムの再起動
プログラムを変更したら、忘れずにランタイムの再起動を実施してください。
[
ランタイム
] - [ランタイムを再起動
]を押下
(2)画像切り抜きプログラムの実行
●rembg実行コード
プログラムを修正したので、再度、以下プログラムを実行して、切り抜きを行っていきます!
※remove関数に渡す引数「alpha matting_xxxx_xxxx」は、適当に変えて遊んでみてください。
from rembg.bg import remove
import numpy as np
import io
from PIL import Image
input_path = 'sample.png'
output_path = 'cutout.png'
f = np.fromfile(input_path)
result = remove(f,
alpha_matting=True,
alpha_matting_foreground_threshold=240,
alpha_matting_background_threshold=10,
alpha_matting_erode_structure_size=6)
img = Image.open(io.BytesIO(result)).convert("RGBA")
img.save(output_path)
Trimap画像「trimap.png」と、AlphaMattingした画像「cutout.png」を表示して確認します。
from IPython.display import Image, display_png
display_png(Image('trimap.png'))
display_png(Image('cutout.png'))
なんとか「切り抜き」はうまくいきました!あとはお姉たまを「僕んち」に呼ぶだけです😚!
(3)写真合成
画像合成については、フリーの画像編集ツールなどでレイヤー貼り付けを行っても同様のことができますが、せっかくなのでこちらもプログラムで実行します。
●合成する背景をアップロード
合成する背景として、「background.png」と「greenback.png」の2つをアップロードします。
手元にある画像ファイルを「/content」配下にドラッグアンドドロップして、GoogleColabへアップロードしてください。
きちんとアップロードされたか確認します。
from IPython.display import Image, display_png
display_png(Image('background.png'))
display_png(Image('greenback.png'))
●「僕んち」背景と合成
from PIL import Image
# 切り抜き画像
img = Image.open('cutout.png').convert('RGBA')
# 背景画像
bg = Image.open('background.png').convert('RGBA')
# 画像合成
img_clear = Image.new("RGBA", bg.size, (255, 255, 255, 0))
img_clear.paste(img, (200,250))
bg = Image.alpha_composite(bg, img_clear)
# 画像保存
bg.save('merge1.png')
作成された合成画像を表示します。
from IPython.display import Image, display_png
display_png(Image('merge1.png'))
●「グリーンバック」背景と合成
from PIL import Image
# 切り抜き画像
img = Image.open('cutout.png').convert('RGBA')
# 背景画像
bg = Image.open('greenback.png').convert('RGBA')
# 画像合成
img_clear = Image.new("RGBA", bg.size, (255, 255, 255, 0))
img_clear.paste(img, (200,250))
bg = Image.alpha_composite(bg, img_clear)
# 画像保存
bg.save('merge2.png')
切り抜き画像とグリーンバック画像を合成した画像を表示します。
from IPython.display import Image, display_png
display_png(Image('merge2.png'))
ゴチャゴチャしない背景(グリーンバック)で、うまく切り取れているか確認してみます。
少しエッジが甘いところがありますが、まぁまぁできていますね!
■ 4.オブジェクト切り抜きサイト紹介
プログラムを実行しなくても、webツールを実行することで切り抜きを行うこともできます。対価支払いについては、AIの開発などを続けて認識精度を向上させるためなのか、気軽さなのか分かりませんが、サブスクが多いですね。他にも有効なwebサイトがあったら教えてください。ちな、順不同です。
サイト | 切り抜き結果 | 個人的な感想 | 点数 |
---|---|---|---|
Clipping Magic | 自動切り抜きもキレイだし、切り抜き後の調整ツールが秀悦でとても使いやすいです。ヘアツール、フォアグラウンド指定やバックグラウンドの範囲指定が自動でできたり、きめ細かな修正が簡単に実施可能です。有料でサンプルには透かしが入っています。 | 100 | |
remove.bg | 自動切り抜き後は、簡単な手動によるフォアグラウンドの範囲削除/復元ツールの様なものはありましたが、それだけでは切り抜きのきめ細かな調整はできません。有料ですが、小さなプリビュー画像は無料でダウンロード可能です。 | 80 | |
removal.ai | 手と首元の間を見るとremove.bgよりも良いかもしれません。自動切り抜き後のペイントツールが充実していますが、それより切り抜き調整ツールが欲しかった。有料ですが、小さなプリビュー画像は無料でダウンロード可能です。 | 81 | |
Photo Scissors | 自動切り抜き後にヘアーツール、フォアグラウンド指定ツールなどがあります。フォアグラウンドツールで同じ様な範囲が自動で選択されないところや、バックグラウンドが指定できないところなどから、Clipping Magicには及びません。有料ですが、小さなプリビュー画像は無料でダウンロード可能です。 | 85 |
■ 5.以上
お疲れ様でした。
●Google Colabで実施したことについて
最新版のrembg 1.0.26
は、Python 3.8
以上という要求仕様でした。Google Colabは現時点ではPython 3.7.10
でしたので最新版は適合せず、古いrembg 1.0.14
を使用することになってしまいました。ソースコードの修正もする必要があったので、こんなことなら、ローカルPCでAnaconda
やPycharmのvenv
などで、Python 3.8
環境を作った方が良かったです。みなさんは気をつけてください!
win10で実施する場合は、Pythonの拡張モジュールをインストールする為に、以下のCコンパイラが必要となる場合があります。
https://www.python.jp/install/windows/install_vstools2017.html
●画像切り抜きについて
実際に「画像切り抜き」をやってみて、髪の毛など切り抜きが難しいところでも、自動で難なく切り取りができてしまうのは、本当にAIさまの「おチカラ」はスゴイですね!今までできなかったことが、続々と自動でできるようになっています。ただ、処理はまだまだ完全ではないので、Clipping Magicの様に、いかに簡単に補正をできるようにするか、などの機能も合わせて必要だと思いました。