Wan2.2-Animate 预处理完全指南:动画与替换模式的姿态提取、姿态重定向与人物分割实战

原创2026-09-30 16:00:25225 阅读
文章标签:人工智能大模型媒体生成视频多模态本地部署音频

Wan2.2-Animate 预处理完全指南:动画与替换模式的姿态提取、姿态重定向与人物分割实战

Wan2.2-Animate(Wan-Animate)以"驱动视频 + 角色图片"为输入,支持角色动画(animation)与角色替换(replacement)两种生成模式。本文以 UserGuider.md 为主线,结合 preprocess_data.py、process_pipepline.py、retarget_pose.py 等源码实现,完整讲解预处理阶段的模型依赖、目录规范、全部命令行参数、姿态重定向的三种策略与人物掩码提取的参数调优,读完即可独立跑通任意输入素材的预处理流程。


1. 预处理在 Wan-Animate 中的作用

Wan-Animate 的生成阶段并不直接消费原始驱动视频,而是消费一系列预处理产物:姿态骨架视频、脸部特写视频、参考图,以及替换模式下额外的人物掩码与背景视频。生成入口 generate.py 中的 animate-14B 任务会从 --src_root_path 指定的目录读取 src_pose.mp4、src_face.mp4、src_ref.png(替换模式还读取 src_bg.mp4、src_mask.mp4),并在 wan/animate.py 的 prepare_source / prepare_source_for_replace 中完成加载。

预处理的核心目标有两个:

  1. 从驱动视频中逐帧提取 2D 人体骨架(含全身关键点、左右手关键点),用于后续的条件生成;
  2. 按需要将骨架 重定向(retarget) 到参考角色的体型上,使生成的角色动作自然、比例协调;
  3. 替换模式下额外提取 人物掩码与抠除人物后的背景,让生成结果能"替换进"原始场景。

预处理脚本位于 wan/modules/animate/preprocess/,入口为 preprocess_data.py,核心处理逻辑在 ProcessPipeline 类(process_pipepline.py)中。

1.1 两种生成模式,两套预处理管线

两种模式都会从参考视频中提取骨架,但预处理流程不同:

  • Animation 模式(动画):将驱动视频的动作迁移到参考角色图上。强烈建议开启姿态重定向(pose retargeting),尤其是参考角色与驱动角色的身体比例差异较大时。仓库提供了一版简化版重定向管线,帮助开发者快速落地该功能。
    • 注意:由于输入数据的潜在复杂性,简化版重定向的结果不保证完美,强烈建议在进入生成阶段前先人工检查预处理产物。
    • 社区改进该功能的贡献是受欢迎的。
  • Replacement 模式(替换):将参考角色"替换"进驱动视频的场景。此模式下默认关闭姿态重定向,这是有意为之——需要为角色与环境的空间交互留出余地。
    • 警告:若参考角色与驱动角色身体比例严重不匹配,最终输出可能出现伪影或形变。
    • 仓库同时提供了一套简化的角色掩码提取方案,但该方案仅适用于单人视频;多人视频下可能出现错误的姿态追踪、掩码错误或失败,用户需自行开发或集成合适的开源工具。

2. 预处理依赖模型与目录规范

预处理需要额外下载若干模型:

  • 姿态检测(必需):人体检测器 + 2D 姿态估计模型,均以 ONNX 形式运行;
  • 掩码提取、图像编辑(可选,按需):SAM2 用于替换模式的人物掩码;FLUX.1-Kontext-dev 用于增强版姿态重定向。

将模型按如下目录结构放置(以 /path/to/your/ckpt_path/ 为根):

    /path/to/your/ckpt_path/
    ├── det/
    │ └── yolov10m.onnx
    ├── pose2d/
    │ └── vitpose_h_wholebody.onnx
    ├── sam2/
    │ └── sam2_hiera_large.pt
    └── FLUX.1-Kontext-dev/

