2024.06.24
OpenAIの画像生成AIを利用してみた
こんにちは!佐々木です。
OpenAIのAPIを用いて、生成AIを利用し画像を作成してみたいと思います。(なんかややこしい)
ざっくり手順
- OpenAIのAPIにサインアップ
https://platform.openai.com/login?launch
※ChatGPTと入口が違うので注意 - ログイン後APIを選択
- 各々のAPIを選択
- 使い方に沿って利用
となります。
下地の準備
今回はpythonを用いて実行してみます。
https://platform.openai.com/docs/quickstart?context=python
上記にアクセスをして、「Step 1: Setting up Python」から試してみる。
pythonがもうはいっていれば「Install the OpenAI Python library」から試せばOK
pip install --upgrade openai
次はOpenAPIのキーを設定する「Step 2: Set up your API key」を参照
export OPENAI_API_KEY='your-api-key-here'
your-api-key-hereとなっているところにAPIキーをいれる。
でコマンド実行する。
※APIキーはプロジェクトの左メニュー「API keys」から作成可能
これで事前準備は完了
今回は画像生成AIを利用してみる
https://platform.openai.com/docs/guides/images/usage
この方法に従ってやってみる
まずはそのままコード実行します。
生成のプロンプトは「a white siamese cat」
白い猫ちゃんが生成される感じですね。
▼コード
from openai import OpenAI
client = OpenAI()
response = client.images.generate(
model="dall-e-3",
prompt="a white siamese cat",
size="1024x1024",
quality="standard",
n=1,
)
image_url = response.data[0].url
print(response.data)
適当に「openaitest.py」などとしてファイルに保存。
print(response.data)だけ追加しました。
python ./openaitest.py
などと実行してみると、結果が出てきたと思います。
表示されたURLを抜き出してブラウザなどにいれてみると、下記のような画像が生成されました。
可愛いですね〜
※生成されたURLは60分有効のようです。
生成時のオプションにresponse_formatをb64_jsonとすると「base64」形式で返却されます。
ひとまずサンプルは動きました!
画像のたりない部分を補うインペインティング
たとえば1000px x 1000pxの元画像を1400px x 1000pxなどにする際に
不足部分を補足するようなコード生成を考えます。
例えば下記のようなサンプル熊を用いて生成してみます。
生成に利用できる画像はPNG形式のみです。
▼コード
from openai import OpenAI
client = OpenAI()
from PIL import Image, ImageDraw
import base64
import io
def expand_image(image_path, new_width, new_height):
image = Image.open(image_path)
original_width, original_height = image.size
# 新しい画像を作成し、中央に元の画像を貼り付ける
new_image = Image.new("RGB", (new_width, new_height), (255, 255, 255))
paste_x = (new_width - original_width) // 2
paste_y = (new_height - original_height) // 2
new_image.paste(image, (paste_x, paste_y))
# マスク画像を生成(透過部分に画像が生成される)
mask = Image.new("RGBA", (new_width, new_height), 0)
mask.paste(image, (paste_x, paste_y))
return new_image, mask
def save_images(image, mask, image_path, mask_path):
image.save(image_path)
mask.save(mask_path)
def openai_image_inpainting(image_path, mask_path, output_path):
with open(image_path, "rb") as image_file, open(mask_path, "rb") as mask_file:
image_data = image_file.read()
mask_data = mask_file.read()
response = client.images.edit(
response_format="b64_json",
prompt="Fill the missing parts of the image",
n=1,
size= "1024x1024",
image=image_data,
mask=mask_data
)
#print(response.data)
# 生成された画像を保存
image_bytes = base64.b64decode(response.data[0].b64_json)
with open(output_path, "wb") as f:
f.write(image_bytes)
def resize_image(image_path, output_path, new_size):
image = Image.open(image_path)
resized_image = image.resize(new_size, Image.LANCZOS)
resized_image.save(output_path)
# 使用例
image_path = "test.png"
expanded_image_path = "expand_image.png" #拡張するべきところが増えている
mask_path = "mask.png"
output_path = "generated_image.png"
final_output_path = "final_output.png"
width = 1400
height = 1000
# 画像を拡張し、マスクを生成
new_image, mask = expand_image(image_path,width,height)
save_images(new_image, mask, expanded_image_path, mask_path)
# 画像を補完
openai_image_inpainting(expanded_image_path, mask_path, output_path)
# 補完された画像をリサイズ
resize_image(output_path, final_output_path, (width, height))
実行してみると下記のようになりました!!
若干左右に歪みがありますね・・・。
ちょっと画像が複雑なので、別のものであればまた結果が違うかもですね。(命令によっても変わるかも)
画像投稿時の自動延長などに使えるかも?
すでにPhotoshopでもできますが、自動化したい場合もありそうですよね。(CMSからの登録など)
※ただし注意点として、OpenAPI側での画像生成サイズがきまっているため、大きな画像にはむいていなそうです。
以上、佐々木でした!