Imagenを使った商品画像の背景生成アプリを開発してみた

記事タイトルとURLをコピーする

G-gen 大津です。 前回は Imagen と Gragio を使ってテキストプロンプトから新しい画像を生成するアプリを開発しました。

はじめに

当記事で開発するもの

本記事では、Imagen のAPIを用いて、アップロードした画像の背景(または前景)を自動的に認識し、テキストプロンプトに沿った背景(または前景)画像を生成するものです。

具体的には、以下の機能を提供します。

  • 画像、パラメータ、プロンプトをセットして、Imagen 2 にリクエストを投入する
  • アップロードした画像は Imagen 2 でマスキングを実施し、前景と背景に識別する
  • 日本語のテキストプロンプトを受け付ける
  • UI は日本語で表示する

一方で、以下は要件としていません。

  • 自分でマスキング範囲を指定する
  • 画像に文字情報を追加する
  • 特定の画像を使ってファインチューニングする

ソースコードは、Google Cloud が提供する以下の GitHub リポジトリのソースコードを元にし、一部改変しています。ソースコードは Apache 2.0 ライセンスに基づいて公開されています。

なお、筆者の別の記事では、当記事と同じように Imagen を使って画像生成アプリを開発しました。そちらもご参照ください。

blog.g-gen.co.jp

背景生成アプリの活用例

背景画像の生成は、以下のような様々なシーンで活用することができます。

ECサイト運営者

  • 商品画像の背景を瞬時に生成し、商品をより魅力的にアピール
  • 季節やイベントに合わせた背景で、タイムリーな商品画像を作成
  • 大量の商品画像を短時間・低コストで作成し、作業効率を大幅に向上

クリエイター

  • SNS投稿のアイキャッチ画像を簡単に作成
  • ブログ記事のアイキャッチ画像を、記事内容に合ったデザインで生成
  • プレゼンテーション資料の背景を、聴衆を引きつけるデザインで作成

その他

  • 不動産広告の物件画像の背景を変更
  • ゲームやVRの世界で、リアルな背景を生成
  • 教育現場で、教材に合わせた背景画像を生成

背景生成アプリの実行イメージ

アップロードした画像(左上)にテキストプロンプト(左下)を与えることで、Imagen により背景が変更された新しい画像を生成(右側)します。

以下は、本アプリを使って、背景画像を生成した実行例になります。

前回開発した画像生成アプリを使って「サッカーをするパンダ」の画像を生成、背景画像の生成アプリに、の画像(サッカーをするパンダ)とテキストプロンプト(都心の風景)を与えて、新しい画像を4種類生成しています。

本アプリで背景画像を生成した実行例

  • 左側:上部が画像のアップロード、下部は、編集内容やテキストプロンプトなどImagenにセットする引数を指定
  • 右側:入力情報に基づいてimagen が生成した画像を表示する

利用サービス・ライブラリ

当記事では、以下の要素を使ってアプリを開発しました。

Imagen

Gradio

  • 機械学習 Web アプリを容易に構築できる Python フレームワークです。
  • 参考 : Gradio Docs - Interface

Cloud Run

ソースコードの開発

Python のバージョン

当記事では、Python 3.12.0 を使って開発しています。

$ python --version
Python 3.12.0

ディレクトリ構成 今回開発した画像生成 Web アプリのディレクトリ構成は以下のとおりです。

imagen-app
|-- main.py
|-- requirements.txt
|-- Dockerfile

Dockerfile の作成

Cloud Run へのデプロイには Docker イメージを用意する必要があるため、Dockerfile を作成します。

FROM python:3.12-slim
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 10080
CMD [ "python", "./main.py" ]

requirements.txt の作成

使用するライブラリを、以下のとおり requirements.txt に定義します。

gunicorn
google-cloud-aiplatform==1.52.0
google-generativeai==0.5.4
gradio==4.36.0

main.py の作成

開発したコードの全文を以下に記載します。 変数 PROJECT_ID に定義する Your-Project-ID の部分は、ご自身が使用する Google Cloud プロジェクトの IDに置き換えてください。 ライセンス規約に基づき、改変部分が判るようにコメントを追加しています。

# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
  
import io
import traceback
import gradio as gr
import vertexai
from vertexai.preview.vision_models import Image,ImageGenerationModel,ImageGenerationResponse
  
# 環境変数の設定
PROJECT_ID = "Your-Project-ID"  # Google Cloud プロジェクトの ID
LOCATION = "us-central1"  # Gemini モデルを使用するリージョン
  
vertexai.init(project=PROJECT_ID, location=LOCATION)
  
# 画像の前処理
def get_bytes_from_pil(image: Image) -> bytes:
    byte_io_png = io.BytesIO()
    image.save(byte_io_png, "PNG")
    return byte_io_png.getvalue()
  
# 画像の生成処理
def imagen_generate(
    base_image,
    mask_mode: str,
    edit_mode: str,
    prompt: str,
    negative_prompt: str,
):
    # 使用するモデルの指定
    IMAGE_GENERATION_MODEL = "imagegeneration@006"
    generation_model = ImageGenerationModel.from_pretrained(IMAGE_GENERATION_MODEL)
  
    image_pil = Image(image_bytes=get_bytes_from_pil(base_image))
  
    generate_response: ImageGenerationResponse = generation_model.edit_image(
        prompt=prompt,
        base_image=image_pil,
        negative_prompt=negative_prompt,
        number_of_images=4,
        edit_mode=edit_mode,
        mask_mode=mask_mode,
        language="ja",  # 日本語でのプロンプトに対応するために追加
    )
  
    return [img._pil_image for img in generate_response.images]
  