对照 preprocess_data.py 的路径拼接逻辑:

  • det/yolov10m.onnx → 由 Yolo 类加载(pose2d.py),用于检测画面中的人体边界框;
  • pose2d/vitpose_h_wholebody.onnx → 由 ViTPose 类加载(pose2d.py),输出全身/手部关键点热图;
  • sam2/sam2_hiera_large.pt → 仅在 --replace_flag 时按需加载(sam2_checkpoint_path = ... if args.replace_flag else None);
  • FLUX.1-Kontext-dev → 仅在 --use_flux 时按需加载(flux_kontext_path = ... if args.use_flux else None),通过 diffusers 的 FluxKontextPipeline 实例化并运行在 CUDA(process_pipepline.py)。

三个路径参数的含义:

  • video_path:输入驱动视频路径;
  • refer_path:角色图片路径;
  • save_path:预处理结果输出目录。

2.1 输出产物一览

  • Animation 模式:在 save_path 下生成两个视频 src_face.mp4(512×512 脸部特写序列)与 src_pose.mp4(姿态骨架条件视频)。
  • Replacement 模式:额外生成两个视频 src_bg.mp4(抠除人物后的背景)与 src_mask.mp4(人物掩码序列,以三通道灰度视频形式写出)。参考图会复制为 src_ref.png;增强重定向开启时还会输出 refer_edit.png、tpl_edit.png 中间结果(process_pipepline.py)。

src_face.mp4 的生成方式为:利用 get_face_bboxes(utils.py)基于面部关键点计算扩边后的脸部 bbox,裁出人脸并统一 resize 到 512×512 后写为视频。该产物被生成阶段用作表情/面部控制信号。

