图像变化简介

亚马逊 Nova Canvas 提供了一种称为"IMAGE_VARIATION"的任务类型。图像变化是一种多功能的功能,有多种用途。根据我们提供的参数,图像变化可以帮助我们:

  1. 根据该主题的图像生成该主题的新图像
  2. 通过提供该样式的示例,引导模型以特定的视觉样式生成图像
  3. 混合和组合多个参考图像的样式,创造出独特的样式

这为生成复杂而引人入胜的图像开辟了新的创意可能性,而无需复杂的提示工程或模型微调。

用例

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_images, plot_images_for_comparison

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: 创建输入图像的变体

为了展示图像变化的强大功能,我们将生成两个具有相同提示和种子值的图像。第一个图像将在没有任何参考图像的情况下生成。第二个将使用下面的参考图像。运行下面的单元格。生成的图像将保存到"output"文件夹。

# 定义主要输入参数。
reference_image_path = "images/wedding_dress.png"
similarity_strength = (
    0.7  # 输入图像对输出的影响程度。从0.2到1。
)

text = "A pink wedding dress"

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

print("Generating image without a reference image...")

# 生成没有参考图像的图像
response_without_ref = bedrock_runtime_client.invoke_model(
    body=json.dumps(
        {
            "taskType": "TEXT_IMAGE",
            "textToImageParams": {"text": text},
            "imageGenerationConfig": {
                "numberOfImages": 1,  # 要生成的图像数量,最多5张。
                "cfgScale": 6.5,  # 提示将被多大程度地遵循
                "seed": seed,  # 从0到858,993,459的任何数字
                "quality": "standard",  # "standard"或"premium"。默认为"standard"。
            },
        }
    ),
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body_without_ref = json.loads(response_without_ref.get("body").read())

images_without_ref = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body_without_ref.get("images")
]

# 保存输出
image_without_reference_path = f"{output_dir}/05-image-variation_no-reference.png"
save_image(response_body_without_ref.get("images")[0], image_without_reference_path)
print(f"Saved image without reference to {image_without_reference_path}")

print("Generating image with a reference image...")

# 使用参考图像生成图像(图像变化功能)
response_with_ref = bedrock_runtime_client.invoke_model(
    body=json.dumps(
        {
            "taskType": "IMAGE_VARIATION",
            "imageVariationParams": {
                "text": text,
                "images": [
                    reference_image_base64
                ],  # 最多可以在这里提供5个参考图像
                "similarityStrength": similarity_strength,  # 输入图像对输出的影响程度。从0.2到1。
            },
            "imageGenerationConfig": {
                "numberOfImages": 1,  # 要生成的图像数量,最多5张。
                "cfgScale": 6.5,  # 提示将被多大程度地遵循
                "seed": seed,  # 从0到858,993,459的任何数字
                "quality": "standard",  # "standard"或"premium"。默认为"standard"。
            },
        }
    ),
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body_with_ref = json.loads(response_with_ref.get("body").read())

images_with_ref = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body_with_ref.get("images")
]

# 保存输出
image_with_reference_path = f"{output_dir}/05-image-variation_with-reference.png"
save_image(response_body_with_ref.get("images")[0], image_with_reference_path)
print(f"Saved image with reference to {image_with_reference_path}")

# 绘制输出
plot_images_for_comparison(
    ref_image_path=reference_image_path,
    base_images=images_without_ref,
    custom_images=images_with_ref,
    prompt=text,
)

示例 2: 将图像变化用于风格迁移

图像变化功能可用于影响生成图像的视觉风格,这个过程通常被称为"风格迁移”。通过使用特定风格的参考图像,如素描或绘画,并使用适度的similarityStrength值和强cfgScale值,生成的图像将继承该风格,同时仍然遵循文本提示的内容。这个强大的功能使用户能够创造出具有所需风格的图像,而无需在文本提示中制定复杂的风格描述。

请注意,similarityStrengthcfgScale之间的相互作用意味着我们可能需要试验这两个值,以达到成功风格迁移的正确平衡。

我们将使用下面的参考图像演示风格迁移。运行下面的单元格。生成的图像将保存到"output"文件夹。

# 定义主要输入参数。
reference_image_path = "images/designer_sketch_dress.png"
similarity_strength = (
    0.5  # 输入图像对输出的影响程度。从0.2到1。
)

text = "a wedding tuxedo for groom"

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

print("Generating image without a reference image...")

