Supershipの名畑です。まさかのてーきゅう新作動画が公開。てーきゅうの第10期が放送されるのを私はいつまでも待ち続けておりますよ。
いきなりですみませんが宣伝
2024年11月27日開催のKDDI Group Developer Community(KGDC) Tech Conference #8 ~KDDIグループにおける生成AIの活用状況と今後の展望~でパネルディスカッションに登壇しますので、よければどうぞ。オフライン、オンライン両方ございます。
はじめに
タイトルのままです。
Photoshop等の画像編集ソフトを使わず、コードのみで、画像上の人物をそのままに背景だけをAI生成したいというケースがあったので、そのコードを残します。Pythonです。
特に目新しいことはないですが、よくあるニーズだと思うので、どなたかの役に立つと嬉しいです。
入力画像と出力画像
今回の記事では先に結果をお伝えします。
以下の入力画像を元として、出力画像を生成します。
入力画像
出力画像
ライブラリ
API呼び出しのためにrequestsを入れておきます。
$ pip install requests
バージョンを確認しておきました。
$ pip list | grep -e requests
requests 2.31.0
API Key
今回、背景の生成にはStability AIのWeb APIを用います。
そのためにDeveloper PlatformでAPI Keyを発行する必要があります。価格はPricingをご参照ください。
ハードコーディングを避けるため、環境変数に保存しておきます。
私の環境での設定ファイルはzshrcです。
$ open ~/.zshrc
今回はSTABILITY_API_KEYという名称で保存しました。
export STABILITY_API_KEY =ここに取得したAPI keyを書く
コード
今回はRemove Background APIを用いて人物のみを切り抜き、切り抜いた画像をInpaint APIに渡した上で生成を行います。
プロンプトには「Large glass windows with a view of the metropolis behind」を指定しています。日本語訳すると「後ろに大都市の光景が広がっている大きなガラスの窓」です。
import os
import requests
# ファイルパス
input_path = './input.png' # 元画像
mask_path = './mask.png' # マスク用画像(途中生成/削除)
output_path = './output.png' # 出力画像
# API Keyの取得確認
api_key = os.getenv("STABILITY_API_KEY")
if api_key is None:
raise Exception("Missing Stability API key.")
headers = {
"Accept": "image/*",
"Authorization": f"Bearer {api_key}"
}
# Remove Background API 呼び出し
response = requests.post(
f"https://api.stability.ai/v2beta/stable-image/edit/remove-background",
headers=headers,
files={
"image": open(input_path, "rb")
},
data={
"output_format": "png"
},
)
# マスク画像保存
if response.status_code == 200:
with open(mask_path, 'wb') as file:
file.write(response.content)
else:
raise Exception(str(response.json()))
# Inpaint API 呼び出し
response = requests.post(
"https://api.stability.ai/v2beta/stable-image/edit/inpaint",
headers=headers,
files={
"image": open(mask_path, "rb"),
},
data={
"prompt": "Large glass windows with a view of the metropolis behind", # プロンプト
"output_format": "png",
"grow_mask": 0, # マスク周辺のぼかしをなくす
},
)
# マスク画像削除
os.remove(mask_path)
# 出力画像保存
if response.status_code == 200:
with open(output_path, "wb") as file:
file.write(response.content)
else:
raise Exception(str(response.json()))
rembgを使用した場合
画像の切り抜きにrembgを使う方法も紹介しておきます。こちらの方法であればAPIの呼び出しが一度で済むためコストを安く抑えられますが、切り抜き精度に差があります。
まずインストール。
$ pip install rembg
バージョンを確認しておきました。
$ pip list | grep -e rembg
rembg 2.0.59
コードは以下です。
from rembg import remove
import os
import requests
# ファイルパス
input_path = './input.png' # 入力画像のパス
mask_path = './mask.png' # マスク画像のパス(途中生成/削除)
output_path = './output.png' # 出力画像のパス
# 背景を除去したマスク画像生成
with open(input_path, 'rb') as i:
with open(mask_path, 'wb') as o:
input_image = i.read()
mask_image = remove(input_image)
o.write(mask_image)
# API Keyの取得確認
api_key = os.getenv("STABILITY_API_KEY")
if api_key is None:
raise Exception("Missing Stability API key.")
# Inpaint API 呼び出し
response = requests.post(
"https://api.stability.ai/v2beta/stable-image/edit/inpaint",
headers={
"Accept": "image/*",
"Authorization": f"Bearer {api_key}"
},
files={
"image": open(mask_path, "rb"),
},
data={
"prompt": "Large glass windows with a view of the metropolis behind", # プロンプト
"output_format": "png",
"grow_mask": 0, # マスク周辺のぼかしをなくす
},
)
# マスク画像削除
os.remove(mask_path)
# 出力画像保存
if response.status_code == 200:
with open(output_path, "wb") as file:
file.write(response.content)
else:
raise Exception(str(response.json()))
出力画像は以下です。今回のケースだと切り抜きの精度もそれほど気にならないですかね。
Stable Diffusionの環境をローカルに構築すればAPI呼び出しコストは0にできますので、興味がある方は調べてやってみてください。
最後に
コードだけで完結させられるのが本当に楽で嬉しいです。
本当に様々な効率化が進んでいると実感する日々です。