See some of my favourite generations at the bottom of this post
In part 1 we saw how we can use descriptions generated by GPT-4 as prompts to Midjourney to visualise characters from our favourite novels. In part 2, we will apply the same idea to two more aspects of a novel: 1. locations, such as buildings, houses, or cities; and 2. key events, such as major plot points and famous scenes. This should help bring our favourite novels to life even further!
The code, now updated to include the option to visualise key locations and events, is available on my GitHub: https://github.com/parsaghaffari/Melquiades
Step 1. Listing characters, locations, and events
Our first task is to list all the key “thing”s of the same type from the book; be it characters, locations or events. So let’s modify the get_characters
function to make it a bit more generic so it can generate lists of any of these types of things, not just characters:
@lmql.query(model="openai/gpt-3.5-turbo-instruct")
def get_things(thing_type, book, author="", num_things=5):
'''lmql
"""Answer the following questions about the book {book} by {author}:
Here's a list of major {type_prompt(thing_type)} from the book: \n"""
things=[]
for i in range(num_things):
"-[THING]" where STOPS_AT(THING, "\n")
things.append(THING.strip())
return things
'''
The get_things
function:
thing_type
which can be one of "characters"
, "places"
, or "events"
num_things
things in the response by leveraging LMQL’s scripted prompting featureIf you look at the prompt closely, you will notice that we’re also using a helper function called type_prompt
to sligthly tweak the prompt based on the type of the entity we’re looking to make a list of:
def type_prompt(type):
"""Returns the prompt for the given type of entity"""
if type == "characters":
return "characters"
elif type == "places":
return "places (such as prominent buildings, landmarks, or locations)"
elif type == "events":
return "events (or epic scenes)"
Now if we run get_things("characters", "The Lord of the Rings")
we get:
- Frodo Baggins
- Gandalf
- Aragorn
- Legolas
- Gimli
And get_things("events", "The Lord of the Rings")
returns:
- The formation of the Fellowship of the Ring
- The journey through the Mines of Moria
- The Battle of Helm's Deep
- The Battle of Pelennor Fields
- The destruction of the One Ring in Mount Doom
And finally get_things("places", "The Lord of the Rings")
returns:
- The Shire
- Rivendell
- Moria
- LothlĂłrien
- Isengard
Cool!
Step 2. Generating visually descriptive prompts
Next we need to run through our lists of characters, events, or locations, and ask GPT-4 to write a visual description for each that we can submit to Midjourney.
For instance, here’s our prompt for writing the description of a key event:
@lmql.query(model="gpt-4")
def get_event_description(event, book, author):
'''lmql
"""Here's an accurate and concise visual description of the scene "{event}" from {book} by {author} which can be used as instructions for a painter to paint it with a high level of accuracy and detail. Break down the instructions into meaningful headings (such as characters, their facial expressions, prominent landmarks, etc): [DESCRIPTION]"""
'''
Now if we run get_event_description("The formation of the Fellowship of the Ring", "The Lord of the Rings")
we get:
1. Characters:
- Gandalf: Depict him as an old, wise wizard with a long white beard, wearing a grey cloak and hat, holding a staff.
- Frodo: A small hobbit with curly hair, wearing a waistcoat and trousers, holding the One Ring.
- Sam, Merry, and Pippin: Three hobbits, smaller than the human characters, dressed in typical hobbit attire.
- Aragorn: Tall, rugged, with long hair and a beard, wearing a travel-worn outfit, holding a sword.
- Legolas: An elf with long blonde hair, sharp features, dressed in green and brown, holding a bow and arrow.
- Gimli: A dwarf, shorter than the others, with a thick beard, wearing armor and holding an axe.
- Boromir: A man with short dark hair, wearing armor and a cloak, holding a shield and sword.
2. Facial Expressions:
- Gandalf: A serious, determined expression.
- Frodo: A look of fear and determination.
- Sam, Merry, and Pippin: Expressions of worry but also bravery.
- Aragorn: A stern, focused expression.
- Legolas: A calm, composed expression.
- Gimli: A fierce, ready-for-battle expression.
- Boromir: A conflicted, yet resolved expression.
3. Prominent Landmarks:
- The Council of Elrond: Depict a circular stone table surrounded by various characters, set in a beautiful garden filled with exotic plants and trees.
- Rivendell: The elven city in the background, with its unique architecture, bridges, and waterfalls.
4. Atmosphere:
- The scene should be set in daylight, but with a sense of impending darkness.
- The characters should be positioned as if they are ready to embark on a journey, facing towards the viewer.
5. Details:
- The One Ring: Frodo should be holding the ring, which should be depicted as a simple gold band.
- Weapons: Each character's weapon should be clearly visible and accurately represented.
- Costumes: Each character's outfit should reflect their respective cultures and statuses as described in the book.
That’s a quite neat description and encompasses a lot of detail!
Similarly we will also implement get_character_description
and get_place_description
with slightly different prompts which you can see here.
Step 3. Visualising events and locations
We now have our prompts for a key location or a key event, and can start visualising them using Midjourney. We will reuse the same functions as we did in part 1, such as mj_imagine
to make this happen.
If we run this on the prompt we generated for “The formation of the Fellowship of the Ring”, Midjourney will draw 4 options which can create variations of or upscale like before:
And voilĂ ! Just like that we can visualise the key events and locations from our favourite novels.
As a reminder, I’ve wrapped all of the above functionality in a visual Streamlit app which you can get from here: https://github.com/parsaghaffari/Melquiades
Some final thoughts:
I’ve listed some of my favourite generations below:
A Song of Ice and Fire (Game of Thrones)
The Lord of the Rings
Dune
One Hundred Years of Solitude
The Old Man and the Sea
To Kill a Mockingbird