ガーデニングの新時代 !

Amazon Bedrock で理想の庭を実現してみた

~ GreenSnap 株式会社による生成 AI 実装解説 ~

2024-07-02
デベロッパーのためのクラウド活用方法

Author : 高畑 匡秀 (GreenSnap 株式会社)

GreenSnap 株式会社の高畑です。
本記事では、当社が Amazon Bedrock を使用して開発した画像加工の新サービス、gardenAI について紹介します。

Amazon Bedrock では、Amazon や Anthropic といった、さまざまな企業が開発した基盤モデルを使用することができます。その中でも、画像生成に対応できる Amazon Titan Image Generator G1 は単に画像を生成するのみならず、画像の編集も行うことができます。

本記事では、gardenAI において、どうして Titan Image Generator G1 を採用したのか、そしてどのようにして理想の画像を生成しているのかをそれぞれ説明します。

※本記事内で使われている画像はすべて Amazon Titan Image Generator G1 を利用して作成しています。


新サービス、gardenAI のご紹介

GreenSnap 株式会社は、植物に関する SNS アプリや Web メディアの運営を行っています。最近は生成 AI に力を入れており、植物と生成 AI の可能性を模索しています。その一環で開発された gardenAI は、生成 AI 技術を活用して庭や外構をリアルにデザインするサービスです。元となる庭の写真をアップロードし、「イングリッシュガーデン風」「日本庭園風」などの雰囲気を指定したり、場所を指定してシンボルツリーを配置するなどしてデザインを進めていきます。

事業者はこのサービスを使用することで、コストをかけずにリアルな完成イメージを施工前に共有できるようになります。結果として、施工後にイメージと違うというミスマッチを減らすことが可能になります。具体的には、このようなアレンジが可能になります。

(左:オリジナル 右:加工後)


Amazon Titan Image Generator G1 とその機能

Amazon Titan Image Generator G1 について

Amazon Titan Image Generator G1 は、Amazon Bedrock 上で提供される画像生成のモデルです。テキストから画像を生成することはもちろん、画像の一部を指定して編集する INPAINTING 機能、画像の背景を変更する OUTPAITING 機能等、さまざまな機能が備わっています。また、INPAINTING 機能では、マスク画像を用意する方法と、マスク領域をテキストで指定する方法、2 つの方法が用意されています。

INPAITING 機能についての詳細

今回の新サービスの核心である、Amazon Titan Image Generator G1 の INPAINTING 機能について説明します。

  • オリジナル画像
  • 修正する部分のマスク画像
  • 修正内容のプロンプト

これら3つを指定することで、画像を編集できます。

Amazon Titan Image Generator G1 の INPAINTING 機能の素晴らしいところは、指定した領域をプロンプト通りに変更するだけでなく、周囲の背景に合わせてマスク内側を変更する点です。

以下の画像は、庭の画像を INPAINTING 機能で編集した 2 つの例です。どちらも同じプロンプトでアレンジしましたが、入口のドアを認識し、そこに石畳のカーブが繋がるように編集されています。これが「周囲の背景に合わせて」を実現している例です。また、生成される庭の画像は、本物の庭を撮影したかのようなリアルなものになりました。

使用したプロンプト

There is a winding stone path that runs through the garden, and along this path, various types of flowers are in full bloom.

日本語訳

庭には曲がりくねった石の小道があり、その道沿いには様々な種類の花が咲いています。

(左:オリジナル 右:加工後)

これらの利点を踏まえて、gardenAI には Amazon Titan Image Generator G1 の採用を決定しました。


理想の庭を作ってみよう

ここまで、gardenAI の説明と Amazon Titan Image Generator G1 を採用した理由について説明してきました。ここからは、実際に庭の写真を使用し、理想の庭にアレンジしていきます。

庭のイメージをプロンプトにする

INPAINTING 機能で理想の庭を作成できることがわかった一方で、脳内のイメージを言語化するのは難しいかもしれません。そこで、理想の庭のプロンプトも AI に作ってもらいましょう。Anthropic の Claude 3 Haiku は Amazon Bedrockから利用できるモデルの 1 つで、画像を認識して特定のタスクをこなすことができます。

庭の画像を検索して、自分のイメージに近いもの、または理想の庭の画像をダウンロードし、その様子を Claude に教えてもらいます。以下は Claude 3 Haiku を使用して Prompt を生成させる Python のサンプルコードです。

import boto3 
import json 
import base64

# 理想の庭画像のファイルパス
INPUT_FILE_PATH ="{path/to/input/image}"

bedrock_runtime = boto3.client(
    service_name="bedrock-runtime",
    region_name="us-east-1"
)

def call_claude_haiku(base64_string):
    prompt_config = {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 4096,
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {
                            "type": "base64",
                            "media_type": "image/png",
                            "data": base64_string,
                        },
                    },
                    # 庭の画像を説明してもらうプロンプト
                    {"type": "text", "text": "これは庭の画像です。庭の部分に焦点をあててこの庭の光景が伝わるように英語で500byte以内で教えて下さい"},
                ],
            }
        ],
    }
    body = json.dumps(prompt_config)
    model_id = "anthropic.claude-3-haiku-20240307-v1:0"
    accept = "application/json"
    content_type = "application/json"

    response = bedrock_runtime.invoke_model(
        body=body, modelId=model_id, accept=accept, contentType=content_type
    )
    return json.loads(response.get("body").read())

