genmedia-for-commerce 通用商品生成能力:帧插值、R2V 旋转视频与换背景的完整实战指南
2026/9/15 12:41:35 网站建设 项目流程

genmedia-for-commerce 通用商品生成能力:帧插值、R2V 旋转视频与换背景的完整实战指南

【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples

本篇指南聚焦 ADK 示例项目 genmedia-for-commerce 中面向任意商品类型的通用生成能力模块(other):帧插值(Frame Interpolation)、参考图转视频(R2V)360° 旋转与人物换背景(Background Changer)。文章以 workflows/other/README.md 为主干,结合workflows/下的源码与 MCP API 实现,完整讲解三个功能的 HTTP 端点、调用管线、关键参数、源码实现原理与排障方法,帮助读者直接在本地或 Cloud Run 上复现可运行的商品视频/图片生成服务。

模块概览:一鱼三吃的通用生成工具箱

other模块定位为"与商品类型无关"的通用能力集合,通过 Router Agent 路由分发,对外暴露 3 个 MCP 工具:spinning_other_r2vspinning_interpolationbackground_changer。它区别于专门化的鞋子旋转(workflows/spinning/r2v/shoes/)与 VTO 换装流程,不需要商品分类前置条件,任何商品图片都可以直接进入流水线。

Feature能力描述
Interpolation(帧插值)在商品相邻帧之间生成平滑过渡视频,适合把一组静态照片变成产品展示片
R2V(Reference-to-Video)基于商品参考图生成 360° 旋转视频,无需鞋类专属分类
Background Changer(换背景)保持人脸身份的前提下替换人物照片背景,用于多场景营销图生成

三个功能共享同一套图像预处理基础设施(背景移除、超分、画布化),核心实现在 workflows/shared/ 与 workflows/spinning/。

目录结构:能力按模块拆分的组织方式

other的功能横跨多个能力目录,源码与前端组件分离存放:

genmedia4commerce/workflows/spinning/r2v/other/ ├── main.py # R2V 旋转的 FastAPI 端点 ├── r2v_utils.py # R2V 提示词生成 ├── image_selection.py # 商品类型分类与最佳图像选择 ├── pipeline.py # Veo R2V 视频生成(阻塞式) └── images/products_r2v/ # R2V 商品样例图 genmedia4commerce/workflows/spinning/interpolation/other/ ├── main.py # 帧插值 FastAPI 端点 ├── interpolation_utils.py # 帧插值逻辑与后处理 └── images/products_interpolation/ # 插值样例图 genmedia4commerce/workflows/shared/ └── image_utils.py # 共享图像预处理(preprocess_images 等) genmedia4commerce/workflows/other/ ├── main.py # 换背景 FastAPI 端点 └── background_changer/ └── background_changer.py # 背景替换逻辑 frontend_dev/spinning/r2v/other/ └── SpinningR2V.tsx # R2V 旋转前端组件 frontend_dev/spinning/interpolation/other/ ├── SpinningInterpolation.tsx # 插值前端组件 ├── Spinning.css └── InteractiveViewer.tsx frontend_dev/other/background_changer/ └── BackgroundChanger.tsx # 换背景前端组件

换背景模块对应 MCP 服务端路由实现在 mcp_server/other/background_changer/background_changer_api.py,其路由前缀为/api/other/background-changer,与文档示例中的/api/other/change-background对应(网关层透传路径以实际部署为准)。

Feature 1:帧插值(Frame Interpolation)

帧插值用于在多张静态商品照片之间生成平滑过渡视频。典型场景是:把 4 张不同角度的商品图,通过"预处理 → 逐段生成过渡 → 合并"三步变成一段连续的产品展示视频。

管线

Images → Preprocess (BG removal + upscale + canvas) → Generate Transitions → Merge

预处理阶段复用共享模块 image_utils.py 的preprocess_images(背景移除、超分、画布化三步);过渡生成调用 Veo 的 interpolation 模式;最后用共享的视频工具合并成 MP4。

端点说明

POST /interpolation-preprocess:预处理插值输入图。multipart/form-data表单字段images接收图片文件列表,返回 JSON 数组,每个元素包含index(帧序号)与data(base64 编码的 PNG 图像):

{ "images": [ {"index": 0, "data": "base64_image"}, {"index": 1, "data": "base64_image"} ] }

POST /interpolation-generate-prompt:生成插值提示词,当前返回一个静态优化提示词。字段img1img2为相邻两帧,输出形如{"prompt": "Smoothly transition between the two product views..."}

