简介

在这个笔记本中,我们将重点关注图像条件化功能,它可以通过提供参考图像和文本提示来生成遵循参考图像布局和结构的输出。支持两种模式:

  • Canny边缘: 从参考图像中提取突出的边缘,以引导生成过程。
  • 分割: 定义参考图像中的特定区域/对象,让模型生成与这些区域对齐的内容。

用例

OctankFashion可以利用图像条件化功能自动生成其广告创意的多个变体。例如,他们可以通过调整视觉焦点、背景或造型元素来创建婚纱图像的不同版本,这些都基于提供的参考图像。这使他们能够更有效地快速测试和优化广告内容,更好地响应客户偏好和新兴趋势。

先决条件: 请先运行 00-prerequisites.ipynb 中的先决条件。

import io
import json
import base64
import boto3
from botocore.config import Config
from PIL import Image
from utils import save_image, plot_image_conditioning

bedrock_runtime_client = boto3.client(
    "bedrock-runtime",
    region_name="us-east-1",
    config=Config(
        read_timeout=5 * 60
    ),  # 重要: 将读取超时时间增加到5分钟,以支持更长的操作。
)
image_generation_model_id = "amazon.nova-canvas-v1:0"
output_dir = "output"

图像条件化

图像条件化允许用户使用参考图像来引导图像创作。

示例 1: 探索"分割"控制模式

当使用"分割"控制模式时,“条件图像"将被自动分析以识别突出的内容形状。这种分析结果是一个分割掩码,它引导生成图像的构图。“分割"控制模式比"Canny边缘"模式给予模型更多自由度,非常适合摆姿势、确定摄像机角度等。

我们将使用"分割"控制模式将下面的草图转换为美丽的照片。运行下面的单元格,生成的图像将保存到"output"文件夹。

# 条件参数
condition_image = "images/designer_sketch_dress.png"
control_mode = "SEGMENTATION"
control_strength = 0.4  # 范围: 0.2 到 1.0

prompt = "fashion photo of a woman in an elegant wedding dress, coastal backdrop"

# 输出宽度和高度应与条件图像的纵横比相匹配,以获得最佳效果
width = 1024
height = 1024

seed = 102
# 对参考图像进行编码
with open(condition_image, "rb") as image_file:
    reference_image_base64 = base64.b64encode(image_file.read()).decode("utf-8")

# 根据参考图像生成图像
body = json.dumps(
    {
        "taskType": "TEXT_IMAGE",
        "textToImageParams": {
            "text": prompt,  # 必需
            "conditionImage": reference_image_base64,  # 可选
            "controlMode": control_mode,  # 可选: CANNY_EDGE | SEGMENTATION
            "controlStrength": control_strength,  # 范围: 0.2 到 1.0,
        },
        "imageGenerationConfig": {
            "numberOfImages": 1,  # 要生成的图像数量,最多5张
            "width": width,
            "height": height,
            "cfgScale": 6.5,  # 提示将被多大程度地遵循
            "seed": seed,
            "quality": "premium",  # 质量为"standard"或"premium"
        },
    }
)

print("正在生成图像...")

response = bedrock_runtime_client.invoke_model(
    body=body,
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body = json.loads(response.get("body").read())
response_images = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body.get("images")
]

# 保存输出
output_image_path = f"{output_dir}/06-image-conditioning.png"
save_image(response_body.get("images")[0], output_image_path)
print(f"图像已保存到 {output_image_path}")

# 绘制输出
plot_image_conditioning(condition_image, response_images, prompt)
💡 额外活动: 尝试不同的提示来改变环境、服装细节或艺术风格。
示例 2: 探索"Canny边缘"条件化

当使用"Canny边缘"控制模式时,生成图像的元素将遵循条件图像的突出轮廓或"边缘”。这些边缘被尊重的程度取决于"controlStrength"参数的值。

我们将使用以下图像作为"conditionImage”。运行下面的单元格,生成的图像将保存到"output"文件夹。

# 条件参数
condition_image = "images/wedding_dress_details.png"
control_mode = "CANNY_EDGE"
control_strength = 0.9  # 范围: 0 到 1.0

# 输出宽度和高度应与条件图像的纵横比相匹配,以获得最佳效果
width = 720
height = 1024

prompt = "A light blue dress with elegant details"

seed = 99  # 可以是0到214783647之间的任何数字
# 对参考图像进行编码
with open(condition_image, "rb") as image_file:
    reference_image_base64 = base64.b64encode(image_file.read()).decode("utf-8")

