Amazon Titan Image Generator のプロンプトエンジニアリングガイドを見ながらあれこれ

## はじめに
AWSの生成AIサービスAmazon Bedrockでは、様々な基盤モデルを使うことができますが、その中の画像生成モデルにTitan Image Generatorがあります。

ふと思い立ってAmazon Titan Image Generatorを使って遊ぼうと思ったのですが、プロンプトをどう書けばいいのか自信がなかったので、こちらの [Titan Image Generator のプロンプトエンジニアリングガイド](chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://d2eo22ngex1n9g.cloudfront.net/Documentation/User+Guides/Titan/Amazon+Titan+Image+Generator+Prompt+Engineering+Guidelines.pdf)を読んでいきたいと思います。

## 画像生成のプロンプトの構成要素

一般的に、image-to-textやimage-and-text-to-imageを行う基盤モデルのプロンプトの構成要素は以下のものがあります。

- テキスト記述：欲しい画像に対するテキストでの説明。被写体、スタイル、構成などの詳細情報を記述できる。

- 画像の条件：ベースとなる参照画像を指定することが可能。モデルへの前提条件として与えて、追加の指示をすることができる。

- ガイドトークン：「写実的」「映画調の照明」などの、より高レベルの指示を与えるための特別なトークン。モデルへのキーワード指定のようなイメージ。

- パラメータの選択：画像の解像度、サンプリング手法、反復回数などを指定して、最終的な出力を制御する。

## 画像生成モデルのプロンプトエンジニアリングとは？

テキストから画像、もしくは、テキストと画像から画像を生成するために基盤モデルに入力するプロンプトを作成、改善するプロセスをプロンプトエンジニアリングといいます。

プロンプトエンジニアリングの重要な要素は以下の通りです。

- 単語の吟味：視覚的な情報を詳細に伝える説明的な単語やフレーズを選択する。曖昧な表現を使うよりも、鮮明で具体的な単語を使う方がうまくいく。

- スタイルとトーン：会話調、詩的、ユーモラスな方法で、生成される画像の雰囲気やスタイルを制御する。

- 構成：論理的なプロンプト構成要素の順序と、句読点を使った構成の指定。例えば、カンマを使って文節を区切ったり、コロンを使って説明文に導いたりする。

- 指示の詳細：オブジェクトの形状、色、照明、背景などの詳細情報を追加して、生成する画像の範囲を絞り込む。

- ネガティブプロンプト：生成する画像の中に含めたくない要素を指定する。

- 反復的な改善：結果に基づいて、プロンプトを段階的に改善する。

- 例として画像を与える：既存の画像に対する説明をプロンプトに流用する

プロンプトエンジニアリングの目的は、画像生成モデルに所望の画像を生成してもらうために最適なプロンプトを作ることです。大規模言語モデルと同様に、画像生成モデルにおいても、プロンプトエンジニアリングは重要です。

## Amazon Titan Image Generator のプロンプト

Titanを使った画像生成でも、一般的なtext-to-imageのテクニックが有効。Titanならではのテクニックとしては、ダブルクオーテーションを使った引用が挙げられます。たとえば、
「An image of a boy holding a sign that says "success"」の方が「An image of a boy holding a sign that says 'success'」よりも良い書き方とされます。

一般的に、以下の書き方がおすすめ。
- プロンプトは主語から始める。「An image of a ...」
- できるだけ詳細情報をプロンプトに含める。必要に応じて、希望する媒体、色、照明、備考、形容詞、品質、およびスタイルを含める。
- 具体的なプロンプトを使用し、必要に応じてネガティブプロンプトを使用する。
- モデルのパラメータを使う。

## インペインティング、アウトペインティング

インペインティングとアウトペインティングは、画像、テキストプロンプト、マスク（オプション）を入力とする画像生成手法です。マスクは、マスク画像を入力にするか、マスクしたい領域を指定するためのプロンプトとして入力することができます。マスクプロンプトが使用された場合、Titanのセグメンテーションアルゴリズムを使ってマスク画像が内部で生成されます。

### インペインティング

一般的に、インペインティングはマスク内の領域を再生成する処理です。

#### 実験

Titan Image Generatorのインペインティング機能を使った実験をしてみました。以下の画像は、参照画像として入力した画像です。
![original-cat.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/0a8734c8-d7ff-2922-b1d1-4f2f77c91510.jpeg)

この画像に、以下のプロンプトを指定してインペインティングを実行してみました。
プロンプト：white, fluffy cat, long fur, cute, adorable, soft, furry, feline, pet
ネガティブプロンプト：ugly, scary, deformed, disfigured, creepy, disturbing, low quality, blurry
マスクプロンプト：a brown tabby cat

すると、画像の中央にいた茶色い縞猫が白猫に返信しました！
背景は元画像のままです。

![change-cat.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/6eb604ec-bf3e-806e-fcc2-0e9da24a45cc.jpeg)

### アウトペインティング

一般的に、アウトペインティングはマスクされた領域を自然に外側に拡張する処理です。

#### 実験

Titan Image Generatorのアウトペインティング機能を使った実験をしてみました。以下の画像は、参照画像として入力した画像です。
![original-cat.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/0a8734c8-d7ff-2922-b1d1-4f2f77c91510.jpeg)

この画像に、以下のプロンプトを指定してアウトペインティングを実行してみました。
プロンプト：summer, vibrant blue sky, sandy beach, crystal clear ocean, bright sunlight, beach umbrellas, tropical paradise, seaside resort
ネガティブプロンプト：blurry, low quality, disfigured, deformed, ugly, scary, creepy, disturbing, overcast, cloudy
マスクプロンプト：a cat

すると、猫の背景が夏のビーチになりました！
猫は元画像のままです。

![outpainting-back.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/6055b411-c370-f6a8-bf08-9ad95cf8f491.jpeg)

### マスクプロンプト

マスク画像を用意できる場合はそちらの方がより良い画像を得られる可能性が高いですが、面倒だなという場合はマスクプロンプトでマスクしたい部分を説明して、Titanに内部でマスク画像を生成してもらうことができます。

マスクしたい領域が正確にマスクされるように、具体的な説明テキストを作る必要があります。

たとえば、こんな画像があったとき、
![two-cats.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/b6b77e75-d87b-c409-7092-7161379fb63d.jpeg)

マスクプロンプトに「cat」とだけ書いてインペインティングを実行すると、猫が両方とも書き変わってしまいます。
![two-cats-brown.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/b898964a-3226-8543-92aa-d81ed5111b0b.jpeg)

なので、白い猫のみを変えたい場合は、「white cat」と書きましょうという話でした。
![two-cats-no-white.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/67834a8f-3ba9-6ad6-4121-29381d3ed1c6.jpeg)

### 物体除去のときのプロンプト

画像の中から特定の何かを除去したい場合は、テキストプロンプトをからっぽにする必要があります。

### インペインティングで物体を置き換える場合のプロンプト

- マスク領域内で再構築するコンテンツとその独自の特徴/属性（例：色、視点など）を正確に記載する。
- （任意）インペインティングが再構築をより現実的に改善するのに役立つ、オブジェクトのコンテキスト/背景に関する詳細情報を記載する。

何もなかったところに人を立たせたいな、と思った時に、単に「person」と書くと、何らかの人が追加されますが、「A person running a marathon」と書くと、ランニングウェアに身を包んだ人が追加されるイメージですね。

誰も座っていないベンチに誰かを座らせたい場合も、「person」よりも、「A person sitting on a bench facing the camera」まで書くと、だいぶイメージ通りの人が追加されるはずです。

### アウトペインティングのプロンプト

インペインティングと同等のプロンプトの精密さが必要です。アウトペイントする背景の詳細な説明を多く提供するほど、期待通りの画像が生成されます。

「A person」よりも「A person talking to another person」
「A dog」よりも「A dog sitting on a bench next to a woman」

## 画像のバリエーション生成 (Image Variations)

バリエーション生成は、画像とテキストプロンプト（オプション）を入力として、入力画像の内容を保持しつつも少し変化させた画像を生成する機能です。テキストプロンプトには、入力画像の中で保持しておきたい部分の詳細な説明を記載する必要があります。

### 実験

この画像をベース画像にして画像のバリエーションを生成してみました。
![two-cats.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/9e33b08a-11c5-a9f8-87aa-4fd2181a3a40.jpeg)

まずは、テキストプロンプト「two cats」と指定した結果。2匹の猫が並んで座っています。
![スクリーンショット 2024-07-31 17.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/fc3606f2-8dad-45e0-ca6e-3051b85184c3.png)

次は、テキストプロンプト「two cats, one white cat, one black cat」と指定。指示通り、白猫と黒猫が1匹ずつ並んで座っています。
![スクリーンショット 2024-07-31 17.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/7ee6ac56-3b6b-5a75-fcc3-9a48415bd87b.png)

参考までに、画像のバリエーション機能ではなく、単純な画像生成で上記プロンプトを実行すると、以下のような結果になります。2匹の猫が割と自由な感じで表現されています。ベース画像を与えることで、2匹の猫がお行儀よく並んでいる様子を保持した状態でバリエーション生成できていることがわかりました。
![スクリーンショット 2024-07-31 17.58.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/75cfea3a-9747-b321-3222-71befa993bd9.png)

## さいごに

Amazon Titan Image Generatorのプロンプトエンジニアリングガイドを見ながら、いろいろと実験してみました。試せば試すほど、奥が深いと感じます。欲しい画像をサクッと生成できるようになるために、これからも精進を続けたいと思います。

この記事では、[GenU](https://github.com/aws-samples/generative-ai-use-cases-jp)というOSSのツールの画像生成機能を使って実験しました。Amazon Titan Image Generatorを有効にするために、`packages/cdk/cdk.json`の`imageGenerationModelIds`に`amazon.titan-image-generator-v1`を追加しました。