POST /interpolation-generate:生成两帧之间的单段过渡视频。字段包括img1(起始帧)、img2(结束帧)、index(分段序号)、prompt(过渡提示词)、backgroundColor(背景色 hex,默认#FFFFFF),输出video/mp4

POST /interpolation-merge:合并多段视频并支持速度调整。字段videos为视频文件列表,speeds为 JSON 数组形式的播放速度列表,输出video/mp4

源码实现细节

interpolation_utils.py是插值能力的核心实现(workflows/spinning/interpolation/other/interpolation_utils.py),包含两条关键路径:

  1. 提示词生成get_interpolation_prompt先用generate_generic_product_title让 Gemini 以温度 0 输出一个极简商品类别标题(如 "a smartphone"、"a t-shirt"),再套进 Veo 模板:
return f"""[Subject]: {product_title.strip()} rotating clockwise in a perfect white void. **[Action]:** The camera performs **one continuous, seamless orbit** around the stationary product. ... **[Scene]:** A completely white studio void (Hex: #FFFFFF, RGB: 255, 255, 255). ..."""
  1. 单段生成与后处理process_single_video组合generate_veo(模型veo-3.1-generate-001,时长 4 秒,传入last_frame启用插值模式)与post_process_single_video。后者是保证多段视频无缝衔接的关键:从视频末尾抽取约 15 帧,用find_most_similar_frame_index找到与目标结束帧最相似的一帧,把视频裁剪到该帧;非首段视频还会去掉第一帧,避免拼接时帧重复:
def process_single_video(client, start_image, end_image, prompt, index, num_frames_for_similarity=15, background_color="#FFFFFF"): veo_video = generate_veo(client, start_image, end_image, prompt) video = post_process_single_video( video_bytes=veo_video, end_image=end_image, num_frames_for_similarity=num_frames_for_similarity, is_first_video=(index == 0), ) return video

视频生成失败的重试由共享的generate_veo_shared承担(指数退避,最多 5 次重试),见 workflows/shared/veo_utils.py 与 workflows/shared/llm_utils.py 的retry_with_exponential_backoff

调用示例

import requests import base64 import json # Step 1: 预处理图片 preprocess_response = requests.post( "/api/spinning/interpolation/other/interpolation-preprocess", files=[("images", open(f"frame_{i}.jpg", "rb")) for i in range(4)] ) processed = preprocess_response.json()["images"] # Step 2: 逐对生成过渡视频 videos = [] for i in range(len(processed) - 1): response = requests.post( "/api/spinning/interpolation/other/interpolation-generate", files={ "img1": base64.b64decode(processed[i]["data"]), "img2": base64.b64decode(processed[i+1]["data"]) }, data={"index": i, "prompt": "Smooth transition", "backgroundColor": "#FFFFFF"} ) videos.append(response.content) # Step 3: 合并所有分段 merge_response = requests.post( "/api/spinning/interpolation/other/interpolation-merge", files=[("videos", v) for v in videos], data={"speeds": json.dumps([1.0] * len(videos))} ) with open("final_video.mp4", "wb") as f: f.write(merge_response.content)

Feature 2:R2V(Reference-to-Video)360° 旋转

R2V 用商品参考图直接生成 360° 环绕旋转视频,与鞋子旋转(shoes 模块)的区别在于不需要鞋类专用分类——任何商品都可用同一套流程。

管线

Images → Preprocess (upscale + extract) → Stack References → Generate Prompt → Generate Video

预处理(超分 + 商品抠取)后,参考图会被堆叠组合以符合 Veo 的参考图数量上限(最多 3 张),随后生成旋转提示词并调用 Veo R2V 生成视频。

端点说明

POST /r2v-preprocess:预处理商品图。字段images接收图片文件列表(最多 4 张),返回处理后的参考图列表:

{ "processed_images": [ {"index": 0, "image_base64": "..."}, {"index": 1, "image_base64": "..."}, {"index": 2, "image_base64": "..."} ], "num_processed": 3 }

注意:图片会被堆叠组合成最多 3 张参考图(Veo 参考图数量上限)。

POST /r2v-generate-prompt:基于商品图生成旋转提示词。字段images为图片文件列表,输出商品描述与提示词:

{ "prompt": "A sleek wireless speaker rotates slowly 360 degrees...", "description": "wireless bluetooth speaker with metallic finish" }

POST /r2v-generate:生成单段旋转视频。字段reference_images(参考图文件列表)、prompt(生成提示词)、index(视频序号,默认 0),输出video/mp4

POST /r2v-pipeline:端到端 R2V 管线一键接口。仅需字段images(最多 4 张商品图),直接输出video/mp4

源码实现细节

提示词模板定义在 r2v_utils.py,模板明确要求"相机围绕静止商品做一次连续、无缝、快速的 360° 环绕,商品本身不动":

**[Subject]:** {{description}} **[Action]:** The camera performs **one continuous, seamless, very fast 360-degree orbit** around the stationary product. ... **[Scene]:** A completely white studio void (Hex: #FFFFFF, RGB: 255, 255, 255). ...

其中{{description}}generate_product_description调用 Gemini 生成:系统提示词要求模型输出"商品类型 + 主色"的最短描述,且明确禁止出现品牌名(温度 0、max_output_tokens=100、关闭思考预算)。例如"A red ceramic mug standing still in a completely white studio void (Hex: #FFFFFF, RGB: 255, 255, 255)"。描述会再被填充进VEO_R2V_PROMPT_TEMPLATE作为最终 Veo 提示词。

图片选择与堆叠逻辑在 image_selection.py:classify_product_images先判断商品是"3D 物体(鞋、车)"还是"平面物体",select_best_images再据此决定堆叠布局——3D 物体侧视图独立成画布、正反面堆叠;平面物体正反面独立、侧面堆叠。共享的stack_and_canvas_images(workflows/shared/image_utils.py)在 4 张图时会把后两张横向堆叠后输出 3 张 4K 画布。

视频生成在 pipeline.py 的generate_video_r2v:将参考图包装为VideoGenerationReferenceImage(reference_type="asset"),调用veo-3.1-generate-001,配置 16:9 画幅、时长 8 秒、单视频、无音频,然后轮询长任务直至完成并返回视频字节。

调用示例

import requests # 简单方式:直接走端到端管线 response = requests.post( "/api/spinning/r2v/other/r2v-pipeline", files=[("images", open(f"product_{i}.jpg", "rb")) for i in range(4)] ) with open("spinning_video.mp4", "wb") as f: f.write(response.content)

Feature 3:背景更换(Background Changer)

换背景功能把人物照片中的背景替换为新场景,同时保持人脸身份不变,适用于为同一组人物素材快速产出多套营销场景图。

管线

Person Image → Preprocess (face + person in parallel) → Generate Variations → Evaluate → Stream Results

从 background_changer_api.py 的实现可以看到关键设计:人脸预处理与人物预处理通过asyncio.gather并行执行(各自包装在run_in_threadpool中),所有变体并行生成,每个变体生成后立即评估,结果以 SSE 流式返回。

端点说明

POST /change-background:生成多张换背景变体,SSE 流式返回,预处理自动完成。字段:

  • person_image:人物照片文件(必填)
  • background_description:目标背景的文字描述(可选)
  • background_image:参考背景图片(可选)
  • num_variations:生成变体数量(默认 4)

注意:background_descriptionbackground_image至少提供一个,否则 API 返回 400"Either background_description or background_image must be provided"(见 background_changer_api.py)。

输出为 SSE 流,每个变体在"生成 + 评估"完成后立即推送(顺序不保证):

data: {"index": 0, "status": "ready", "image_base64": "...", "evaluation": {"similarity_percentage": 93.6, "face_detected": true}} data: {"index": 2, "status": "ready", "image_base64": "...", "evaluation": {"similarity_percentage": 92.9, "face_detected": true}} data: {"index": 1, "status": "failed", "error": "Generation failed"} data: {"index": 3, "status": "ready", "image_base64": "...", "evaluation": {"similarity_percentage": 92.7, "face_detected": true}} data: {"status": "complete", "total": 4}

错误400"No face detected in the person image. Please upload a clearer image with a visible face."(当 Vision API 检测不到人脸时触发)。

处理流程

  1. 人脸裁剪/超分与人物预处理并行执行
  2. 所有变体并行开始生成
  3. 每个变体生成后立即评估
  4. 结果按完成顺序逐个流式推送(非输入顺序)

源码实现细节

background_changer.py(workflows/other/background_changer/background_changer.py)实现了三步核心逻辑:

  1. 人脸预处理preprocess_face_image:用共享工具crop_face(Google Cloud Vision 人脸检测 + 30% padding 裁剪,见 image_utils.py 的crop_face)→ Imagen 4.0upscale_image_bytes超分 x4 → 移除背景并放置到#F0F0F0灰底。返回(reference_face, preprocessed_face)二元组,无脸时返回(None, None)

  2. 人物预处理preprocess_person_imagereplace_background移除背景(contour_tolerance=0.01、透明背景)→ x4 超分;异常时回退返回原图。

  3. 两阶段生成generate_background_change:第一步让 Nano Banana(generate_nano,3:4 画幅、1K 尺寸、PNG 输出、温度 0.1)把人物放入新背景;第二步人脸校正——将第一步结果与reference_face拼进提示词("No, the face is different. Use this face: ..."),再次生成以修正人脸一致性。第二步失败时降级返回第一步结果。

质量评估evaluate_background_change_image:将生成图与参考人脸提交给共享进程池(workflows/shared/person_eval.py 的submit_evaluation,DeepFace ArcFace 模型,120 秒超时),返回similarity_percentagedistanceface_detected等指标;评估异常时返回全零兜底结果。

调用示例

import requests import json import base64 # 文字描述方式 - SSE 流式接收 response = requests.post( "/api/other/change-background", files={"person_image": open("person.jpg", "rb")}, data={"background_description": "tropical beach at sunset", "num_variations": 4}, stream=True ) # 逐个处理 SSE 事件 results = [] for line in response.iter_lines(): if line and line.startswith(b"data: "): data = json.loads(line[6:]) if data.get("status") == "ready": results.append(data) print(f"Variation {data['index']}: {data['evaluation']['similarity_percentage']:.1f}%") elif data.get("status") == "complete": print(f"All {data['total']} variations complete") # 保存相似度最高的结果 best = max(results, key=lambda x: x["evaluation"]["similarity_percentage"]) with open("background_result.png", "wb") as f: f.write(base64.b64decode(best["image_base64"])) # 参考背景图方式 response = requests.post( "/api/other/change-background", files={ "person_image": open("person.jpg", "rb"), "background_image": open("beach.jpg", "rb") }, data={"num_variations": 4}, stream=True )

画廊端点与配置

GET /get_gallery_images

获取任意功能的示例商品图。查询参数gallery_type取值为"default""interpolation""r2v"之一,返回 JSON:

{ "products": [ { "folder_name": "product_001", "images": [ {"url": "/other/images/products/product_001/front.jpg", "name": "front.jpg"} ] } ] }

环境变量配置

config.env(参考根目录 config.env.example)中配置:

VariableDescription
PROJECT_IDGoogle Cloud 项目 ID
LOCATIONGemini API 使用的 GCP 区域(示例中同时提供GLOBAL_REGION=globalUS_REGION=us-central1EUROPE_REGION=europe-west4DEFAULT_REGION=us-central1
NANO_LOCATIONNano Banana API 区域(默认"global"

从源码看,pipeline.pybackground_changer_api.py均以PROJECT_ID+GLOBAL_REGION构造genai.Client(vertexai=True, ...)MODEL_NAME_GENERATED_2(插值标题模型,默认gemini-3.5-flash-lite)、MODEL_NAME_GENERATED_5(换背景 Nano Banana 模型)、MODEL_NAME_GENERATED_8(Imagen 超分模型)等模型名均通过环境变量读取,部署时需按实际开通的模型服务配置。

关键组件速查

组件文件核心职责
get_interpolation_prompt/process_single_videointerpolation_utils.py插值提示词生成、单段视频生成 + 无缝裁剪后处理
VEO_R2V_PROMPT_TEMPLATE/generate_product_descriptionr2v_utils.py旋转提示词 Jinja 模板、Gemini 商品描述生成
classify_product_images/select_best_imagesimage_selection.py商品类型分类、最佳 4 图选择与堆叠布局
generate_video_r2vpipeline.pyVeo R2V 长任务视频生成
preprocess_face_image/preprocess_person_image/generate_background_change/evaluate_background_change_imagebackground_changer.py换背景的预处理、两阶段生成、人脸相似度评估
preprocess_images(共享)workflows/shared/image_utils.py批量预处理(背景移除、超分、画布创建),插值与 R2V 共用
change_background_endpointbackground_changer_api.pySSE 流式换背景 HTTP 端点

共享图像预处理的细节见 workflows/shared/README.md,其中preprocess_images(images_bytes_list, client, upscale_client, num_workers=16, upscale_images=True, create_canva=True)同时服务于插值与 R2V 两个模式。

常见问题排查

插值视频出现伪影

  • 确保输入帧之间足够相似,过渡才能平滑
  • 先调用预处理端点统一图像尺寸
  • 尝试减小相邻帧之间的差异

R2V 视频旋转不正常

  • 提供多角度图片(正面、侧面、背面)
  • 确保商品已从背景中清晰抠出
  • 建议使用 3~4 张输入图以获得最佳效果

换背景后脸部相似度偏低

  • 使用清晰的正脸人物照片
  • 避免复杂姿势或面部部分遮挡
  • 多生成几个变体并挑选相似度最高的结果

"No face detected" 错误

  • 确保人脸在图中清晰可见
  • 使用光线充足、高分辨率的图片
  • 人脸在图中应至少约 100×100 像素

总结

other模块通过"共享预处理 + 三个独立生成管线"的设计,把帧插值、R2V 旋转与换背景三个通用能力封装成可直接调用的 HTTP 端点:插值与 R2V 复用preprocess_images与 Veo 系列模型,后者还借助 Gemini 自动生成商品描述与旋转提示词;换背景则用"两阶段生成 + DeepFace 人脸评估 + SSE 流式返回"兼顾效果与体验。实际接入时,重点确认PROJECT_ID/LOCATION/NANO_LOCATIONMODEL_NAME_GENERATED_*系列环境变量,并遵循各端点的输入约束(如 R2V 最多 4 图、换背景必须提供文字描述或参考背景图),即可在生产链路中复现文档所示的完整商品生成流程。

【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询