# Update function called by Gradio
def update(
    base_image,
    mask_mode,
    edit_mode,
    prompt,
    negative_prompt,
):
  
    if len(negative_prompt) == 0:
        negative_prompt = None
  
    print("prompt:", prompt)
    print("negative_prompt:", negative_prompt)
  
    images = []
    error_message = ""
  
    try:
        images = imagen_generate(base_image, mask_mode, edit_mode, prompt, negative_prompt)
    except Exception as e:
        print(e)
        error_message = """
        An error occured calling the API.
        1. Check if response was not blocked based on policy violation, check if the UI behaves the same way.
        2. Try a different prompt to see if that was the problem.
        """
        error_message += "\n" + traceback.format_exc()
  
    return images, error_message
  
  
# gradio の設定
iface = gr.Interface(
    # 使用する関数
    fn=update,
    # 入力タイプ:テキストと画像
    inputs=[
        gr.Image(
            label="アップロードした画像",
            type="pil",
        ),
        gr.Dropdown(
            label="マスクモード",
            choices=["foreground", "background"],
            value="background",
        ),
        gr.Dropdown(
            label="編集モード",
            choices=["product-image", "inpainting-insert","inpainting-remove","outpainting"],
            value="product-image",
        ),
        gr.Textbox(
            label="プロンプト入力",  # 日本語での表示に修正
            # 日本語での説明文章に修正
            placeholder="短い文とキーワードをカンマで区切って使用する",
            value="",
        ),
        gr.Textbox(
            label="ネガティブプロンプト",  # 日本語での表示に修正
            # 日本語での説明文章に修正
            placeholder="表示したくない内容を定義する",
            value="",
        ),
    ],
    # 出力タイプ:画像
    outputs=[
        gr.Gallery(
            label="Generated Images",
            show_label=True,
            elem_id="gallery",
            columns=[2],
            object_fit="contain",
            height="auto",
        ),
        gr.Textbox(label="Error Messages"),
    ],
    # 日本語での説明文章に修正
    title="Image modify with Imagen on Vertex AI",  # タイトルの修正
    description="""画像から背景(前景)を認識し、プロンプトの内容に沿った画像を生成します。Imagen のドキュメントについては、この[リンク](https://cloud.google.com/vertex-ai/docs/generative-ai/image/generate-images)を参照してください。 """,
    allow_flagging="never",
    theme=gr.themes.Soft(),
)
  
# # Local 起動
# iface.launch()
  
# Cloud Run 起動
iface.launch(server_name="0.0.0.0", server_port=10080)

Google Cloud へのデプロイ

Cloud Run の使用

開発した画像生成 Web アプリを、Google Cloud 上にデプロイします。

当記事ではデプロイ先のサービスとして、サーバーレス コンテナ コンピューティングサービスである Cloud Run を使用します。Cloud Run の詳細については以下の記事をご一読ください。

blog.g-gen.co.jp

Cloud Run にデプロイ

Dockerfile の存在するディレクトリで以下のコマンドを実行し、コンテナイメージのビルドと Cloud Run へのデプロイを同時に行います。

# Cloud Run サービスをデプロイ
$ gcloud run deploy edit-imagen --source . \
--region=asia-northeast1 \
--allow-unauthenticated \
--port 10080 \
--memory=1Gi \
--min-instances=1 \
--max-instances=1

ビルドされたコンテナイメージは、指定したリージョンに自動で作成される「cloud-run-source-deploy」という名前の Artifact Registory リポジトリに格納されます。

動作確認

Cloud Run のデプロイが完了すると、標準出力に Cloud Run のエンドポイントが Service URL として出力されます。この URL に、ブラウザからアクセスします。

$  gcloud run deploy edit-imagen --source . --port 10080 --region=asia-northeast1 --allow-unauthenticated --memory=1Gi --min-instances=1 --max-instances=1
This command is equivalent to running `gcloud builds submit --pack image=[IMAGE] .` and `gcloud run deploy gradio-imagen --image [IMAGE]`
Building using Buildpacks and deploying container to Cloud Run service [edit-imagen] in project [Your-Project-ID] region [asia-northeast1]
✓ Building and deploying... Done.                                                                                                                                                                            
 ✓ Uploading sources...                                                                                                                                                                                     
 ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/34c8fdeb-02c3-469d-b6ed-9b589d64d759?project=ZZZZZZZZZZZ].                                             
 ✓ Creating Revision...                                                                                                                                                                                     
 ✓ Routing traffic...                                                                                                                                                                                       
 ✓ Setting IAM Policy...                                                                                                                                                                                    
Done.                                                                                                                                                                                                        
Service [edit-imagen] revision [edit-imagen-XXXXX-XXXXX] has been deployed and is serving 100 percent of traffic.
Service URL: https://gradio-imagen-XXXXXXXXX-an.a.run.app

動作画面

Cloud Run で生成されたURLにブラウザからアクセスすると、以下の Web 画面が表示されます。

背景生成アプリのの実行画面

Cloud Run のアクセス元制御について

Cloud Run にデプロイした Web アプリのアクセス元制御を行いたい場合、Cloud Run の前段にロードバランサーを配置し、Identity Aware Proxy(IAP)による IAM 認証や Cloud Armor による IP アドレスの制限を実装することができます。

以下の記事もご参照ください。

blog.g-gen.co.jp

大津 和幸 (記事一覧)

クラウドソリューション部

2022年4月にG-gen にジョイン。
前職まではAWSをはじめインフラ領域全般のなんでも屋。二刀流クラウドエンジニアを目指して、AWSのスキルをGoogle Cloudにマイグレーション中の日々。