实战指南:从 Veo 拼贴生成到质检后处理的完整实现)
ADK 眼镜试戴视频生成流水线Video VTO / Glasses实战指南从 Veo 拼贴生成到质检后处理的完整实现【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples本文以 ADKAgent Development Kit示例仓库 genmedia-for-commerce 中的眼镜Glasses视频虚拟试戴Video VTO模块为核心系统讲解其从模特照片 产品图 → 拼贴画Collage→ Veo 视频生成 → 绿幕裁剪与质检过滤的完整实现链路并深入剖析批量化生成、后台去背、Gemini 抖动检测等源码级细节。读完本文你将掌握如何在 ADK Agent 与 MCP 工具层面调用run_glasses_video_generate/run_glasses_video_regenerate两个视频生成工具理解其 REST API 参数语义并能据此为自己的电商营销视频场景搭建可复用的生成与质检方案。一、模块定位Video VTO 与 Image VTO 的分工在genmedia4commerce仓库中眼镜虚拟试戴VTOVirtual Try-On能力被拆分为两个模块Image VTO图像基于 Nano Banana 完成去背景、创建眼镜佩戴帧create-frame、帧编辑edit-frame与图像增强enhance-image其完整概述见 image_vto/glasses/README.mdVideo VTO视频即本文主题在图像能力之上用 Veo 把拼贴画动画化为营销视频并完成绿幕裁剪、人脸校验与抖动检测等后处理。两个模块由 Router Agent 统一路由对外暴露的 MCP 工具与 REST API 如下表所示能力维度MCP 工具REST 端点核心模型图像glasses_vto、glasses_enhance、glasses_edit_frame/api/glasses/*图像相关Nano Banana视频run_glasses_video_generate、run_glasses_video_regenerate/api/glasses/generate-video、/api/glasses/regenerate-videoVeo Gemini视频流水线的总体链路为Model Image Glasses Image → 去背景 → 创建拼贴画 → Veo 生成视频 → 后处理绿幕裁剪/人脸校验/抖动检测→ 输出 MP4二、目录结构与职责划分视频 VTO 模块的核心文件分布在两个目录中职责清晰分离genmedia4commerce/workflows/video_vto/glasses/ # 流水线业务实现 ├── pipeline.py # 视频生成与再生成的整体编排run_generation_pipeline / run_regeneration_pipeline ├── generate_video_util.py # Veo 视频生成、拼贴画创建、后处理绿幕裁剪 ├── glasses_eval.py # 视频抖动检测Gemini、颜色检测OpenCV、人脸检测Vision API ├── custom_template.py # AI 驱动的广告结构化 Prompt 生成 ├── men_templates.jsonl # 男性模特视频模板 ├── women_templates.jsonl # 女性模特视频模板 └── videos/ # 模板视频素材men/、women/ genmedia4commerce/mcp_server/video_vto/glasses/ # MCP / API 暴露层 ├── glasses_mcp.py # MCP 工具run_glasses_video_generate、run_glasses_video_regenerate └── glasses_api.py # REST API 路由前缀 /api/glasses值得强调的是pipeline.py是编排层负责把去背景 → 拼贴 → Veo → 后处理串成一条完整链路generate_video_util.py只负责拼贴画与 Veo 生成等原子能力glasses_eval.py则是质检层。分层设计使得生成与校验可以独立演进、独立测试。三、核心流水线从图片到视频的完整编排3.1 生成流水线run_generation_pipeline入口函数run_generation_pipeline位于 pipeline.py其执行流程可拆解为四个阶段去背景Background Removal若传入model_image_bytes、model_side_image_bytes、product_image_bytes会以ThreadPoolExecutor(max_workers3)并行调用共享工具workflows/shared/image_utils.replace_background对三张图同时去背景阈值参数为0.01大幅压缩预处理耗时拼贴画创建Collage Creation根据zoom_level计算留白margin (6 - zoom_level) * 100再调用create_collage把模特正面图可选侧面图与眼镜产品图合成到纯色背景画布上输出 PNG 字节并做 Base64 编码返回collage_data字段——这一数据在再生成时可直接复用Veo 视频生成将拼贴画字节与 Prompt 交给generate_veo默认生成 4 条、每条 8 秒后处理与过滤非动画模式下用ProcessPoolExecutor并行对每条视频执行post_process_video——先做绿幕裁剪再用 Gemini 做抖动检测任一环节失败即丢弃该视频最终只保留通过质检的视频并返回{videos: [...], filenames: [...], collage_data: ...}。关键设计点并行化去背景用线程池IO 密集后处理用进程池CPU 密集两条并行路径互不干扰容忍部分失败只要仍有视频通过质检就正常返回仅记录Some videos failed post-processing告警日志全部失败时在生成阶段返回空列表同时仍返回collage_data以便重试而在再生成阶段则抛出异常动画模式当is_animation_modeTrue时跳过拼贴与全部后处理直接用模特图做 Veo 动画产物文件名以animation_video_*.mp4命名否则为collage_video_*.mp4。3.2 再生成流水线run_regeneration_pipeline再生成Regeneration的意义在于第一次生成时拼贴画可能已通过质检但用户想换 Prompt 或增加视频条数无需重复去背景与拼贴步骤。请求体由RegenerationRequestpydantic 模型承载class RegenerationRequest(BaseModel): prompt: str collage_data: str # Base64 编码的拼贴画 number_of_videos: int 1 bg_color: str 0,215,6,255 is_animation_mode: bool Falserun_regeneration_pipeline直接base64.b64decode(collage_data)还原拼贴画字节跳过预处理随即进入 Veo 生成与后处理阶段动画模式同样跳过后处理。背景色解析做了容错tuple(map(int, req.bg_color.split(,)))失败时回退到默认绿色(0, 215, 6, 255)。四、Veo 生成工具拼贴画创建与批量视频生成4.1 拼贴画创建create_collagecreate_collage 是视频质量的地基函数签名与关键参数如下def create_collage( model_image_bytesNone, glasses_image_bytesNone, model_side_image_bytesNone, target_width3840, # 画布宽默认 4K 宽 target_height2160, # 画布高 horizontal_margin600, # 左右留白 vertical_margin300, # 上下留白 image_spacing300, # 图间间距 model_vertical_spacing50, # 上下堆叠的两张模特图之间的间距 bg_color(0, 215, 6, 255), # 默认绿色便于后续抠像 ):其核心策略是等比缩放、绝不裁剪或拉伸全部使用Image.Resampling.LANCZOS高质量重采样并针对输入图片数量分三种布局单图居中放置按最受限的维度计算缩放比例双图左右并排两图强制等高对齐按content_width / (ar1 ar2)求解公共高度三图模特正面 模特侧面 眼镜左侧上下堆叠两张模特图等高度、垂直间距 50px右侧放置眼镜产品图眼镜高度超出可用高度时按比例整体回缩。从源码可推断zoom_level0–6通过margin (6 - zoom_level) * 100反向控制留白zoom_level越大留白越小、画面主体占比越高horizontal_margin与vertical_margin之比为 2:1符合横版电商视频的构图习惯。画布默认 3840×21604K保证 Veo 生成时输入足够清晰。4.2 批量视频生成generate_veogenerate_veo 解决了 Veo API 的单次请求条数上限问题定义MAX_VIDEOS_PER_BATCH 4当请求条数超过 4 时自动拆分批次如 6 →[4, 2]10 →[4, 4, 2]多批次时用ThreadPoolExecutor(max_workerslen(batch_sizes))并行提交所有批次再汇总结果避免串行等待单批次内部调用共享工具workflows/shared/veo_utils.generate_veo使用模型常量VEO_MODEL veo-2.0-generate-001并显式设置person_generationallow_adult、enhance_promptFalse。4.3 绿幕裁剪后处理process_veo_video_model_on_fitVeo 生成的视频开头通常包含一段纯绿幕帧process_veo_video_model_on_fit 负责将其裁掉用共享工具workflows/shared/video_utils.extract_frames_as_bytes_list抽取全部帧以fps24、分析频率fps_to_analyze2每秒抽 2 帧、跳过前start_secs_to_skip1秒为默认参数抽取前 3 秒内的两批采样帧调用find_color_drop_frame基于背景色占比的颜色骤降并稳定检测与get_index_single_person人脸检测分别得到绿幕消失帧与画面中仅剩一人的帧取两者较大值作为裁剪起点若裁剪后剩余时长超过 3 秒original_seconds 3则判定视频过短、直接丢弃返回None用workflows/shared/video_utils.create_mp4_from_bytes_to_bytes以 24fps、质量 7 重新封装为 MP4。五、质检层Gemini 抖动检测 OpenCV 颜色检测 Vision API 人脸检测glasses_eval.py 汇集了三种互补的质检手段是失败视频过滤的依据5.1 Gemini 2.5 视频抖动检测check_video_for_glitches函数将视频字节与提示词组装为多模态内容通过流式接口generate_content_stream模型名来自环境变量MODEL_NAME_GENERATED_3让 Gemini 以高端时尚品牌数字内容质检专员的身份审查视频。系统提示词 VIDEO_QC_SYSTEM_PROMPT 明确了审查基线不应误报短视频刻意极简、模特动作缓慢、无音轨是品牌标准风格不得标记为异常应报异常可见的绿幕/蓝幕、乱码占位文本、剪辑软件界面元素/水印、画面撕裂或像素化等制作痕迹以及漂浮图形、流体模拟等超现实 VFX输出必须是 JSON 格式{is_glitched: true, reason: ...}。调用时设置了temperature1、response_modalities[TEXT]、thinking_configthinking_budget-1表示开启完整思考以及系统指令注入响应文本用正则\{[^}]*is_glitched[^}]*\}抽取 JSON 并解析解析失败时返回None由上层兜底。5.2 OpenCV 颜色检测detect_color_background将图像从 BGR 转到 HSV 空间围绕目标色相的 HSV 区间饱和度/明度下限默认 0.3用cv2.inRange计算目标色像素占比find_color_drop_frame对帧序列计算目标色占比的一阶差分找到占比骤降且后续变化稳定stability_threshold0.005的帧索引即绿幕消失的起点。5.3 Vision API 人脸检测get_index_single_person将每帧构造为FACE_DETECTION的AnnotateImageRequest通过batch_annotate_images一次性批量标注再经is_video_valid判断允许 0 或 1 人出现第 2 人即视为异常找到从某帧起持续只有一人的起点索引。两个关键判定值idx_bg与idx_face任一为-1未找到都会让该视频被判为不合格。六、AI 广告 Prompt 生成custom_template.py6.1 结构化广告 Promptgenerate_custom_templategenerate_custom_template 用 Geminitemperature0response_mime_typeapplication/json把用户的自然语言草稿扩展为结构化广告分镜。输出遵循StructuredPromptpydantic 模型字段含义如下字段说明subject模特外貌描述模板为A beautiful [gender] model is wearing the same [眼镜描述]…最多三句action模特动作/姿态要求以广告专业经验设计表情与动作scene拍摄场景未指定时返回Clean, minimalist studio environment with a uniform, soft grey background.camera_angles_and_movements镜头角度与运动未指定时返回 A static close-up shot, framed from the chest up.eyeglasses/sunglasses眼镜/太阳镜外观描述材质、框色、镜腿二选一返回另一个为Nonelighting灯光设置未指定时返回Uniform lighting and no reflection on the (eyeglasses|sunglasses) lenses.custom_field用户自定义字段的改写增强无输入时为None系统提示词强调用户可能用意大利语或英语输入但输出必须为英语可结合输入的模特图/产品图判断是眼镜还是太阳镜。API 层/generate-custom-prompt在返回前还会补默认transition_sentence有模特图为Instantly transition to:否则为Instantly turn off the scene.并剔除空值字段。6.2 动画增强 Promptgenerate_animation_promptgenerate_animation_prompt 用于动画模式把用户的一句话动画描述改写成描述场景而非下达指令的叙述式文案例如把Maintain naturalistic facial expressions…改写为The facial expressions are natural and the eyewear remains the hero product.要求不超过 5 句话、语言简单、始终聚焦眼镜本身且不偏离用户原始意图。七、模板体系men_templates.jsonl与women_templates.jsonl预置模板以 JSONL 存储每行包含video_path、product_img与结构化video_prompt。以男性模板为例men_templates.jsonl三个模板分别对应扶镜特写m_wearing缓步走近m_walking2转头正视m_turn三类经典广告动作{video_path: /glasses/videos/men/m_walking2.mp4, product_img: /glasses/images/brown.png, video_prompt: { input_subject: The person in the picture is wearing the exact same eyeglasses as in the photo..., subject: A beautiful male model, approximately 20 years old, is wearing the same Havana tortoiseshell eyeglasses..., action: The person walks confidently and slowly towards the camera from a medium distance then stops..., scene: Minimalist studio with a solid light grey background., camera_angles_and_movements: Medium shot, static, positioned at eye-level., lighting: Uniform lighting and no reflection on lenses., allowed_photos: [45] }}/get_templates端点会读取这两个 JSONL 文件并原样返回glasses_api.py前端可据此让用户先选模板视频产品图再微调 Prompt降低生成成本与不确定性。八、MCP 工具与 REST API两种调用姿势8.1 MCP 工具供 ADK Agent 使用glasses_mcp.py 把流水线封装为两个异步 MCP 工具内部用run_in_threadpool避免阻塞事件循环run_glasses_video_generate(model_image_base64, product_image_base64, model_side_image_base64, prompt, number_of_videos4, background_color0,215,6,255, zoom_level0, is_animation_modeFalse)创建拼贴画并生成视频返回{videos: [...], filenames: [...], collage_data: ...}Base64 非法时返回{error: ...}zoom_level会被钳制到 0–6run_glasses_video_regenerate(prompt, collage_data_base64, number_of_videos1, background_color0,215,6,255, is_animation_modeFalse)基于既有拼贴画重新生成避免重复预处理。8.2 REST API供前端/脚本使用glasses_api.py以APIRouter(prefix/api/glasses)暴露以下端点端点方法说明/get_templatesGET返回男/女模板视频列表/generate-promptPOST由 JSON 结构化字段拼接单一 Prompt 字符串/generate-custom-promptPOST自然语言 图片 → 结构化广告 Promptmultipart/generate-animation-promptPOST文本 模特图 → 增强动画 Prompt/generate-videoPOST拼贴生成视频multipart/regenerate-videoPOST基于collage_data再生成JSON/merge-videosPOST合并多个视频片段并支持变速8.3 端到端调用示例以下 Python 示例演示标准Model-on-Fit模式model_imageproduct_imagemultipart/form-dataimport requests import base64 with open(model_front.jpg, rb) as f: model_data f.read() with open(glasses.png, rb) as f: glasses_data f.read() response requests.post( http://localhost:8000/api/glasses/generate-video, data{ prompt: A professional model wearing stylish sunglasses in a modern studio, number_of_videos: 2, background_color: 0,215,6,255, zoom_level: 3, }, files{ model_image: (model.jpg, model_data), product_image: (glasses.png, glasses_data), }, ) result response.json() for i, video_b64 in enumerate(result[videos]): with open(foutput_{i}.mp4, wb) as f: f.write(base64.b64decode(video_b64))其中zoom_level3对应留白(6-3)*100 300像素若想对同一拼贴换 Prompt 重生成可把响应中的collage_data回传给/regenerate-video。九、环境变量与配置模块所需环境变量配置于config.env变量说明默认值PROJECT_IDGoogle Cloud 项目 IDmy_projectGENAI_LOCATION/GLOBAL_REGIONGemini API 区域globalVEO_LOCATIONVeo API 区域globalNANO_LOCATIONNano Banana API 区域globalMODEL_NAME_GENERATED_3抖动检测使用的 Gemini 模型名无需显式配置pipeline.py与glasses_mcp.py均通过os.getenv(PROJECT_ID, my_project)与os.getenv(GLOBAL_REGION, global)构造genai.Client(vertexaiTrue, ...)glasses_eval.py的 Vision API 客户端使用quota_project_id指向同一PROJECT_ID。注意抖动检测使用的模型名必须通过MODEL_NAME_GENERATED_3显式指定否则 Gemini 调用会失败。十、常见问题排查All videos failed processing所有视频均未通过处理原因多为模特正脸不清晰get_index_single_person无法稳定检出仅一人建议改用正面朝向、面部清晰的模特图并优先选择front视角可临时调小number_of_videos如 2观察是否有视频通过校验用于定位是生成质量问题还是校验过严。抖动视频被过滤这是预期行为——check_video_for_glitches专门过滤低质量输出避免不合格素材流入电商页面可通过增加生成条数如 8 条触发[4, 4]双批次并行提高留存率。绿幕未被正确裁剪确认background_color与实际拼贴背景一致默认绿色0,215,6,255是经过find_color_drop_frame验证的最佳选择若自定义背景色需同时保证detect_color_background的 HSV 阈值能覆盖该颜色。再生成时报错run_regeneration_pipeline在全部视频失败时会抛出异常区别于首次生成返回空列表此时应检查collage_data是否完整、Prompt 是否与拼贴内容匹配或降低number_of_videos重试。十一、结语眼镜 Video VTO 模块为模特佩戴眼镜营销视频的自动化生产提供了完整参考实现pipeline.py负责编排与容错、generate_video_util.py负责拼贴与 Veo 批量生成、glasses_eval.py用 Gemini OpenCV Vision API 三重质检把关custom_template.py则把自然语言一键转成专业广告分镜。无论是通过 MCP 工具让 ADK Agent 直接调用还是通过 REST API 集成到电商前端这套生成—校验—过滤—重试的架构都值得作为电商内容生产类 Agent 的蓝本复用。如需了解图像侧Nano Banana 帧生成与前端组件的完整配合可继续阅读 image_vto/glasses/README.md 与仓库根目录的 README.md。【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考