2.2 分辨率与帧率

  • resolution_area:同时决定预处理与生成模型的分辨率,按像素面积衡量。默认 <a href="https://link.gitcode.com/i/53693ce201bc61553e47a22018b6a4c9" target="_blank">1280, 720],实际实现中按 width * height 的总面积等比缩放原图(保持原始宽高比),并通过 resize_by_area([utils.py)保证边长是 64 的倍数,以便后续 VAE/DiT 下采样整除(divisor=16 用于帧序列,64 用于参考图与条件图)。源码注释原文:"To handle different aspect ratios, the video is resized to have a total area equivalent to width * height, while preserving the original aspect ratio."(preprocess_data.py)
  • fps:指定视频处理的帧率,默认 30。较低的帧率可以提升生成效率,但可能引起卡顿或抽帧感。设为 -1 时使用原视频帧率(if fps == -1: fps = video_fps,见 process_pipepline.py)。帧采样通过 get_frame_indices(utils.py)按目标帧率重采样。

3. 完整命令行与全部参数说明

预处理入口脚本为 wan/modules/animate/preprocess/preprocess_data.py,参数定义见其 _parse_args()(preprocess_data.py)。完整参数如下:

参数 类型 默认值 说明
--ckpt_path str None 预处理模型 checkpoint 目录(上述目录结构的根)
--video_path str None 驱动视频路径
--refer_path str None 角色参考图路径
--save_path str None 预处理结果保存目录
--resolution_area int×2 [1280, 720] 目标分辨率 [width, height],按面积等比缩放
--fps int 30 目标处理帧率;-1 表示沿用原视频帧率
--replace_flag flag False 是否启用替换模式
--retarget_flag flag False 是否启用姿态重定向(目前仅动画模式支持)
--use_flux flag False 是否在重定向中使用图像编辑模型;参考图或驱动视频首帧非标准正面姿势时推荐
--iterations int 3 掩码膨胀迭代次数
--k int 7 掩码膨胀卷积核大小
--w_len int 1 掩码轮廓网格在 w 维的细分数量,越大轮廓越精细,1 表示不细分
--h_len int 1 掩码轮廓网格在 h 维的细分数量,越大轮廓越精细,1 表示不细分

脚本内置两条断言(preprocess_data.py):

assert len(args.resolution_area) == 2, "resolution_area should be a list of two integers [width, height]"
assert not args.use_flux or args.retarget_flag, "Image editing with FLUX can only be used when pose retargeting is enabled."

即 --use_flux 必须与 --retarget_flag 同时启用,否则直接报错。

3.1 动画模式示例命令

取自 README.md(路径按本仓库布局整理):

python ./wan/modules/animate/preprocess/preprocess_data.py \
    --ckpt_path ./Wan2.2-Animate-14B/process_checkpoint \
    --video_path ./examples/wan_animate/animate/video.mp4 \
    --refer_path ./examples/wan_animate/animate/image.jpeg \
    --save_path ./examples/wan_animate/animate/process_results \
    --resolution_area 1280 720 \
    --retarget_flag \
    --use_flux

3.2 替换模式示例命令

python ./wan/modules/animate/preprocess/preprocess_data.py \
    --ckpt_path ./Wan2.2-Animate-14B/process_checkpoint \
    --video_path ./examples/wan_animate/replace/video.mp4 \
    --refer_path ./examples/wan_animate/replace/image.jpeg \
    --save_path ./examples/wan_animate/replace/process_results \
    --resolution_area 1280 720 \
    --iterations 3 \
    --k 7 \
    --w_len 1 \
    --h_len 1 \
    --replace_flag

预处理完成后即可进入生成阶段,动画模式与替换模式的生成命令同样见 README.md(生成入口 generate.py --task animate-14B)。


4. Animation 模式:三种姿态重定向策略

动画模式通过 retarget_flag 与 use_flux 两个开关组合出三种形态:

形态 retarget_flag use_flux 适用场景
不使用姿态重定向 不设 不设 参考角色与驱动角色比例接近
基础姿态重定向 设 不设 参考角色与驱动视频首帧角色均为正面前展姿势
增强姿态重定向(基于 FLUX.1-Kontext-dev) 设 设 参考图或驱动首帧姿势不规范时推荐

4.1 基础重定向的硬性前提

使用基础重定向时,必须确保 参考角色 与 驱动视频首帧中的角色 都处于**正面、伸展(front-facing, stretched)**的姿势。因为基础重定向直接以首帧姿态与参考图姿态作为骨骼长度比的计算基准(retarget_pose 中 src_skeleton 取驱动首帧、dst_skeleton 取参考角色)。

4.2 增强重定向(FLUX.1-Kontext-dev)

除上述条件外,官方推荐使用 retarget_flag + use_flux 的增强方案。其工作流程(process_pipepline.py)为:

  1. 基于驱动视频全身/半身可见性,自动生成编辑 prompt(get_editing_prompts,同文件 L237-L277):腿部可见时使用 T-pose / 双手自然下垂的"站立正身"描述,仅手臂可见时省略腿部描述,两者均不可见时退化为 "Change the person to face forward.";同时按画面宽高比(横向/竖向)切换对应的英文 prompt 模板;
  2. 用 FluxKontextPipeline 分别对参考图和驱动视频第二帧做图像编辑,guidance_scale=2.5、num_inference_steps=28,使其变为标准正面姿势;
  3. 编辑结果保存为 refer_edit.png、tpl_edit.png(便于检查中间产物),并重新跑一遍姿态检测,得到编辑后的骨架;
  4. 调用 get_retarget_pose(tpl_pose_meta0, refer_pose_meta, tpl_pose_metas, tpl_edit_pose_meta0, refer_edit_pose_meta)(retarget_pose.py)完成重定向。

注意:由于 FLUX.1-Kontext-dev 能力有限,不保证产生预期结果(如一致性未保持、姿势错误等)。建议检查中间产物与最终生成的姿态视频,两者都存放在 save_path。用户也可以自行更换更强的图像编辑模型,或自行探索 Flux 的 prompt。

4.3 重定向的源码级实现原理

retarget_pose.py 实现了简化版的重定向核心,主要步骤包括:

  • 尺度对齐(scale_min):优先用"鼻尖到踝关节中点"的像素距离之比计算参考/驱动骨架的全局尺度;关键点不足或置信度低时退化为"臀部中点"方案,再退化为画面面积比方案(retarget_pose.py)。
  • 骨骼长度比(bone ratio):按 limbSeq 定义的 19 条肢干,逐条计算驱动骨架与参考骨架的骨骼长度比;缺失时用相邻肩臂比例均值插补,并通过 rescale_shorten_skeleton 对左右对称骨骼取最大比、对眼睛/耳朵取均值,避免比例失衡(同文件 L450-L477)。
  • 对称性修复(fix_lack_keypoints_use_sym):当某侧肢干关键点缺失时,参考对称侧骨骼长度补全;完全无参照时按肩-髋距离按比例估计(同文件 L369-L447)。
  • 坐标重建(get_scaled_pose):保持各肢干的角度不变、将长度替换为目标骨骼长度,逐肢干重构关键点;脚部长度被限制在小腿长度的 0.5 倍以内(同文件 L196-L204);随后按地面点(full body 用踝/脚中点,非 full body 用颈部)对齐水平与垂直偏移,并将手部关键点按肩部比例缩放同步迁移(同文件 L229-L288)。
  • 身体区域判定(check_full_body / check_full_body_both):根据踝关节、髋关节可见性将画面判定为 full body / three-quarter body / half body,两者取更低等级作为共同处理策略,决定地面锚点选择(同文件 L481-L517)。

重定向完成后,get_retarget_pose 把结果封装为 AAPoseMeta(含身体关键点与左右手关键点及其置信度),交由 draw_aapose_by_meta_new(human_visualization.py)绘制成骨架画布。重定向时画布尺寸以参考图为准,否则以驱动帧为准再 padding_resize 到参考图尺寸(process_pipepline.py),保证骨架与参考角色比例一致。


5. Replacement 模式:人物掩码提取与背景抠除

开启 replace_flag 后,预处理会额外处理视频中人物的掩码,掩码的大小与形状可通过若干参数调节(process_pipepline.py):

  1. 先用 SAM2 视频预测器做掩码分割:get_mask 按每 400 帧分段,每段选取 4 个关键帧,以全身骨架关键点(索引 <a href="https://link.gitcode.com/i/5c127a282d38bd9c18043f923314ad59" target="_blank">0, 1, 2, 5, 8, 11, 10, 13],即鼻、颈、肩、髋、踝等 8 点)作为提示点调用 add_new_points,再 propagate_in_video 传播出全段掩码(同文件 L280-L343)。SAM2 通过 [sam_utils.py 的 build_sam2_video_predictor 构建,模型配置为 sam2_hiera_l.yaml,加载 sam2_hiera_large.pt 权重,且显式关闭 FlashAttention(transformer.USE_FLASH_ATTN = False,见 process_pipepline.py)。
  2. 然后对掩码做膨胀与网格细化:
    • iterations 与 k 使掩码更大、覆盖更多区域。实现上 get_mask_body_img 用 k×k 的全 1 核执行 cv2.dilate,迭代 iterations 次(utils.py)。
    • w_len 与 h_len 调节掩码形状:get_aug_mask 将掩码 bbox 在 w/h 方向分别细分为 w_len/h_len 个格子,只要格子内包含掩码像素就整体置 1,把锯齿状轮廓"填平"成网格状。取值越小轮廓越粗,越大越精细;默认均为 1(不细分)(utils.py)。当 iterations <= 0 时跳过膨胀直接使用原始掩码。
  3. 背景图 src_bg.mp4 为 frame * (1 - mask) 的逐帧抠除结果,掩码以三通道灰度(255 级)写成 src_mask.mp4。

5.1 掩码大小与生成质量的权衡

  • 更小、轮廓更精细的掩码:能保留更多原始背景,但可能限制角色的生成区域;考虑到参考角色与驱动角色可能存在外观差异,过小的掩码可能导致形状泄漏(shape leakage)。
  • 更大、轮廓更粗糙的掩码:角色生成更灵活、一致性更好,但因包含更多背景,可能影响背景一致性。

官方建议根据具体输入数据调节相关参数。生成阶段中,掩码与背景视频会被编码为条件张量:mask_pixel_values = 1 - batch<a href="https://link.gitcode.com/i/40d7f398e24d4e91a4af5a698e8c4b5d" target="_blank">"mask_pixel_values"] 并在 VAE 隐空间插值到 H/8 × W/8([wan/animate.py),用于引导替换区域的重建,这正解释了为何掩码质量直接影响替换效果。


6. 姿态检测与数据装载的实现细节

两种模式共用同一套 2D 姿态检测链路(Pose2d,pose2d.py):

  1. Yolo(YOLOv10m ONNX,输入 640×640)逐帧检测人体框,支持置信度阈值、NMS、多目标抑制与"最大框/中心框"选择策略(select_type),默认 single_person=True 只保留主人物(同文件 L207-L280);
  2. ViTPose(vitpose_h_wholebody.onnx,输入 256×192)在检测框内预测关键点热图,经 keypoints_from_heatmaps 还原坐标与置信度,输出 whole-body 关键点(身体 + 面部 + 左右手),并按 ImageNet 均值/方差归一化预处理;
  3. load_pose_metas_from_kp2ds_seq 将逐帧关键点组织为带 width/height 的 pose meta 列表,供后续绘制与重定向使用。

驱动视频通过 decord 的 VideoReader 装载(process_pipepline.py):读取总帧数与平均帧率,若实际帧数与"时长 × 帧率"推算的期望帧数偏差超过 10% 会打印告警并改用期望帧数;随后按目标帧率重采样、按 resolution_area 面积缩放。参考图则经 padding_resize 适配到与视频一致的高宽(动画模式下先缩放再单独检测姿态)。

另外,Pose2d 的 load_images 还支持直接传入 .mp4/.avi/.mov/.mkv 视频路径或 .jpg/.jpeg/.png/.bmp 图片路径(同文件 L357-L394),可作为独立组件复用于其他任务。


7. 排查建议与最佳实践

综合原文档的提示与源码行为,整理以下实战建议:

  1. 重定向前务必检查首帧:基础重定向要求参考角色与驱动首帧均为正面前展姿势;若不符,要么改用 --use_flux 增强重定向,要么更换驱动素材,否则会直接放大比例误差。
  2. 每次预处理后检查产物:动画模式检查 src_pose.mp4 中骨架是否贴合参考角色体型、src_face.mp4 是否稳定跟住脸部;增强重定向还可在 save_path 检查 refer_edit.png / tpl_edit.png,确认 Flux 编辑后的姿势已标准化。官方明确提示简化版重定向结果"NOT guaranteed to be perfect"。
  3. 替换模式严格限定单人视频:SAM2 掩码提取以主人物关键点为提示,多人场景可能追踪错误角色或掩码失败,需自行引入多人方案。
  4. 掩码参数以小步调试:默认 iterations=3, k=7, w_len=1, h_len=1 是通用起点;背景要求高时适当减小膨胀或提高 w_len/h_len 让轮廓更贴合,角色一致性优先时反向调整,按素材逐组对比 src_mask.mp4 效果。
  5. 关注帧率与面积的效率平衡:fps 调低可显著减少后续扩散步数,但会牺牲流畅度;resolution_area 决定生成分辨率,按显存与画质需求权衡,且必须保持宽高面积语义(如 1280 720)。

通过以上预处理步骤产出规范化的 src_pose.mp4、src_face.mp4、src_ref.png(及替换模式的 src_bg.mp4、src_mask.mp4)后,即可交给 generate.py --task animate-14B 进入角色动画或替换的生成阶段。

登录后查看全文
Wan2.2