見出し画像

DALL-E3のプロンプトを構造化し、キャラクターを自在に操る

DALL-E3いいですよね!
これだけ素晴らしいと小説の挿絵や漫画とかに使いたくなりますが…結構大きな問題があります。

「同じキャラクターが作れない!」

小説や漫画の場合は結構致命的です。沢山生成して選んでいく事になりますが、生成に時間がかかるので、相当なストレスになります。これを何とかしよう!という考察になります。

なぉ、この記事は「ChatGPT plus」を利用している事が前提になりますのでご了承下さい。

まずは、プロンプトをどうするか?ですが、過去に私が書いたブログでこんな文章を見つけました。

「言葉は伝え方と受け取り方次第で誤解を生みますが、プログラムは書かれた通りにしか動かないので誤解を生みません。」

私は正直、日本語よりプログラミング言語のが得意です。ならば、初心に帰り、プログラム言語的なアプローチで考えましょう!

オブジェクト指向的な考え方

プログラムと言えばオブジェクト指向ですね!
私が思いついたアイデアをChatGPTさんに代弁してもらいます。

構造化データ形式JSON

オブジェクト指向的な考え方を元に、キャラクターの見た目を正確に表現するには、キャラクターの特徴を構造化したデータ形式が必要となります。キャラクターの情報を「JSONデータ」で整理することにより、キャラクターをよりリアルに描写できると考えられます。

例えば、主要なキャラクターを考えてみましょう。JSONを使った場合、キャラクターの属性や特徴(髪の色、目の色、身長など)をオブジェクトのプロパティとして表現でき、それらのオブジェクトをキャラクターのリストとして管理できます。

このような構造化データを使用することで、読者にキャラクターの外見を詳細に伝えることができ、物語の中でキャラクターの外観が変化する場合にも整合性を保つのに役立ちます。オブジェクト指向的なアプローチは、物語の中で複雑なキャラクター関係をモデル化し、読者にとってもキャラクターがリアルに感じられるようになります。JSONデータというツールを使えば、物語のキャラクターをより深く掘り下げ、読者に魅力的なイメージを提供できるでしょう。

…という感じです!

JSONデータが何か?って話ですが、分からない方はとりあえずテキストのフォーマットみたいなものという理解で読み進んでいただければと思います。

まぁ、習うより慣れろです。やってみましょう!

キャラクターデザインの確定

まずはキャラクターの絵を決めましょう。
自分で絵が描ける方はそれでも良いかもしれませんが、やはりDALL-E3に描いてもらいたいねですよね?
ここはプロンプト気にせず、思うがままに、お気に入りのキャラクターを描いてもらいましょう!

描けましたか?

例えば、こんな絵ですね!

この絵をChatGPT-4Vを使ってJSON化します。JSONのテンプレートは私がGPT-3.5を利用して作っておきました。参考にして下さい。
下記のように指示しましょう。

### この絵の女の子を元に下記のJsonデータの値を埋めて下さい。不明点は想像で埋めて下さい
{
  "Art Style": "???",
  "Color Palette": "???",
  "Background": "???",
  "Image Size": {
    "Width": ???,
    "Height": ???
  },
  "Character Information": [
    {
      "Character": "???",
      "Age": ???,
      "Action": {
        "Expression": "???",
        "Pose": {
          "Upper Body": {
            "Arm Position": "???",
            "Upper Body Orientation": "???"
          },
          "Lower Body": {
            "Leg Position": "???",
            "Alternate Position": "???"
          }
        }
      },
      "State": {
        "Outfit": {
          "Top": {
            "Type": "???",
            "Design": "???",
            "Color": "???"
          },
          "Bottom": {
            "Type": "???",
            "Design": "???",
            "Color": "???"
          }
        },
        "Race/Ethnicity": "???",
        "Appearance": {
          "Face": {
            "Eyes": {
              "Shape": "???",
              "Right Eye": {
                "Color": "???"
              },
              "Left Eye": {
                "Color": "???"
              }
            },
            "Nose": {
              "Shape": "???"
            },
            "Mouth": {
              "Shape": "???",
              "Lip Color": "???"
            },
            "Eyebrows": {
              "Shape": "???",
              "Color": "???"
            }
          },
          "Hairstyle": {
            "Style": "???",
            "Hair Color": "???",
            "Hair Length": "???",
            "Bangs": "???"
          },
          "Physical Features": {
            "Height": "???",
            "Body Type": "???",
            "Skin Color": "???"
          },
          "Gender": "???",
          "Accessories": [
            {
              "Type": "???",
              "Position": "???"
            }
          ],
          "Distinctive Mark": [
            "???",
            "???"
          ]
        }
      }
    }
  ]
}