# 生成没有参考图像的图像
response_without_ref = bedrock_runtime_client.invoke_model(
    body=json.dumps(
        {
            "taskType": "TEXT_IMAGE",
            "textToImageParams": {"text": text},
            "imageGenerationConfig": {
                "numberOfImages": 1,  # 要生成的图像数量,最多5张
                "width": 1024,
                "height": 1024,
                "cfgScale": 6.5,  # 提示将被多大程度地遵循
                "seed": seed,
                "quality": "standard",  # 质量为"standard"或"premium"
            },
        }
    ),
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body_without_ref = json.loads(response_without_ref.get("body").read())

images_without_ref = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body_without_ref.get("images")
]

# 保存输出
image_without_reference_path = (
    f"{output_dir}/05-image-variation_style-transfer_no-reference.png"
)
save_image(response_body_without_ref.get("images")[0], image_without_reference_path)
print(f"Saved image without reference to {image_without_reference_path}")

print("Generating image with a reference image...")

# 使用参考图像生成图像(图像变化功能)
response_with_ref = bedrock_runtime_client.invoke_model(
    body=json.dumps(
        {
            "taskType": "IMAGE_VARIATION",
            "imageVariationParams": {
                "text": text,
                "images": [reference_image_base64],  # 最多5个参考图像
                "similarityStrength": similarity_strength,  # 输入图像对输出的影响程度。从0.2到1。
            },
            "imageGenerationConfig": {
                "numberOfImages": 1,  # 要生成的图像数量,最多5张
                "width": 1024,
                "height": 1024,
                "cfgScale": 6.5,  # 提示将被多大程度地遵循
                "seed": seed,
                "quality": "standard",  # 质量为"standard"或"premium"
            },
        }
    ),
    modelId=image_generation_model_id,
    accept="application/json",
    contentType="application/json",
)

response_body_with_ref = json.loads(response_with_ref.get("body").read())

images_with_ref = [
    Image.open(io.BytesIO(base64.b64decode(base64_image)))
    for base64_image in response_body_with_ref.get("images")
]

# 保存输出
image_with_reference_path = (
    f"{output_dir}/05-image-variation_style-transfer_with-reference.png"
)
save_image(response_body_with_ref.get("images")[0], image_with_reference_path)
print(f"Saved image with reference to {image_with_reference_path}")

# 绘制输出
plot_images_for_comparison(
    ref_image_path=reference_image_path,
    base_images=images_without_ref,
    custom_images=images_with_ref,
    prompt=text,
)

示例 3: 调整相似度强度参数

图像变化功能允许用户通过调整similarityStrength参数来控制生成的图像与参考图像的相似程度。该参数取值范围为0.2到1.0,较低的值会产生更多偏离参考图像的图像,较高的值会产生更接近参考图像样式和构图的图像。

为了说明similarityStrength参数的效果,让我们使用下面的参考图像生成图像,但使用三个不同的值。运行下面的单元格。生成的图像将保存到"output"文件夹。

# 定义主要输入参数。
reference_image_path = "images/cartoon_wedding.png"
similarity_strength_values = [0.2, 0.65, 1.0]  # 值可以从0.2到1.0

text = "An elegant white wedding dress displayed in a glass showcase"

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

# 使用不同的similarityStrength值生成图像
generated_images = []
for index, similarity_strength in enumerate(similarity_strength_values):
    print(f"Generating image {index+1} of {len(similarity_strength_values)}...")

    response = bedrock_runtime_client.invoke_model(
        body=json.dumps(
            {
                "taskType": "IMAGE_VARIATION",
                "imageVariationParams": {
                    "text": text,
                    "images": [reference_image_base64],  # 最多5个参考图像
                    "similarityStrength": similarity_strength,  # 输入图像对输出的影响程度。从0.2到1。
                },
                "imageGenerationConfig": {
                    "numberOfImages": 1,  # 要生成的图像数量,最多5张
                    "cfgScale": 6.5,  # 提示将被多大程度地遵循
                    "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())

    base64_images = response_body.get("images")
    image_path = f"{output_dir}/05-image-variation_similarity-{similarity_strength}.png"
    save_image(base64_images[0], image_path)
    print(f"Saving to {image_path}")

    generated_img = [
        Image.open(io.BytesIO(base64.b64decode(base64_image)))
        for base64_image in base64_images
    ]
    generated_images.append(generated_img[0])

# 绘制比较图像
plot_images_for_comparison(
    generated_images=generated_images,
    labels=similarity_strength_values,
    prompt=text,
    comparison_mode=True,
    title_prefix="Similarity Strength",
)

可以看到,当使用较低的similarityStrength值时,生成的图像将主要遵循文本提示的内容,只会受到参考图像样式的微妙影响。随着值的增加,参