DeepLabCut `analyze_videos` 视频推理 API 完全指南:参数详解与 TensorFlow/PyTorch 双引擎实现
DeepLabCut analyze_videos 视频推理 API 完全指南:参数详解与 TensorFlow/PyTorch 双引擎实现
本篇文章围绕 DeepLabCut 官方 API 参考文档 deeplabcut.analyze_videos.rst 所指向的核心函数 deeplabcut.compat.analyze_videos,系统讲解如何在训练好的网络上对视频进行姿态推理:从函数签名、全部参数语义、引擎自动分派机制,到单/多动物项目的输出产物与跟踪拼接流程。读完本文,你将能独立配置并运行视频分析,理解每个参数对推理行为与产出的实际影响,并掌握 TensorFlow 与 PyTorch 两套引擎的差异化用法。
一、API 定位与整体架构
在 DeepLabCut 3.x 中,analyze_videos 是"用训练好的网络对视频做预测"的统一入口。文档中的 .rst 文件仅是一行 Sphinx 指令 .. autofunction:: deeplabcut.compat.analyze_videos(见 docs/api/deeplabcut.analyze_videos.rst),它把最终渲染的完整内容委托给 deeplabcut/compat.py 中同名函数的 docstring。因此本文讲解的就是这个函数本体,及其背后的真实调用链。
从源码结构看,该函数是典型的"兼容层(compat layer)"设计:
- 对外:它被导入并列入公开 API,见 deeplabcut/init.py(第 37、213 行),因此项目中既可以直接
import deeplabcut后调用deeplabcut.analyze_videos(...),也可以调用deeplabcut.compat.analyze_videos(...); - 对内:它根据项目 shuffle 所属的引擎(TensorFlow 或 PyTorch)将调用转发到两个独立实现:
- TensorFlow 引擎:deeplabcut/pose_estimation_tensorflow/predict_videos.py 中的
analyze_videos(第 257 行起),多动物时还会内部转入predict_multianimal逻辑; - PyTorch 引擎:deeplabcut/pose_estimation_pytorch/apis/videos.py 中的
analyze_videos(第 245 行起)。
- TensorFlow 引擎:deeplabcut/pose_estimation_tensorflow/predict_videos.py 中的
此外,函数顶部带有两个重命名装饰器(@renamed_parameter),用于兼容旧版本参数名:
- 旧参数
batchsize→ 新参数batch_size(自 3.0.0 起); - 旧参数
videotype→ 新参数video_extensions(自 3.0.0 起)。
二、函数签名与完整参数参考
完整的函数签名如下(取自 deeplabcut/compat.py 第 579–608 行):
def analyze_videos(
config: str | Path,
videos: list[str | Path],
video_extensions: str | Sequence[str] | None = None,
shuffle: int = 1,
trainingsetindex: int = 0,
gputouse: str | None = None,
save_as_csv: bool = False,
in_random_order: bool = True,
destfolder: str | Path | None = None,
batch_size: int | None = None,
cropping: list[int] | None = None,
TFGPUinference: bool = True,
dynamic: tuple[bool, float, int] = (False, 0.5, 10),
modelprefix: str = "",
robust_nframes: bool = False,
allow_growth: bool = False,
use_shelve: bool = False,
auto_track: bool = True,
n_tracks: int | None = None,
animal_names: list[str] | None = None,
calibrate: bool = False,
identity_only: bool = False,
use_openvino: str | None = None,
engine: Engine | None = None,
overwrite: bool = False,
**torch_kwargs,
) -> str:
函数返回 str 类型的 DLCScorer——即本次用于分析视频的评分器(scorer)名称,后续 create_labeled_video、plot_trajectories 等下游函数也需要使用同一 scorer 定位产物。
下表汇总了全部参数及其含义、默认值与适用引擎:
| 参数 | 默认值 | 作用 | 引擎 |
|---|---|---|---|
config |
— | config.yaml 项目的完整路径 |
通用 |
videos |
— | 视频完整路径列表,或一个目录路径(目录内所有同扩展名视频) | 通用 |
video_extensions |
None |
视频扩展名过滤规则,见下文"输入处理" | 通用 |
shuffle |
1 |
训练所用数据集的 shuffle 索引 | 通用 |
trainingsetindex |
0 |
使用 TrainingFraction 列表中的第几个(0 起始) |
通用 |
gputouse |
None |
仅 TF 引擎;指定 GPU 编号(对照 nvidia-smi),无 GPU 传 None |
TF |
save_as_csv |
False |
额外把预测导出为 .csv(多动物且 auto_track=True 时由 stitch_tracklets 保存) |
通用 |
in_random_order |
True |
传入视频目录时是否随机顺序分析 | 通用 |
destfolder |
None |
分析数据输出目录,默认与视频同目录;后续分析也须传同一目录 | 通用 |
batch_size |
None |
推理批大小;PyTorch 引擎当前不支持,传值会覆盖 pose_cfg.yaml |
TF |
cropping |
None |
裁剪坐标 [x1, x2, y1, y2],作用于全部视频 |
通用 |
TFGPUinference |
True |
仅 TF 引擎;用 TensorFlow 代码在 GPU 上推理 | TF |
dynamic |
(False, 0.5, 10) |
动态裁剪三元组 (state, detectiontreshold, margin) |
通用 |
modelprefix |
"" |
存放 DLC 模型的目录;默认在项目目录内寻找 | 通用 |
robust_nframes |
False |
逐帧读取视频以获得可靠帧数(较慢,抗文件损坏) | 通用 |
allow_growth |
False |
仅 TF 引擎;小显存 GPU 上让显存按需增长而非预分配 | TF |
use_shelve |
False |
用 shelf(pickle 持久化数据库)边推理边落盘,内存占用恒定 | 通用 |
auto_track |
True |
多动物项目自动执行跟踪与拼接,产出最终 .h5 |
多动物 |
n_tracks |
None |
要重建的轨迹数量;默认取 config.yaml 中个体数 |
多动物 |
animal_names |
None |
指定个体命名列表;与 n_tracks 存在长度约束 |
多动物 |
calibrate |
False |
用训练数据校准个体组装流程,增强对错误骨架链接的鲁棒性 | 多动物 |
identity_only |
False |
模型已学习个体身份时,组装与跟踪仅依赖身份预测 | 多动物 |
use_openvino |
None |
仅 TF 引擎;环境装有 OpenVINO 时传 "CPU" 用 CPU 推理 |
TF |
engine |
None |
覆盖 shuffle 的引擎(一般不应手动指定,默认从元数据加载) | 通用 |
overwrite |
False |
仅 PyTorch 引擎;对已有预测文件的视频重新分析 | PyTorch |
torch_kwargs |
{} |
透传给 PyTorch API 的额外参数,如 device(指定 CUDA 设备) |
PyTorch |
三、引擎自动分派机制
analyze_videos 最核心的设计是引擎分派。当 engine=None 时,函数通过 get_shuffle_engine(read_config(config), trainingsetindex=..., shuffle=..., modelprefix=...) 从项目配置与元数据中读取该 shuffle 实际使用的引擎(见 deeplabcut/compat.py 第 783–789 行):
if engine is None:
engine = get_shuffle_engine(
read_config(config),
trainingsetindex=trainingsetindex,
shuffle=shuffle,
modelprefix=modelprefix,
)
随后分别进入两个分支:
- TF 分支:调用
deeplabcut.pose_estimation_tensorflow.analyze_videos,并透传batchsize=batch_size(兼容层把新参数名映射回 TF API 的旧名)、cropping、TFGPUinference、dynamic、robust_nframes、allow_growth、use_shelve、auto_track、n_tracks、animal_names、calibrate、identity_only等;只有显式传入use_openvino时才透传该参数(否则走 TF API 自身默认值); - PyTorch 分支:调用
deeplabcut.pose_estimation_pytorch.apis.analyze_videos。兼容层会先处理两件事:- 若同时传了
gputouse,则通过_update_device(gputouse, torch_kwargs)把它映射为 PyTorch 的device参数; - 若
batch_size非空,把它并入torch_kwargs["batch_size"];若用户已通过torch_kwargs传过batch_size,则打印提示并以torch_kwargs中的值为准。
- 若同时传了
若两个引擎都不匹配,函数以 raise NotImplementedError(f"This function is not implemented for {engine}") 结束。这意味着:用户一般无需关心引擎,DeepLabCut 会按 shuffle 元数据自动选择正确实现;手动传 engine 属于高级用法,官方不建议(docstring 明确说明 "this should generally not be done")。
四、视频输入处理
videos 参数接受两种形式:单个/多个视频文件路径,或一个目录路径。video_extensions 控制按扩展名过滤,两条规则需要区分(compat 层与两个引擎的 docstring 描述一致):
video_extensions=None(默认):文件路径按原样接受;目录会被扫描,筛选出可识别的视频扩展名文件;video_extensions为str或Sequence[str](例如"mp4"或["mp4", "avi"]):文件路径与目录内容都会按给定扩展名过滤。
在 PyTorch 引擎中,collect_video_paths(videos, extensions=video_extensions, shuffle=in_random_order) 负责收集与排序视频(见 deeplabcut/pose_estimation_pytorch/apis/videos.py 第 543 行);in_random_order=True 仅当传入的是目录时才有意义。
cropping 参数若给出,则对所有视频统一使用 [x1, x2, y1, y2] 坐标裁剪;若不同视频需要不同裁剪区域,则应对单个视频分别调用。PyTorch 实现中还有一层联动:当 cropping 为 None 且项目配置里 cropping 为真时,会读取配置中的 x1/x2/y1/y2(见同一文件第 441–447 行)。
五、推理执行细节与输出产物
1. 输出格式
预测结果以 MultiIndex Pandas 数组 的形式保存:索引包含网络名(scorer)、身体部位名、坐标 (x, y)(像素)以及每个部位每个帧的似然值(likelihood)。默认以高效的 HDF 格式(.h5)存放在视频所在目录;若 save_as_csv=True,则额外导出 .csv,可直接导入 MATLAB、R、Prism 等软件。
2. 网络快照的选择
"用哪个训练好的网络"由 config.yaml 中的参数(尤其是 snapshotindex)决定。PyTorch 引擎额外提供 snapshot_index 与 detector_snapshot_index(仅 top-down 模型)用于覆盖配置:索引从 0 开始,-1 表示最后一个快照,例如 snapshot-0.pt、snapshot-50.pt、snapshot-100.pt、snapshot-best.pt 中索引 1 对应 snapshot-50.pt;若传 None,则从项目配置加载。对应解析逻辑见 deeplabcut/pose_estimation_pytorch/apis/videos.py 第 434–439 行。
3. 动态裁剪(dynamic cropping)
dynamic=(state, detectiontreshold, margin) 三元组控制动态裁剪:
- 当
state=True时启用; - 若检测到目标(即任一身体部位似然 >
detectiontreshold),则根据所有部位的最小/最大 x、y 计算目标边界; - 边界按
margin向外扩展,此后只分析该裁剪窗内的姿态,直到目标丢失(低于detectiontreshold); - 当前位置会用于更新下一帧的裁剪窗——因此
margin必须足够大,以覆盖动物的移动幅度。
需要特别注意的是 PyTorch 引擎的约束:动态裁剪只适用于 bottom-up 姿态模型。若模型不是 bottom-up,PyTorch 实现会打印提示并关闭动态裁剪,并建议改用 top_down_dynamic 参数配合 top-down 模型使用(见 deeplabcut/pose_estimation_pytorch/apis/videos.py 第 470–488 行)。
4. 内存与帧数
use_shelve=True时,数据不再在分析结束时统一 dump 成 pickle,而是边推理边写入 shelf(基于 pickle 的持久化、数据库式对象),内存占用恒定。PyTorch 实现中会创建ShelfWriter,并在video_inference期间打开/关闭(见同一文件第 564–570、222–229 行)。robust_nframes=True时逐帧读取视频统计帧数,不依赖元数据,因而对文件损坏更鲁棒,但更慢;PyTorch 引擎通过video.get_n_frames(robust=robust_nframes)调用(第 205 行)。- 若处理帧数与元数据不符,PyTorch 引擎会打印警告,提示视频可能损坏,建议重新编码视频(deeplabcut/pose_estimation_pytorch/apis/videos.py 第 231–239 行)。
5. 批量与跳过机制
batch_size默认取pose_cfg.yaml或项目配置中的值(PyTorch 引擎默认project_cfg.get("batch_size", 1),见第 459–460 行);- PyTorch 引擎的
overwrite=False(默认)会跳过已存在预测文件的视频,打印Video ... already analyzed at ...(第 572–574 行);overwrite=True则重新分析,并在auto_track=True时同时重新生成已有 tracklet 文件。
六、多动物项目的跟踪与拼接
以下参数仅对多动物项目有意义(compat 层 docstring 的 Note 部分明确列出):
auto_trackidentity_onlycalibraten_tracksanimal_names
默认情况下 auto_track=True:跟踪(tracking)与拼接(stitching)自动完成,直接产出最终的 .h5 数据文件,行为与单动物项目一致。若 auto_track=False,则必须手动依次运行以下两个子调用才能得到 .h5:
convert_detections2trackletsstitch_tracklets
关于个体命名与数量:
animal_names:希望写入标注数据文件的个体名称列表。若给出且n_tracks=None,则n_tracks自动设为len(animal_names);若n_tracks非空,则必须满足n_tracks == len(animal_names);若未给出,则从项目config.yaml的individuals字段加载。n_tracks:默认从config.yaml取;当视频中的动物数量与训练时不同时,可传其他值。identity_only=True:当模型已学习个体身份时,组装与跟踪只依赖身份预测。calibrate=True:使用训练数据校准个体组装流程,可提升对错误身体部位连接的鲁棒性,但要求缺失数据极少。
在 TensorFlow 引擎侧,多动物路径会进一步调用 deeplabcut/pose_estimation_tensorflow/predict_multianimal.py 中的相关逻辑,并按 track_method(box/skeleton/ellipse)执行跟踪。
七、TensorFlow 引擎专属参数
gputouse:指定 GPU 编号(对照nvidia-smi输出的编号);无 GPU 传None。TFGPUinference=True:用 TensorFlow 代码在 GPU 上执行推理。该能力源自论文 "Pretraining boosts out-of-domain robustness for pose estimation"(Mathis 等,arXiv:1909.11229)。allow_growth=False:某些小显存 GPU 会遇到显存不足问题。设为True时显存分配器不再预分配整块 GPU 显存,而是从小的占用开始按需增长。use_openvino="CPU":若 Python 环境装有 OpenVINO,可用它在 CPU 上做推理。
八、PyTorch 引擎的进阶能力
PyTorch 引擎在 deeplabcut/pose_estimation_pytorch/apis/videos.py 中实现,除兼容层透传的参数外,还支持以下专有参数:
device:指定推理设备(兼容层会把gputouse映射进来)。snapshot_index/detector_snapshot_index:覆盖配置中的姿态模型/检测器快照选择(top-down 模型必须指定检测器快照,否则直接抛ValueError)。detector_batch_size:检测器推理批大小,默认取project_cfg.get("detector_batch_size", 1)。top_down_dynamic:top-down 动态裁剪配置,仅用于单动物推理;传入空 dict 使用默认参数(官方不推荐,应针对数据定制)。可用键包括:top_down_crop_size(裁剪缩放尺寸,默认从pytorch_cfg.yaml加载)、patch_counts(默认(3, 2),未找到裁剪时沿宽/高的分块数)、patch_overlap(默认50,相邻分块重叠像素)、min_bbox_size(默认(50, 50),最小检测框尺寸)、threshold(默认0.6,认定个体被检测到的部位得分阈值)、margin(默认25,关键点生成边界框时的外扩边距)、min_hq_keypoints(默认2,判定个体被检测并计算 bbox 所需的高分关键点数量)、bbox_from_hq(默认False,为真时仅用高于阈值的点计算 bbox)。ctd_conditions:仅 CTD(条件 top-down)模型,指定生成条件的 bottom-up 模型;为None时从pytorch_config.yaml的"inference": "conditions"加载,也接受{"shuffle": 17, "snapshot": "snapshot-best-190.pt"}形式的 dict。CTD 模型做视频分析必须提供条件(缺失直接抛ValueError,见第 493–497 行)。ctd_tracking:CTD 模型可直接用于个体跟踪——把第 T 帧的姿态作为第 T+1 帧的条件,此时只有首帧需要 bottom-up 模型初始化;也接受CTDTrackingConfig实例。save_as_df:不能与use_shelve=True同时使用;在跟踪前把整段视频预测保存为包含 pandas DataFrame 的.h5。show_gpu_memory:为真时 tqdm 进度条显示当前进程的 GPU 显存占用。inference_cfg:指定InferenceConfig;为None时使用pytorch_cfg.yaml中的配置。transform:对视频应用自定义变换(如 albumentations 的A.Compose)。
九、命令行入口
除了 Python API,还可以通过 CLI 使用该功能。deeplabcut/cli.py 第 383 行定义了 analyze_videos 子命令,最终委托给 deeplabcut.analyze_videos(该 CLI 目前调用的是 deeplabcut.pose_estimation_tensorflow.predict_videos.analyze_videos)。CLI 参数包括:
config:项目config.yaml完整路径;videos:一个或多个视频路径;-num/--num_shuffles(shuffle):训练数据集 shuffle 索引,默认 1;-vtype/--video_type(video_extensions):输入为目录时的视频扩展名,默认.avi;-c/--save(save_as_csv):额外保存.csv,默认关闭。
命令行示例:
python3 dlc.py analyze_videos /home/project/reaching/config.yaml \
/home/project/reaching/newVideo/1.avi
十、完整可运行示例
以下示例均来自官方 docstring(见 deeplabcut/compat.py 第 724–778 行),可直接复制使用。
在 Windows 上分析单个视频:
deeplabcut.analyze_videos(
'C:\\myproject\\reaching-task\\config.yaml',
['C:\\yourusername\\rig-95\\Videos\\reachingvideo1.avi'],
)
在 Linux/macOS 上分析单个视频:
deeplabcut.analyze_videos(
'/analysis/project/reaching-task/config.yaml',
['/analysis/project/videos/reachingvideo1.avi'],
)
分析目录内所有 .avi 视频:
deeplabcut.analyze_videos(
'/analysis/project/reaching-task/config.yaml',
['/analysis/project/videos'],
video_extensions='.avi',
)
一次分析多个视频:
deeplabcut.analyze_videos(
'/analysis/project/reaching-task/config.yaml',
[
'/analysis/project/videos/reachingvideo1.avi',
'/analysis/project/videos/reachingvideo2.avi',
],
)
使用 shuffle=2 分析多个视频:
deeplabcut.analyze_videos(
'/analysis/project/reaching-task/config.yaml',
[
'/analysis/project/videos/reachingvideo1.avi',
'/analysis/project/videos/reachingvideo2.avi',
],
shuffle=2,
)
使用 shuffle=2 并额外保存 CSV:
deeplabcut.analyze_videos(
'/analysis/project/reaching-task/config.yaml',
[
'/analysis/project/videos/reachingvideo1.avi',
'/analysis/project/videos/reachingvideo2.avi',
],
shuffle=2,
save_as_csv=True,
)
十一、使用建议与注意事项
- 输出目录一致性:
destfolder一旦指定,后续的create_labeled_video、plot_trajectories、filterpredictions等分析步骤也必须传入同一目录,否则无法定位产物。 - 多动物手动流程:当
auto_track=False时,务必记得补跑convert_detections2tracklets与stitch_tracklets,否则只有中间预测文件而没有最终的.h5。 - 单动物项目的隐式调整:PyTorch 引擎在单动物项目下会把
save_as_df强制设为True,并禁用use_shelve(打印提示,见 deeplabcut/pose_estimation_pytorch/apis/videos.py 第 462–468 行),以保证单动物输出格式的一致性。 - 视频损坏处理:若提示"元数据帧数 ≠ 实际处理帧数",说明视频可能损坏,可尝试重新编码视频后再次分析(PyTorch 引擎会在日志中给出对应提示)。
- 兼容旧代码:3.0.0 之后旧参数名
batchsize、videotype仍可通过重命名装饰器兼容使用,但建议迁移到新参数名。
通过对兼容层与两个引擎实现的剖析可以看到:analyze_videos 把参数校验、引擎分派、单/多动物流程差异全部收敛在统一入口之下,用户只需关注项目 config.yaml 与上述参数,即可在 TensorFlow 或 PyTorch 引擎上稳定地完成视频姿态推理。