画像は以前にClaude2で生成した小説に登場する「星間の約束」のゼリエリアになりますね。
なお、このテンプレートはゼリエリア仕様となっておりますので、左右の目の色まで指定しています。この辺りの項目はキャラクターの特徴に合わせて変更してもChatGPT側で良い様に解釈してくれますので、これじゃなきゃダメというのは無いです。

では、この結果をそのままプロンプトにしてChatGPTのDALL-E3の機能を利用して画像を生成してみましょう。

プロンプトと画像は下記になりました。

{
  "Art Style": "Anime/Manga",
  "Color Palette": "Vibrant with cool tones",
  "Background": "Starry space with a futuristic spaceship",
  "Image Size": {
    "Width": "768",
    "Height": "768"
  },
  "Character Information": [
    {
      "Character": "Unknown Female Character",
      "Age": "Teenager (estimated)",
      "Action": {
        "Expression": "Calm",
        "Pose": {
          "Upper Body": {
            "Arm Position": "One hand on chest",
            "Upper Body Orientation": "Front"
          },
          "Lower Body": {
            "Leg Position": "Not visible",
            "Alternate Position": "Not visible"
          }
        }
      },
      "State": {
        "Outfit": {
          "Top": {
            "Type": "Loose Blouse",
            "Design": "Plain",
            "Color": "White"
          },
          "Bottom": {
            "Type": "Not visible",
            "Design": "Not visible",
            "Color": "Not visible"
          }
        },
        "Race/Ethnicity": "Anime (ambiguous)",
        "Appearance": {
          "Face": {
            "Eyes": {
              "Shape": "Large, Almond",
              "Right Eye": {
                "Color": "Blue with hints of purple and pink"
              },
              "Left Eye": {
                "Color": "Pink with hints of purple and blue"
              }
            },
            "Nose": {
              "Shape": "Small and subtle"
            },
            "Mouth": {
              "Shape": "Small, Neutral",
              "Lip Color": "Light Pink"
            },
            "Eyebrows": {
              "Shape": "Delicate, slightly arched",
              "Color": "Light Gray"
            }
          },
          "Hairstyle": {
            "Style": "Straight with a side parting",
            "Hair Color": "Silver/White",
            "Hair Length": "Long, reaching past her back",
            "Bangs": "Straight cut"
          },
          "Physical Features": {
            "Height": "Average (estimated)",
            "Body Type": "Slender",
            "Skin Color": "Fair"
          },
          "Gender": "Female",
          "Accessories": [
            {
              "Type": "Ornamental hairpiece",
              "Position": "On her hair, right side"
            }
          ],
          "Distinctive Mark": [
            "Galaxy/star pattern in her hair",
            "Mismatched eye colors"
          ]
        }
      }
    }
  ]
}
ゼリエリア

なかなかいい具合に再現されているのでは無いでしょうか?
人物以外は全く詳細の情報を取得していないので、宇宙船が円盤になっているなど、全く別物ですね。このあたりの対比が面白いところです。

では、このプロンプトを利用して、ゼリエリアに別の行動をさせたいと思います。プロンプトを直接変更しても良いのですが、面倒ですよね!
ChatGPT-3.5にサクッと修正してもらいましょう!

