APIを使ってDALL-E3で画像生成!驚きの簡単さに興奮しませんか?
APIを使ってDALL-E3で画像生成!驚きの簡単さに興奮しませんか?
こんにちは、makokonです。今回は、画像生成を手掛ける新たなツール、DALL-E3についてお話しします。ChatGPTやBing Chatで使えるこのツール、既にご存知でしょうか?
私自身、仕事以外では、繊細な映像を作ることはあまりないのですが、ぼんやりとした映像をAIで楽しむ分には、これほど便利なツールはありません。ChatGPTで自由自在に楽しむことも可能ですが、APIを通じてDALL-E3を使うことにより、さらなる可能性を探求することができます。
はじめは、「今更、APIを使うことに意味があるのか?」と疑問に思っていました。しかし、実際に作ってみると思わぬ楽しさに出会えました。その魅力を、今回は皆さんと一緒に紐解いていきたいと思います。
OpenAI API Images API
現在OpenAIのイメージAPIでは、3つのメソッドが公開されています。
https://platform.openai.com/docs/guides/images?context=node
今回使うメソッドは、テキストプロンプトに基づいてイメージを最初から作成する (DALL・E 3 および DALL・E 2)で、DALL-E3を使います。既存の画像の編集やバリエーションの作成もいいのですが、今回は画像生成のみです。
今回作成するプログラムの動作
以下のループを繰り返すことにします。
生成したい画像の特徴を入力する。
入力された画像の特徴から、プロンプトを生成する。
プロンプト生成は、gpt4のChat履歴を利用して、特徴の追加、修正を行うDALL-E3を利用して、プロンプトから映像を生成する。
生成した映像を表示して、保存する
最初に戻る
ループ終了時には、生成したプロンプトと画像のリスト(ファイル名)をログとして保存する。
こんな方法で、映像を自分好みに修正していきます。ループを繰り返して画像を修正しますが、あくまでもプロンプトを修正していくだけなので、画像編集ではありません。予想外の映像の思わぬ変化を楽しむためのものですので、連続して出来上る映像の絵柄には。連続性がありません。
準備
今回使用するライブラリは、このあたりですね。langchainの周辺はアップデート盛んなので、upgradeしたほうがいいかもしれません。
pip install --upgrade openai langchain langchain-openai requests matplotlib pillow
import os
import getpass
import datetime
from openai import OpenAI
# 環境変数にAPIキーを設定 現在システムでは設定済み
#os.environ["OPENAI_API_KEY"] = "your API key"
#image
import matplotlib.pyplot as plt
from PIL import Image
import requests
from io import BytesIO
#chat 設定
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts.chat import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
APIキーは、コードに書くのではなく、環境変数に入れておくか、設定ファイルから読み込むようにしましょう。履歴付きChatも使用するので、メモリ周りも設定しています。
関数
def log_history(all_history, filename):
最後に履歴を保存します。
def save_image(url, filename):
指定urlの画像をロードして、表示したあと保存します。
def get_image_url(prompt):
指定したプロンプトを用いて、画像を生成し、出来上がった画像のurlを返します。画像サイズやクオリティは、今回は固定です。
def log_history(all_history, filename):
with open(filename, 'w',encoding='utf-8') as f:
for message in all_history:
f.write(message+"\n")
print(message)
def save_image(url, filename):
response = requests.get(url)
img = Image.open(BytesIO(response.content))
# 画像を表示
plt.imshow(img)
plt.show()
img.save(filename)
def get_image_url(prompt):
client = OpenAI()
response = client.images.generate(
model="dall-e-3",
prompt=prompt,
size="1024x1024", #1024x1792,1792x1024,1024x1024
quality="hd",# hd/sd
n=1,
)
return response.data[0].url
チャットの設定 メイン前半
#main
client = OpenAI()
#prompt template for chat
chat = ChatOpenAI(
model_name="gpt-4",
temperature=0.7,
max_tokens=1024,
)
memory = ConversationBufferWindowMemory(k=16, return_messages=True)
chat_template="""
画像生成AIにわたすプロンプトを日本語で生成してください。
画像に対する条件(新規、修正、追加)を示しますので、会話履歴を参考に毎回改めてプロンプト全文を生成してください。
回答はプロンプトのみで、指示内容の反復や、了解しましたなどの会話を入れないでください。
コンテンツポリシーに反しないよう、安全かつ適切な内容で生成してください。
"""
# チャットプロンプトテンプレートに `MessagesPlaceholder` を追加することで、履歴対応
prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template(chat_template),
MessagesPlaceholder(variable_name="history"),
HumanMessagePromptTemplate.from_template("{input}")
])
conversation = ConversationChain(llm=chat, memory=memory, prompt=prompt)
チャットの設定をします。gpt4を使って、最大16ターンの会話とします。
本当に16ターンすると、tokenオーバーになるかもしれません。毎回フルプロンプトを生成するつもりなので、ターン数は4-8で十分だと思います。
gpt4を使うほどの処理ではないのですが、今までの条件を忘れたり、うっかり危険なプロンプトを作らない対策を含めてGPT4任せです。
メインループ
img_prompt=""
all_history=[]
while True:
user=input(f'生成したい画像の特徴を指定してください:')
if user == "exit":
break;
ai=conversation.predict(input=user)
print(ai)
all_history.append(user)
all_history.append(ai)
# image create
img_prompt=ai
image_url = get_image_url(img_prompt)
# 画像のURL
print(image_url)
all_history.append(image_url)
filename = "./images/img"+datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+".jpg"
save_image(image_url,filename)
all_history.append(filename)
log_filename="img_log"+datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+".txt"
log_history(all_history,log_filename)
ここでは、プログラムの動作で説明したループが記載されています。
all_historyは、入力、生成プロンプト、生成画像のurl、生成画像の保存ファイルネームを記録します。
なお、生成画像のurlは、多分1時間で有効期限が切れるようです。(正確な時間は未確認ですが、危険は嫌なので、ローカルに保存する形にしています)
実行してみる
実行してみます。5回ほど使って女の子の登校風景を書いてみます。
下の実行結果は、ユーザー入力と生成プロンプトのみ抜粋
なるほどね。女の子の顔がみたいな
ちょっと押しが強すぎるかな。もうちょっと引いてほしい。周りもボケボケはどうなんだろう。ちゃん周囲の人も書いてもらおう
おっと、意外にも完全なイラスト風味。面白いね。風景もほしい。田舎の学校になってもらおう
すっげー。整然と歩いているな。ちょっと怖いよ。こんなに人数はいらない。
まあ、こんな感じかな。
明確なイメージに沿って、狙い通りの映像を作るのは難しいけど、適当な要望をgpt4がちゃんとまとめてくれて、破綻のない映像を作ってくれました。タッチや、風景の描写を細かく指定すれば、どうとでも直せそうだけど色々と絵の変化を楽しむ分にはこんなところでしょう。
最後の絵をGPT-4Vに説明してもらった。
画像は、山々と霧に囲まれた郊外の道路にいる女子学生のグループを描いています。中心にいる少女はカメラをまっすぐ見つめており、短い髪と制服が特徴的です。背後には同じ制服を着た他の少女たちがおり、彼女たちは少しぼんやりしていて、中心の少女よりも注意が向かないように描かれています。全体の雰囲気は平和で、若干神秘的です。これは、高い詳細度を持つ3Dレンダリング画像であり、実写ではなくアートワークです。
まとめ
APIを用いて、DALL-E3で画像を生成しました。
CHATPGPTを用いて、段階的に要望を加えたプロンプトを生成することによって、徐々に希望に沿った映像を得ることができます。
画像編集、加工ではなくプロンプト加工にすることによって、意外な映像が作られて楽しめました。
練習的に書いたのだけどなかなか便利そうな気がします。WEBアプリ化したら結構実用的かもしれません。画像プロンプトも日本語のみで、作成しましたが、全然問題は感じませんでした。
画質に関するテンプレートを、組み合わせ可能にしておけば本当に使えるかもしれませんね。(出来上がったらまた紹介します)
おまけ タイトル画の説明 by GPT-4V
この画像は、作業机の前で頭を抱えて絶望的な表情をしている若い男性のアニメーションされたキャラクターが描かれています。机の上は散らかっており、多数の鉛筆、絵の具、描きかけのスケッチなどで溢れています。背景には、壁に貼られたスケッチやペイントに使われたブラシが見え、クリエイティブな活動、おそらくイラストや美術作品の制作過程が進行中であることが伺えます。男性の表情や周囲の混沌からは、創作におけるフラストレーションやブロックを感じさせるシーンが表現されています。