# 根据参考图像生成图像
body = json.dumps(
    {
        "taskType": "TEXT_IMAGE",
        "textToImageParams": {
            "text": prompt,
            "conditionImage": reference_image_base64,
            "controlMode": control_mode,  # "CANNY_EDGE" 或 "SEGMENTATION"
            "controlStrength": control_strength,  # 范围: 0 到 1.0,
        },
        "imageGenerationConfig": {
            "numberOfImages": 1,  # 要生成的图像数量,最多5张
            "cfgScale": 6.5,  # 提示将被多大程度地遵循
            "width": width,
            "height": height,
            "seed": seed,
            "quality": "standard",  # 质量为"standard"或"premium"
        },
    }
)

print("正在生成图像...")

response = bedrock_runtime_client.invoke_model(
    body=body,
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body = json.loads(response.get("body").read())
response_images = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body.get("images")
]

# 保存输出
output_image_path = f"{output_dir}/06-image-conditioning_canny-edge.png"
save_image(response_body.get("images")[0], output_image_path)
print(f"图像已保存到 {output_image_path}")

# 绘制输出
plot_image_conditioning(condition_image, response_images, prompt)
💡 额外活动: 尝试不同的 controlStrength 值和不同的提示,观察它们的影响。
示例 3: 探索"controlStrength"参数

条件图像生成功能允许用户通过调整"controlStrength"参数来调整条件图像对生成输出的影响。该参数取值范围为0.2到1.0,较低的值会引入更多随机性,较高的值会使生成的图像更紧密地遵循条件图像的布局和构图。“controlStrength"参数的默认值为0.7。

为了说明"controlStrength"参数的效果,让我们使用相同的文本提示和条件图像,但使用三个不同的值来生成图像。

# 条件参数
condition_image = "images/evening_gown.png"
control_mode = "CANNY_EDGE"
control_strength_values = [0, 0.25, 1.0]  # 范围: 0 到 1.0

prompt = "a women's T-shirt and short jeans showcased in a shopping window"

# 输出宽度和高度应与条件图像的纵横比相匹配,以获得最佳效果
width = 1024
height = 1024

seed = 102  # 100  # 可以是0到214783647之间的任何随机数
# 对参考图像进行编码
with open(condition_image, "rb") as image_file:
    reference_image_base64 = base64.b64encode(image_file.read()).decode("utf-8")

# 使用不同的similarityStrength值生成图像
generated_images = []
for index, control_strength in enumerate(control_strength_values):
    print(f"正在生成第{index+1}张图像,共{len(control_strength_values)}张...")

    response = bedrock_runtime_client.invoke_model(
        body=json.dumps(
            {
                "taskType": "TEXT_IMAGE",
                "textToImageParams": {
                    "text": prompt,  # 必需
                    "conditionImage": reference_image_base64,  # 可选
                    "controlMode": control_mode,  # 可选: CANNY_EDGE | SEGMENTATION
                    "controlStrength": control_strength,  # 范围: 0.2 到 1.0,
                },
                "imageGenerationConfig": {
                    "numberOfImages": 1,  # 要生成的图像数量,最多5张
                    "cfgScale": 6.5,  # 提示将被多大程度地遵循
                    "width": width,
                    "height": height,
                    "seed": seed,
                    "quality": "standard",  # 质量为"standard"或"premium"
                },
            }
        ),
        modelId=image_generation_model_id,
        accept="application/json",
        contentType="application/json",
    )

    response_body = json.loads(response.get("body").read())

    # 保存图像
    output_image_path = (
        f"{output_dir}/06-image-conditioning_controlStrength_{control_strength}.png"
    )
    base64_images = response_body.get("images")
    save_image(base64_images[0], output_image_path)
    print(f"图像已保存到 {output_image_path}")

    generated_img = [
        Image.open(io.BytesIO(base64.b64decode(base64_image)))
        for base64_image in response_body.get("images")
    ]
    generated_images.append(generated_img[0])

# 绘制比较图像
plot_image_conditioning(
    condition_image,
    generated_images=generated_images,
    control_strength_values=control_strength_values,
    prompt=prompt,
    comparison_mode=True,
)

观察到,当使用较低的"controlStrength"值时,生成的图像将主要遵循文本提示的内容,只会从条件图像的布局和构图中受到微妙的影响。随着值的增加,条件图像的影响变得更加显著。

用户应该根据他们希望在遵循文本提示和遵循条件图像结构之间达到的平衡来调整该参数,同时考虑正在使用的特定文本提示和条件图像。

总结

使用Nova Canvas模型的图像条件化功能为用户提供了直接控制生成图像的布局、结构和视角的能力。

我们鼓励用户探索Amazon Bedrock中这些新功能,体验创建精确、定制视觉内容的扩展潜力。