こんなプロンプトです!(先ほど生成したJSONデータは省略しています)

### 下記のJsonデータのキャラクターが日本の公園で楽しそうに遊んでいて、躍動感ある感じに想像して値を変更して下さい。Appearanceは絶対に変えないで下さい
(ここにJSONデータをコピペ)

出力内容

{
  "Art Style": "Anime/Manga",
  "Color Palette": "Vibrant with cool tones",
  "Background": "Japanese Park with Cherry Blossom Trees",
  "Image Size": {
    "Width": "768",
    "Height": "768"
  },
  "Character Information": [
    {
      "Character": "Unknown Female Character",
      "Age": "Teenager (estimated)",
      "Action": {
        "Expression": "Joyful",
        "Pose": {
          "Upper Body": {
            "Arm Position": "Both hands in the air",
            "Upper Body Orientation": "Front"
          },
          "Lower Body": {
            "Leg Position": "Jumping",
            "Alternate Position": "Running"
          }
        }
      },
      "State": {
        "Outfit": {
          "Top": {
            "Type": "Loose Blouse",
            "Design": "Floral Pattern",
            "Color": "Pink"
          },
          "Bottom": {
            "Type": "Skirt",
            "Design": "Flowy",
            "Color": "White"
          }
        },
        "Race/Ethnicity": "Anime (ambiguous)",
        "Appearance": {
          "Face": {
            "Eyes": {
              "Shape": "Large, Almond",
              "Right Eye": {
                "Color": "Blue with hints of purple and pink"
              },
              "Left Eye": {
                "Color": "Pink with hints of purple and blue"
              }
            },
            "Nose": {
              "Shape": "Small and subtle"
            },
            "Mouth": {
              "Shape": "Smiling",
              "Lip Color": "Light Pink"
            },
            "Eyebrows": {
              "Shape": "Delicate, slightly arched",
              "Color": "Light Gray"
            }
          },
          "Hairstyle": {
            "Style": "Straight with a side parting",
            "Hair Color": "Silver/White",
            "Hair Length": "Long, flowing in the wind",
            "Bangs": "Swept to the side"
          },
          "Physical Features": {
            "Height": "Average (estimated)",
            "Body Type": "Slender",
            "Skin Color": "Fair"
          },
          "Gender": "Female",
          "Accessories": [
            {
              "Type": "Ornamental hairpiece",
              "Position": "On her hair, right side"
            },
            {
              "Type": "Cherry Blossom Hairpin",
              "Position": "Left side"
            }
          ],
          "Distinctive Mark": [
            "Galaxy/star pattern in her hair",
            "Mismatched eye colors"
          ]
        }
      }
    }
  ]
}

「Appearanceを絶対変えるな」って指示していますが、変えられてしまっていますね(笑)
Appearanceはキャラクターの基本情報なので変えられたくないところですが、自然に見せるためには変えなくてはいけない箇所もあるかもしれません。良しとしましょう。
気に入らない場合は、手作業でも修正できますので、大きく変えられた場合は手修正すればOKですね。

これを何も修正せず、DALL-E3に画像生成してもらいましょう!

公園で遊ぶゼリエリア①
公園で遊ぶゼリエリア②
公園で遊ぶゼリエリア③

3枚生成してくれました。
最後の画像は目の色の左右が逆ですが、おおむね良好ですね!
キャラクターの特徴をとらえたまま、動きのある画像が生成できています!

あと、細かいところを指摘したらキリがないですが、同じキャラクターという認識できるレベルの絵であれば、このプロンプトで行けそうですね!
服とかの多少の差異はありますが…

「ガンダムのアニメだって、壊れて無くなったモビルスーツの腕が、次のシーンで復活したりしてるからセーフ!」

といっておきましょう!

