Rembgを使って画像から背景を削除してみた

Rembgを使って画像から背景を削除してみた

Rembgという背景除去のPythonライブラリがすごかったので紹介です。これでコラ画像作り放題。
Clock Icon2022.10.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、Twitter監視botの八木です。

いつものようにTwitter監視を行なっていると、あるツイートが目に飛び込んできました。

120 : Remove Image Background using Python https://t.co/888CDqtc68 pic.twitter.com/14g18gzi2n

— Python Coding (@clcoding) October 7, 2022

Rembgという、画像から背景を削除するPythonライブラリがあるようです。
ツイートの画像を見てみると、非常に綺麗に背景が削除されています。すごい。

ツイートはPythonコードからの呼び出しですが、READMEをみるとCLIもありました。

今回はこのCLIでいろんな画像を処理してみます。

前提条件

PC: MacBook Pro (13-inch, M1, 2020)
OS: macOS Monterey 12.5.1
Python: v3.9.13
rembg: 2.0.25

やってみた

まず、rembgをインストールします。

pip install rembg

コマンドがインストールできたので、あとは実行するだけです。
以下のコマンドで実行できます。

rembg i input.jpg output.jpg

私が最初に実行した時は、以下のエラーが発生しました。

Access denied with the following error:

 	Too many users have viewed or downloaded this file recently. Please
	try accessing the file again later. If the file you are trying to
	access is particularly large or is shared with many people, it may
	take up to 24 hours to be able to view or download the file. If you
	still can't access a file after 24 hours, contact your domain
	administrator.

You may still be able to access the file from the browser:

	 https://drive.google.com/uc?id=1tCU5MM1LhRgGou5OpmpjBQbSrYIUoYab

Traceback (most recent call last):
  File "/Users/my_username/.pyenv/versions/3.9.13/bin/rembg", line 8, in <module>
    sys.exit(main())
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/rembg/cli.py", line 95, in i
    output.write(remove(input.read(), session=new_session(model), **kwargs))
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/rembg/session_factory.py", line 60, in new_session
    ort.InferenceSession(
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 347, in __init__
    self._create_inference_session(providers, provider_options, disabled_optimizers)
  File "/Users/my_username/.pyenv/versions/3.9.13/lib/python3.9/site-packages/onnxruntime/capi/onnxruntime_inference_collection.py", line 384, in _create_inference_session
    sess = C.InferenceSession(session_options, self._model_path, True, self._read_config_from_model)
onnxruntime.capi.onnxruntime_pybind11_state.NoSuchFile: [ONNXRuntimeError] : 3 : NO_SUCHFILE : Load model from /Users/my_username/.u2net/u2net.onnx failed:Load model /Users/my_username/.u2net/u2net.onnx failed. File doesn't exist

コマンドは初回実行時にモデルをGoogle Driveからダウンロードしているのですが、ドライブのリクエスト制限に引っ掛かったようです。(ちょうどツイートが拡散されたタイミングだったので、アクセスが集中したのかもしれません。)

You may still be able to access the file from the browser:

	 https://drive.google.com/uc?id=1tCU5MM1LhRgGou5OpmpjBQbSrYIUoYab

「ブラウザからアクセスできるかも」という案内があるので、このURLからモデルをダウンロードし、~/.u2net/u2net.onnxに配置しました。

上記の手順でエラーが解消できたので、実際に幾つかの画像で処理を行なってみました。

結果を見ると、人物だけでなく、動物や車でも綺麗に切り出してくれています。

手に持ってるカメラも含んでくれてます。


背景に人がいても問題なし。


ネコチャンも


車だっていけちゃう。

一方で、画像の中に複数の物体がある場合、切り出し精度は少し落ちるようです。

また、画像全体に対して物体が小さい場合も少し精度が落ちていました。先にトリミングしてから、背景削除を行うとよさそうです。

コードから利用する場合は?

ライブラリはCLIでインストールしたものと同じです。

pip install rembg

あとはコードでインポートするだけです。

from rembg import remove
from PIL import Image

input_path = 'input.png'
output_path = 'output.png'

input = Image.open(input_path)
output = remove(input)
output.save(output_path)

どんな処理をしているの?

2020年に発表された、U2-Netというアルゴリズムを使用しています。
アルゴリズムの詳しい内容は論文や他の解説記事をご覧ください。(私は何もわからなかった。。。)
論文
Github

最後に

非常に高い精度に驚愕しました。CPUでもそれなりの速度が出るので、画像の加工には十分でした。ライブラリ自体はGPUにも対応しているため、動画などの処理を行う場合はGPUを使うとよさそうです。
思ってみるとバーチャル背景とかもこういう技術が使われているんですね。(今更)

ちょうど先日、弊社社長がこんなツイートをしていたのでピッタリなツールだと思いました。

全社員から提出してもらった写真の背景を自然な境界線で削除してから程よい背景色で埋めて印刷業者に提出する簡単なお仕事。個人情報なので責任者としてコードを書く。

— さとし? (@sato_shi) October 7, 2022

スライド用のイラスト作成や、コラを作るのにも便利そうです。

以上、八木(@goat0613)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.