Anomalib 视频异常检测数据模块详解:Avenue、ShanghaiTech 与 UCSDped 的配置、数据准备与切帧原理
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
视频异常检测依赖时序片段(clip)而非单帧图像,因此数据加载、切帧与真值对齐方式都和图片数据集不同。本文基于 Anomalib 官方参考文档 video datamodules 页面 及其对应源码,系统讲解Avenue、ShanghaiTech、UCSDped三个视频数据集模块的完整参数、数据自动准备流程、基于 YAML 配置的实例化方式,以及底层AnomalibVideoDataset的切帧与真值选取机制,帮助读者直接上手用 Anomalib 训练视频异常检测模型。
一、视频数据模块总览:统一接口与继承体系
Anomalib 的视频数据模块(Video Datamodules)为视频异常检测数据集提供标准化的加载与处理接口,覆盖训练与推理两个阶段。当前版本(见 src/anomalib/data/datamodules/video/init.py)提供以下三个数据模块:
| 数据模块 | 对应数据集 | 说明 |
|---|---|---|
Avenue | CUHK Avenue | 校园场景视频异常事件检测,支持自动下载与.mat掩码转换 |
ShanghaiTech | ShanghaiTech Campus | 按场景(scene 1–13)划分,需手动下载,训练视频自动转码 |
UCSDped | UCSD Pedestrian | 行人监控视频,异常定义为车辆、自行车等非行人实体 |
三者均可从顶层包直接导入:
from anomalib.data import Avenue, ShanghaiTech, UCSDped这一导出关系由 src/anomalib/data/init.py 中的from .datamodules.video import Avenue, ShanghaiTech, UCSDped, VideoDataFormat完成,且三个类都包含在__all__中。
1.1 基类 AnomalibVideoDataModule
三个模块共同继承自 AnomalibVideoDataModule,该类进一步继承图片数据模块基类AnomalibDataModule(PyTorch LightningLightningDataModule的封装)。从源码结构看,视频基类做了两处关键约束:
- 不支持动态测试集划分:
_create_test_split是空实现,注释说明视频数据集由于帧间时序依赖,通常自带固定的 train/test 划分,因此不做动态重分配; - 不支持合成异常生成:在
_setup中,若val_split_mode == ValSplitMode.SYNTHETIC,会直接抛出ValueError。
这意味着视频模块的验证集只能通过与测试集同源(SAME_AS_TEST)或从测试集切分(FROM_TEST,示例配置中使用)等方式获得,不能像部分图片数据集那样合成异常样本。
二、三个视频数据模块逐一解析
2.1 Avenue(CUHK Avenue)
源码见 src/anomalib/data/datamodules/video/avenue.py。构造参数与默认值如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
root | "./datasets/avenue" | 数据集根目录(会经resolve_dataset_root解析) |
gt_dir | "./datasets/avenue/ground_truth_demo" | 真值标注目录 |
clip_length_in_frames | 2 | 每个 clip 的帧数 |
frames_between_clips | 1 | 相邻 clip 之间的间隔帧数 |
target_frame | VideoTargetFrame.LAST | clip 中取真值的帧位置 |
train_batch_size/eval_batch_size | 32/32 | 训练/评估批大小 |
num_workers | 8 | 数据加载进程数 |
train_augmentations/val_augmentations/test_augmentations/augmentations | None | torchvision v2Transform;stage 级增强优先,augmentations作为兜底 |
val_split_mode | ValSplitMode.SAME_AS_TEST | 验证集构造方式 |
val_split_ratio | 0.5 | 保留作验证的比例 |
seed | None | 可复现性随机种子 |
数据集目录结构(准备完成后)在源码 docstring 中有明确定义:
root/ ├── ground_truth_demo/ │ ├── ground_truth_show.m │ ├── Readme.txt │ ├── testing_label_mask/ │ └── testing_videos/ ├── testing_videos/ │ └── 21.avi ... ├── testing_vol/ │ └── vol21.mat ... ├── training_videos/ │ └── 16.avi ... └── training_vol/ └── vol16.mat ...Avenue 的突出特性是全自动数据准备:prepare_data会检查root是否存在,若不存在则调用download_and_extract下载数据集压缩包与标注压缩包(源码中内嵌了 URL 与 SHA256 校验和,见DATASET_DOWNLOAD_INFO/ANNOTATIONS_DOWNLOAD_INFO),解压后将内层目录内容平移到root与gt_dir下,随后执行_convert_masks:用scipy.io.loadmat读取testing_label_mask/*.mat中的volLabel数组,逐帧写出为编号补零的.png掩码文件(cv2.imwrite)。这一预转换的目的是避免训练时反复解析 MATLAB 文件,显著加快数据加载。
许可证方面,源码明确标注 CUHK Avenue 数据集仅用于学术研究(academic research only)。
2.2 ShanghaiTech(ShanghaiTech Campus)
源码见 src/anomalib/data/datamodules/video/shanghaitech.py。在 Avenue 的参数集基础上,额外提供scene: int = 1参数,取值范围[1, 13],用于选择数据集的某个场景子集。默认值差异:
root默认"./datasets/shanghaitech";train_batch_size/eval_batch_size默认32/32。
与 Avenue 不同,ShanghaiTech必须手动下载:源码注释说明原作者托管的自动镜像已不可用。prepare_data的行为是:
- 检查
root/training目录,若不存在则抛出RuntimeError,异常信息即get_download_instructions生成的分步指引——访问官方项目页面、通过页面提供的网盘链接下载、解压到指定root_path,且要求training/与testing/为root的直接子目录(若压缩包带顶层目录需移入); - 若数据集已就位,则比较
training/videos与training/converted_videos的文件数量,不一致时调用_convert_training_videos转码。
转码逻辑值得注意:原始训练视频的编码会导致 pyav 读取帧出现异常,因此源码用 OpenCV 逐帧读取后以XVID编码重写为新视频(anomalib.data.utils.video.convert_video),写入converted_videos/目录,从而保证后续 pyav 路径可以正确按帧解析。
准备完成后的目录结构:
root/ ├── testing/ │ ├── frames/ │ ├── test_frame_mask/ │ └── test_pixel_mask/ └── training/ ├── frames/ ├── converted_videos/ └── videos/2.3 UCSDped(UCSD Pedestrian)
源码见 src/anomalib/data/datamodules/video/ucsd_ped.py。该数据集是行人监控视频集合,异常被定义为车辆、自行车等非行人实体。参数与默认值:
| 参数 | 默认值 | 说明 |
|---|---|---|
root | "./datasets/ucsd" | 数据集根目录 |
category | "UCSDped2" | 子集,仅允许"UCSDped1"或"UCSDped2" |
clip_length_in_frames | 2 | 每 clip 帧数 |
frames_between_clips | 10 | clip 间隔帧数(注意比 Avenue/ShanghaiTech 的默认值 1 大得多) |
train_batch_size/eval_batch_size | 8/8 | 批大小(默认小于另外两个数据集) |
| 其余参数 | 同前 | target_frame、num_workers、增强、验证划分、种子等一致 |
prepare_data与 Avenue 类似支持自动下载:以root/category目录是否存在作为已就位判据,否则下载并解压官方 tar.gz 包(内嵌 SHA256 校验),再把解压出的UCSD_Anomaly_Dataset.v1p2目录内容平移到root下。
三、核心通用参数与切帧机制
3.1 clip 参数:clip_length_in_frames与frames_between_clips
视频数据集并非按"整段视频"而是按"clip"取样。两者含义在 Avenue 的 docstring 中定义明确:dataloader 返回的每个样本包含clip_length_in_frames帧连续画面,frames_between_clips决定相邻 clip 之间的帧间隔(0 表示逐帧滑窗,值越大则采样越稀疏、clip 间重叠越少)。
底层的 clip 索引由ClipsIndexer(anomalib.data.utils.video)完成。基类 AnomalibVideoDataset 中:
samples(DataFrame)被设置后会触发_setup_clips,用indexer_cls以样本的视频路径、掩码路径、clip 长度与间隔重建索引器;__len__返回indexer.num_clips(),即数据集长度是 clip 数而非视频数或帧数;__getitem__从indexer.get_item(index)取出帧,经to_dtype_video(video=..., scale=True)归一化为浮点张量,并额外保存一份未增强的original_image(uint8)用于结果可视化。
3.2 真值帧选取:VideoTargetFrame与_select_targets
target_frame决定多帧 clip 中"哪一帧负责提供真值",枚举定义在 src/anomalib/data/datasets/base/video.py:
VideoTargetFrame.FIRST:取 clip 首帧;VideoTargetFrame.LAST:取 clip 末帧(各数据集默认值);VideoTargetFrame.MID:取中间帧(clip_length_in_frames / 2);VideoTargetFrame.ALL:保留全部帧的真值。
对应实现在_select_targets:按索引对gt_mask、gt_label、original_image、frames做切片。源码中的调用条件是clip_length_in_frames > 1 and target_frame != ALL,即单帧 clip 无需选取;当target_frame非法(不在枚举中)时抛出ValueError。
另外,逐帧标签gt_label由掩码推导:item.gt_label = torch.tensor([1 in frame for frame in item.gt_mask]).int().squeeze(0),即"该帧掩码中是否存在异常像素"的 0/1 序列,供 clip 级异常分类使用。
3.3 增强与批格式
增强接口采用 torchvision v2 的Transform,且对图像-掩码对联合增强(self.augmentations(item.image, Mask(item.gt_mask))),保证掩码与图像变换一致。stage 级参数train_augmentations/val_augmentations/test_augmentations优先于通用augmentations。批次由VideoBatch.collate拼装(见 src/anomalib/data/dataclasses),当 clip 长度为 1 时item.image会squeeze(0)去掉时间维。
四、基于配置文件实例化数据模块
除 Python API 外,Anomalib 支持用 YAML 配置驱动数据模块。get_datamodule(src/anomalib/data/init.py)读取data.class_path(取最后一段类名),从anomalib.data模块动态解析类,再用init_args实例化;找不到类时抛出UnknownDatamoduleError并打印可用子类列表。若init_args中含image_size,会自动转成元组。
仓库examples/configs/data/下提供了三个视频数据集的现成配置,可直接配合 pipeline 使用:
examples/configs/data/ucsd_ped.yaml:
class_path: anomalib.data.UCSDped init_args: root: "./datasets/ucsd" category: "UCSDped2" clip_length_in_frames: 2 frames_between_clips: 10 target_frame: LAST train_batch_size: 8 eval_batch_size: 1 num_workers: 8 val_split_mode: FROM_TEST val_split_ratio: 0.5 seed: nullexamples/configs/data/avenue.yaml:
class_path: anomalib.data.Avenue init_args: root: ./datasets/avenue gt_dir: ./datasets/avenue/masks clip_length_in_frames: 1 frames_between_clips: 1 target_frame: last train_batch_size: 32 eval_batch_size: 32 num_workers: 8 val_split_mode: from_test val_split_ratio: 0.5 seed: nullexamples/configs/data/shanghaitech.yaml:
class_path: anomalib.data.ShanghaiTech init_args: root: "./datasets/shanghaitech" scene: 1 clip_length_in_frames: 1 frames_between_clips: 1 target_frame: LAST train_batch_size: 32 eval_batch_size: 32 num_workers: 8 val_split_mode: FROM_TEST val_split_ratio: 0.5 seed: null可见示例配置普遍采用clip_length_in_frames: 1(单帧模式,此时target_frame不起切片作用)配合FROM_TEST验证划分;而代码默认参数(Avenue/ShanghaiTech 的 2 帧 clip)则对应多帧模型场景。两种用法都合法,按所用视频模型的时序建模需求选择即可。
等价的 Python 直接实例化方式(取自源码 docstring 示例):
from anomalib.data import Avenue datamodule = Avenue( root="./datasets/avenue", clip_length_in_frames=2, frames_between_clips=1, target_frame="last", ) datamodule.setup() i, data = next(enumerate(datamodule.train_dataloader())) data.keys() # dict_keys(['image', 'video_path', 'frames', 'last_frame', 'original_image'])五、Dataloader 输出与下游使用
setup()后,每个视频模块提供标准的train_dataloader()/val_dataloader()/test_dataloader()(UCSDped 的 docstring 示例即展示了这三个加载器的获取方式)。训练集与测试集分别由对应的 Dataset 实现构建:AvenueDataset、ShanghaiTechDataset、UCSDpedDataset(见 src/anomalib/data/datasets/video 目录,均通过Split.TRAIN/Split.TEST区分),例如 Avenue 在_setup中即按 train/test 各实例化一次AvenueDataset并传入相同的 clip 与真值参数。
从 docstring 给出的样本键看:Avenue 样本含image(clip 张量)、video_path、frames、last_frame、original_image;ShanghaiTech 样本含image、video_path、frames、label。当clip_length_in_frames=2、train_batch_size=32、输入被缩放为 256×256 时,data["image"].shape为torch.Size([32, 2, 3, 256, 256])(Avenue docstring 中的示例输出)。这些字段与VideoItem/VideoBatch数据类一一对应,可直接接入 Anomalib 的视频异常检测模型与 pipeline(如基准 benchmark pipeline)。
六、注意事项与限制小结
- 验证划分限制:视频模块不支持
ValSplitMode.SYNTHETIC(_setup中抛错),也不做动态测试集划分;示例配置采用FROM_TEST按比例从测试集切验证。 - 数据获取方式差异:Avenue 与 UCSDped 可全自动下载(内置 SHA256 校验);ShanghaiTech 必须手动从官方页面下载并按异常提示整理目录,之后训练视频会在首次准备时自动转码到
converted_videos/。 - 默认参数不统一:
frames_between_clips(UCSDped 为 10,其余为 1)、train_batch_size(UCSDped 为 8,其余为 32)在三个模块间不同,跨数据集迁移配置时建议显式检查这些默认值。 - 授权限制:Avenue 仅限学术研究用途,使用前请确认自身使用场景符合数据集许可;ShanghaiTech 以 BSD 2-Clause 协议发布(见各数据模块源码的 License 注释)。
- 单元测试参考:视频数据模块的测试位于 tests/unit/data/datamodule/video 目录,可作为参数行为与边界条件的参考实现。
参考文件索引
- 官方参考文档:docs/source/markdown/guides/reference/data/datamodules/video.md
- 视频数据模块实现:src/anomalib/data/datamodules/video/avenue.py、src/anomalib/data/datamodules/video/shanghaitech.py、src/anomalib/data/datamodules/video/ucsd_ped.py
- 基类:src/anomalib/data/datamodules/base/video.py、src/anomalib/data/datasets/base/video.py
- 配置示例:examples/configs/data/avenue.yaml、examples/configs/data/shanghaitech.yaml、examples/configs/data/ucsd_ped.yaml
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考