簡単に背景除去する (Background remove)

## はじめに

このセクションでは、柴犬の画像から背景を効果的に除去する手順についてご紹介します。背景除去は、画像の主要な被写体を際立たせたり、他の背景に合成したりする際に非常に役立ちます。

この記事の応用編を投稿しました。
https://qiita.com/kotai2003/items/2bd0a8906e1c00447e35


## やりたいこと

こちらの写真を例に、柴犬の画像から背景を取り除く方法を説明します。このプロセスでは、Pythonを利用し、被写体を保持しつつ周囲の背景を削除します。


![shiba-inu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/99e3c340-80d1-5d3d-2b4b-e1087e7da5f5.jpeg)
![shiba-inu-remove.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/7836a607-8431-dd94-a2fb-527d123a782b.png)

## 利用するもの

本プロジェクトでは、「rembg」という強力なライブラリーを使用します。rembgは、人工知能を利用して画像から背景を自動的に除去するツールで、高い精度で被写体を識別し、背景を効果的に削除できます。このライブラリーは、Python言語で書かれており、簡単にインストールして使用することができます。

rembgの主な特徴は以下の通りです：

* 人工知能を利用した精度の高い背景除去
* シンプルで使いやすいインターフェース
* 広範な画像フォーマットに対応

次のセクションでは、rembgのインストール方法と、実際に柴犬の画像から背景を除去する手順について詳しく説明します。

https://github.com/danielgatis/rembg?ref=blog.streamlit.io

**設置方法**
rembgライブラリーを利用するには、まずPython環境にインストールする必要があります。CPUのみを使用する場合とGPUを利用する場合で、インストール方法が異なります。以下のコマンドを実行してください：

```python
# cpu利用の場合
pip install rembg

# gpuを利用する場合(*)
pip install rembg[gpu]

```
**重要**： GPUを利用する場合は、`onnxruntime-gpu`が必要です。このパッケージは、GPU上でのモデル実行を最適化するために使用され、rembgのパフォーマンスを向上させます。`onnxruntime-gpu`の詳細については、ONNX Runtime公式ウェブサイトを参照してください。
https://onnxruntime.ai/

**基本的な使い方** 

以下のPythonスクリプトは、rembgを使用して画像から背景を除去する基本的な方法を示しています。このスクリプトを実行すると、指定した入力画像から背景が削除され、新しい画像が生成されます。

```python
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)       # 出力画像を保存
```

rembgは、alpha-channelを含むPNG形式で画像を返します。これにより、背景が透明になった画像が得られ、さらにこの透明な部分をマスクとして利用することが可能です。これは、画像を他の背景に合成したり、特定の処理を適用したりする際に非常に便利です。


## コード

以下のPythonコードは、柴犬の画像から背景を除去し、新しい背景を適用する処理を行います。

**背景除去関数**
remove_background関数は、入力された画像の背景を削除します。この関数では、まずPILライブラリを使用して画像を読み込み、次にrembgライブラリを用いて背景を除去し、最後に結果を保存します。

**マスク適用関数**
apply_mask_to_background関数は、背景が除去された画像（RGBA形式）を読み込み、そのアルファチャネルをマスクとして使用して新しい背景を適用します。ここでは、OpenCVライブラリを使用して、白い背景画像を作成し、アルファチャネルをマスクとして適用します。

**メイン処理**
main関数では、最初に背景除去関数を呼び出して画像から背景を削除し、次にマスク適用関数を使用して新しい背景を適用します。最終的に、処理された画像が表示され、ファイルに保存されます。

このコードを実行することで、柴犬の画像から背景を効果的に除去し、新しい背景を適用することができます。

```python
import cv2
from rembg import remove
from PIL import Image
import numpy as np

def remove_background(input_image_path, output_image_path):
    # 背景を削除
    try:
        input_image = Image.open(input_image_path)
    except IOError:
        print(f"Error: Cannot open {input_image_path}")
        return

    output_image = remove(input_image)
    output_image.save(output_image_path)

def apply_mask_to_background(masked_image_path):
    # RGBA画像を読み込み
    rgba_image = cv2.imread(masked_image_path, cv2.IMREAD_UNCHANGED)
    if rgba_image is None:
        print(f"Error: Cannot open {masked_image_path}")
        return

    # アルファチャネルをマスクとして使用
    alpha_channel = rgba_image[:, :, 3]

    # 白い背景画像を作成
    background = np.ones_like(rgba_image, dtype=np.uint8) * 255
    # マスクを適用
    background_masked = cv2.bitwise_and(background, background, mask=alpha_channel)
    return background_masked

def main():
    input_path = './images/shiba-inu.jpg'
    output_path = './images/shiba-inu-remove.png'

    # 背景除去処理
    remove_background(input_path, output_path)

    # マスク適用処理
    masked_image = apply_mask_to_background(output_path)
    if masked_image is not None:
        cv2.imshow('Masked Image', masked_image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        cv2.imwrite('masked_image.jpg', masked_image)

if __name__ == "__main__":
    main()

```

## 実行結果
オリジナル画像
![shiba-inu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/1ce916b6-af81-8b77-5434-4bd084e17788.jpeg)
背景除去画像
![shiba-inu-remove.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/dd096f8e-c637-0d83-e315-757dc8467314.png)
マスク画像
![masked_image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/dd6cc042-b5a0-2997-fc25-a330aacc3ae2.jpeg)


## 参考資料
https://github.com/danielgatis/rembg

https://blog.streamlit.io/build-an-image-background-remover-in-streamlit/

https://qiita.com/kotai2003/items/2bd0a8906e1c00447e35