JSON形式のデータに詳しい方が見ると気が付くと思いますが、"Character Information"が実は配列になっています。これが何を意味するかというと、「複数キャラクターを同時に登場させられる!」という事になります。この記事のタイトルの画像のようなものです。ですが…

「似たようなキャラ2人の場合は混じります!」

悟空とベジータなんて間違いなくフュージョンしますね!男性、女性、動物なんかだと大丈夫な気がします。これは、最終的にChatGPTがDALL-E3に与えるプロンプトがあると思いますが、その生成部分に課題があるのかもしれません。

このJSONベースのデータはキャラクターの基礎情報として非常に有用かと思います。プロンプトエンジニアリングのテクニックは、生成AIの進化とともに変わっていきますので、いつまでも使えるものではないと思います。しかし、プログラムにしろJSONにしろ、現実には基本なくなりませんので、このような情報は未来永劫使えそうな気がしますね!物語生成の整合性チェックにも使えそうです。

現在のところでは、作画のためのプロンプト自体をこの基礎情報に近づける仕組みの考察などが必要そうな気もします。ただ、細かいテクニックを頑張っても、恐らく時代の進歩の方が早いので、無理せず楽しんでいきましょう!

とにかく沢山生成すれば、そのうち理想の絵が出てくるって考え方が基本ですね!


【 自分用メモ 】

この記事は試行錯誤しながら作成しましたので、アイデアとしては有効ですが、まだ洗練されていないところが多くあるかと思います。
ですので、最新の自分用のプロンプトをメモとして下記に配置します。
自分用ですが、参考にしていただけると嬉しいです。

キャラクターを構造化するためにGPT-4Vに渡すプロンプト

### この絵に描かれているすべてのキャラクターを元に下記のJsonデータの値を埋めて下さい。配列で指定しているところは最大3として必要な数だけ出力してください。不明点は想像で埋めて下さい
{
  "Art Style": "???",
  "Color Palette": "???",
  "Background": "???",
  "Image Size": {
    "Width": ???,
    "Height": ???
  },
  "Characters": {
    "???":{
      "Action": {
        "Expression": "???",
        "Pose": {
          "Upper Body": {
            "Arm Position": "???",
            "Upper Body Orientation": "???"
          },
          "Lower Body": {
            "Leg Position": "???",
            "Alternate Position": "???"
          }
        }
      },
      "State": {
        "Outfit": {
          "Top": {
            "Type": "???",
            "Design": "???",
            "Color": "???"
          },
          "Bottom": {
            "Type": "???",
            "Design": "???",
            "Color": "???"
          }
        },
        "Characteristics": {
          "Gender": "???",
          "Race/Ethnicity": "???",
          "Occupation": "???",
          "Age": "???",
          "Face": {
            "Eyes": {
              "Shape": "???",
               "Color": "???"
              },
            },
            "Nose": {
              "Shape": "???"
            },
            "Mouth": {
              "Shape": "???",
              "Lip Color": "???"
            },
            "Eyebrows": {
              "Shape": "???",
              "Color": "???"
            }
          },
          "Hairstyle": {
            "Style": "???",
            "Hair Color": "???",
            "Hair Length": "???",
            "Bangs": "???"
          },
          "Physical Features": {
            "Height": "???",
            "Body Type": "???",
            "Skin Color": "???"
          },
          "Accessories": [
            {
              "Type": "???",
              "Position": "???"
            }
          ],
          "Distinctive Mark": [
            "???",
            "???"
          ]
        }
      }
    }
  }
}

実際に描画するときにJSONデータの前に配置するプロンプト

### Provide images based on the following JSON.
### Instruct to draw the same number of characters as in the 'Characters' array, ensuring that each one is distinctly different, and provide prompts accordingly. Additionally, create all of these in a single image.
### Ensure that the content written in 'Distinctive Mark' is always included in that person's prompt without fail, and make sure it is not applied to a different character.
### Specify the seed value as 'xxxx'.

いいなと思ったら応援しよう!