if __name__ == "__main__":
    with open(INPUT_FILE_PATH, "rb") as image_file:
        input_image = base64.b64encode(image_file.read()).decode("utf8")
    bed_rock_response = call_claude_haiku(input_image)
    result_prompt = bed_rock_response.get("content")[0].get("text")
    print(result_prompt) # 生成された理想の庭のprompt

上記コードを使用して、日本庭園の画像をインプットした場合の出力はこのようになりました。

出力されたプロンプト:

This image depicts a stunning Japanese-style garden. The scene is filled with lush, verdant foliage, including towering trees with vibrant green leaves that create a canopy overhead. A winding stream flows through the garden, its banks lined with mossy rocks and gravel pathways. In the center, a traditional wooden gate or torii arch stands, adding an elegant cultural element to the landscape.

日本語: (Claude 3 で翻訳)

この画像は素晴らしい日本庭園を描いています。その景色は、豊かな緑の植物に満ちています。高い木々の鮮やかな緑の葉が頭上に葺き傘をつくっています。園内を小川が蛇行し、その両岸には苔生した岩と砂利道があります。中心には、伝統的な木造の鳥居が立ち、庭園に優雅な文化的要素を加えています。

出力された Prompt を見ると、Claude3 は画像を日本庭園と認識しており、小川や砂利道などそれらしいキーワードが含まれています。Python から Clause 3 Haiku モデルを利用するソースコードは こちら も参考にしてください。

マスク画像を作る

Python の OpenCV を利用して、マスク画像を作成します。今回は簡単な検証ということで、長方形で指定した範囲をマスクとして使用しました。

import cv2

# 画像のパス
input_image_path = "{input/image/path}"
# マスク画像の保存先(拡張子はpngにする)
output_mask_image_path = "{output/image/path}"

if __name__ == "__main__":
    img = cv2.imread(input_image_path)
    roi = cv2.selectROI("マスク領域選択", img)
    x1, y1, w, h = roi
    x2, y2 = x1 + w, y1 + h
    img[:] = 255
    img[y1:y2, x1:x2] = 0
    cv2.imwrite(output_mask_image_path, img)

理想の庭にアレンジする

準備が整いました。庭の写真に加えて、これまでに作成したマスク画像とアレンジするプロンプトの 3 つを引数に追加し、Bedrock の API を実行しましょう。

import boto3
import json
import base64
from PIL import Image
from io import BytesIO

if __name__ == "__main__":
    # 庭画像のパス
    input_image_path = "images/garden/target.png"
    # 生成したマスク画像のパス
    mask_image_path = "images/garden/mask_image.png"
    # アレンジ結果を保存するファイルパス
    output_image_path = "images/garden/garden_output.png"
    # 生成したプロンプト
    prompt = "This image depicts a stunning Japanese-style garden. The scene is filled with lush, verdant foliage, including towering trees with vibrant green leaves that create a canopy overhead. A winding stream flows through the garden, its banks lined with mossy rocks and gravel pathways. In the center, a traditional wooden gate or torii arch stands, adding an elegant cultural element to the landscape."

    with open(input_image_path, "rb") as image_file:
        input_image_base64 = base64.b64encode(image_file.read()).decode("utf8")
    with open(mask_image_path, "rb") as image_file:
        mask_image_base64 = base64.b64encode(image_file.read()).decode("utf8")

    bedrock_runtime = boto3.client(service_name="bedrock-runtime", region_name="us-east-1")
    body = json.dumps({
        "taskType": "INPAINTING",
        "inPaintingParams": {
            "text": prompt,
            "image": input_image_base64,
            "maskImage": mask_image_base64,
        },
        "imageGenerationConfig": {
            "numberOfImages": 1,  # Range: 1 to 5
            "quality": "premium",  # Options: standard or premium
            "cfgScale": 7.5,  # Range: 1.0 (exclusive) to 10.0
            "seed": 42  # Range: 0 to 214783647
        }
    })
    response = bedrock_runtime.invoke_model(
        body=body,
        modelId="amazon.titan-image-generator-v1",
        accept="application/json",
        contentType="application/json",
    )
    response_body = json.loads(response.get("body").read())
    images = [Image.open(BytesIO(base64.b64decode(base64_image))) for base64_image in response_body.get("images")]
    for idx, img in enumerate(images):
        img.save(output_image_path, quality=100)

雰囲気が理想の日本庭園風になりました。

一度でうまくいかない場合は、マスク画像の領域や変数 cfgScale の値を調整して何度か試してみてください。


まとめ

この記事を通じて、Amazon Bedrock と Amazon Titan Image Generator G1 を活用して、理想の庭を実現させる方法を学びました。INPAINTING 機能の精度と周囲の風景に馴染む画像生成の利便性は、庭のデザインだけでなくあらゆる場面で非常に有用です。

また、Claude 3 Haiku モデルも Amazon Bedrock で利用できるため、テキスト生成と画像生成、両方の生成 AI 環境が AWS 内で完結し、運用・保守という観点でも優れています。

一度の画像生成で完璧に仕上がることはないかもしれませんが、何度でも簡単に生成し直せるので、自分だけの特別な庭を作り上げてください!


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

高畑 匡秀
GreenSnap 株式会社 CTO

次代の「みどりのインフラ」をつくる。をミッションに SNS の GreenSnap と EC の GreenSnapSTORE を開発。最近は生成 AI に力をいれて植物と生成 AI の可能性を模索中。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する