- 人工智能
- 计算机视觉
- 深度学习
【免费下载链接】mmaction2
OpenMMLab's Next Generation Video Understanding Toolbox and Benchmark
本文以 mmaction2 仓库中 STH-V1 数据准备指南 为主体,详解 Something-Something V1 数据集在 mmaction2 中的完整处理流程:标注下载、RGB 帧解压、光流提取、视频编码、文件列表生成与目录结构校验。读完本文后,你将能够独立把 STH-V1 原始数据整理为可直接用于RawframeDataset/VideoDataset训练与评测的标准格式,并理解各步骤脚本背后的参数含义与实现逻辑。
Something-Something V1(简称 STH-V1)是一个专注于"物体间相互作用"的视频动作识别基准,其 174 个动作类别(例如 "Holding something"、"Turning something upside down")均以 "something" 模板构造,目的是考察模型对动作本身而非物体外观的感知能力。相关论文引用如下:
@misc{goyal2017something, title={The "something something" video database for learning and evaluating visual common sense}, author={Raghav Goyal and Samira Ebrahimi Kahou and Vincent Michalski and Joanna Materzyńska and Susanne Westphal and Heuna Kim and Valentin Haenel and Ingo Fruend and Peter Yianilos and Moritz Mueller-Freitag and Florian Hoppe and Christian Thurau and Ingo Bax and Roland Memisevic}, year={2017}, eprint={1706.04261}, archivePrefix={arXiv}, primaryClass={cs.CV} }需要特别注意的两点前提:
- 官方站点已不可用:STH-V1 官方网站目前已无法访问,标注文件与数据分卷都需要从第三方渠道获取;
- 官方只提供 RGB 帧,没有原始视频:这与 UCF-101、Kinetics 等提供 mp4 视频的数据集不同,STH-V1 官方数据是直接抽取好的 JPEG 帧序列,因此整个流程是"从帧开始"而非"从视频开始"。
开始前请确认数据工具目录位于$MMACTION2/tools/data/sthv1/,仓库内该目录下提供了全流程所需脚本:
| 文件 | 作用 |
|---|---|
| extract_flow.sh | 基于 RGB 帧提取 TV-L1 光流 |
| encode_videos.sh | 将 RGB 帧编码为 mp4 视频 |
| generate_rawframes_filelist.sh | 生成 rawframes 格式文件列表 |
| generate_videos_filelist.sh | 生成 videos 格式文件列表 |
| label_map.txt | 174 个动作类别的完整标签映射 |
Step 1. 准备标注文件
由于官方站点不可用,需要从第三方来源下载 STH-V1 的标注文件,并放置到$MMACTION2/data/sthv1/annotations/目录下。
从源码结构看,后续生成文件列表时,parse_sthv1_splits() 会精确读取以下 4 个文件(注意路径均相对于仓库根目录):
data/sthv1/annotations/something-something-v1-labels.csv # 类别索引文件 data/sthv1/annotations/something-something-v1-train.csv # 训练集划分 data/sthv1/annotations/something-something-v1-validation.csv # 验证集划分 data/sthv1/annotations/something-something-v1-test.csv # 测试集划分其中labels.csv的每一行是一个类别名,会被转换为class_mapping = {class_index[idx]: idx}的类别索引映射;train/validation/test 三个划分文件的每行格式为video_id;label(分号分隔),例如0000001;Holding something。line_to_map解析时会取第一列作为视频 ID(level=1 时只保留 basename),第二列通过class_mapping映射为整型类别索引。仓库自带的 label_map.txt 列出了全部 174 个类别(第 1 行 "Holding something",第 174 行 "Poking a hole into some substance"),可用作下载标注后的类别名称比对参考。
Step 2. 准备 RGB 帧
由于官方数据集不提供原始视频、只提供了抽取好的 RGB 帧,你需要从第三方来源直接下载全部压缩分卷(20bn-something-something-v1-01至20bn-something-something-v1-27等),保存到$MMACTION2/data/sthv1/,然后执行:
cd $MMACTION2/data/sthv1/ cat 20bn-something-something-v1-?? | tar zx cd $MMACTION2/tools/data/sthv1/解压后得到以视频 ID 命名的目录(level=1 单层结构),每个目录内是%05d.jpg格式的帧文件,如00001.jpg、00002.jpg……
关键配置:filename_tmpl。官方 JPG 的文件名前缀是{:05}.jpg(例如00001.jpg),而 mmaction2 中 RawframeDataset 的默认帧名模板是img_{:05}.jpg(见其构造函数参数filename_tmpl: str = 'img_{:05}.jpg')。因此所有与 STH-V1 相关的配置文件中,必须在train/val/test的 dataset 字典里显式添加"filename_tmpl='{:05}.jpg'":
data = dict( videos_per_gpu=16, workers_per_gpu=2, train=dict( type=dataset_type, ann_file=ann_file_train, data_prefix=data_root, filename_tmpl='{:05}.jpg', pipeline=train_pipeline), val=dict( type=dataset_type, ann_file=ann_file_val, data_prefix=data_root_val, filename_tmpl='{:05}.jpg', pipeline=val_pipeline), test=dict( type=dataset_type, ann_file=ann_file_test, data_prefix=data_root_val, filename_tmpl='{:05}.jpg', pipeline=test_pipeline))仓库现有配置正是这样写的。例如 tin_imagenet-pretrained-r50_8xb6-1x1x8-40e_sthv1-rgb.py 中:
dataset_type = 'RawframeDataset' data_root = 'data/sthv1/rawframes' ann_file_train = 'data/sthv1/sthv1_train_list_rawframes.txt' ann_file_val = 'data/sthv1/sthv1_val_list_rawframes.txt' train_dataloader = dict( ... dataset=dict( type=dataset_type, ann_file=ann_file_train, data_prefix=dict(img=data_root), filename_tmpl='{:05}.jpg', pipeline=train_pipeline))同时注意该配置中model = dict(cls_head=dict(num_classes=174, ...))——174 正是 STH-V1 的类别数,与labels.csv的行数一致。
如果你只想使用 RGB 帧(不做光流、不编码视频),可以跳过 Step 3 和 Step 4,直接到 Step 5 生成 rawframes 格式的文件列表即可。
Step 3. 提取光流(可选)
本步骤仅在需要光流输入(如 I3D、TSM 的 flow 分支等)时才必要。运行前先按 安装指南 安装 denseflow,因为底层的光流计算由 denseflow 完成。
如果 SSD 空间充裕,官方建议将光流输出到 SSD 上以获得更好的 I/O 性能。可以执行以下命令建立软链接(假设 SSD 挂载在/mnt/SSD/):
# execute these two line (Assume the SSD is mounted at "/mnt/SSD/") mkdir /mnt/SSD/sthv1_extracted/ ln -s /mnt/SSD/sthv1_extracted/ ../../../data/sthv1/rawframes提示:
ln -s的第二参数../../../data/sthv1/rawframes是相对于当前所在位置($MMACTION2/tools/data/sthv1/)的路径,最终指向项目根下的data/sthv1/rawframes软链接,指向 SSD 上的实体目录。
然后运行光流提取脚本:
cd $MMACTION2/tools/data/sthv1/ bash extract_flow.sh该脚本实际执行的是:
python build_rawframes.py ../../data/sthv1/rawframes/ ../../data/sthv1/rawframes/ \ --task flow --level 1 --flow-type tvl1 --input-frames从 build_rawframes.py 的源码可以看到,--task flow --input-frames分支最终拼出的命令是:
denseflow '<frames_dir>' -a=tvl1 -b=20 -s=1 -o='<out_dir>' -nw=... --nh=... -v --if各参数含义:-a=tvl1指定 TV-L1 光流算法,-s=1表示输入是帧序列而非视频,--if(input frames)告知 denseflow 源数据为逐帧图片,-b=20为批次大小。由于输入是 RGB 帧,输出的flow_x_*.jpg/flow_y_*.jpg会直接写入原来的帧目录(源目录与输出目录相同),这也是脚本中两个路径参数完全相同的原因。
Step 4. 编码视频(可选)
STH-V1 官方没有视频文件,但如果你希望用VideoDataset而非RawframeDataset来读取数据(部分模型或评测方式更适合视频输入),可以把 RGB 帧编码为 mp4。本步骤同样可选,只用 RGB 帧时可跳过。
cd $MMACTION2/tools/data/sthv1/ bash encode_videos.sh脚本实际调用:
python build_videos.py ../../data/sthv1/rawframes/ ../../data/sthv1/videos/ \ --fps 12 --level 1 --start-idx 1 --filename-tmpl '%05d'结合 build_videos.py 的参数说明,这里几个关键参数的含义值得注意:
| 参数 | 取值 | 默认值 | 说明 |
|---|---|---|---|
src_dir/out_dir | rawframes/→videos/ | — | 输入帧目录与输出视频目录 |
--fps | 12 | 30 | 合成视频的帧率;STH-V1 官方帧率约为 12 fps,故按此设定 |
--level | 1 | 2 | 目录层级;STH-V1 帧为单层目录,须显式指定 1 |
--start-idx | 1 | 0 | 帧文件起始序号;STH-V1 帧从00001.jpg开始,故为 1 |
--filename-tmpl | '%05d' | 'img_%05d' | 帧名模板;官方帧名为%05d.jpg,无img_前缀 |
--vcodec | — | mpeg4 | ffmpeg 编码方式 |
--ext | — | mp4 | 输出视频扩展名 |
底层实现上,encode_video() 会对每个帧目录调用ffmpeg -start_number {start_idx} -r {fps} -i '<frame_pattern>' -vcodec mpeg4 '<out.mp4>',并通过multiprocessing.Pool(默认 8 个 worker)并行处理全部目录。
Step 5. 生成文件列表
无论使用 rawframes 还是 videos 格式,最后一步都是生成 mmaction2 需要的文件列表:
cd $MMACTION2/tools/data/sthv1/ bash generate_{rawframes, videos}_filelist.sh两个脚本分别调用通用工具 build_file_list.py。以 rawframes 为例,generate_rawframes_filelist.sh 依次执行:
PYTHONPATH=. python tools/data/build_file_list.py sthv1 data/sthv1/rawframes/ \ --rgb-prefix '0' --num-split 1 --level 1 --subset train --format rawframes --shuffle PYTHONPATH=. python tools/data/build_file_list.py sthv1 data/sthv1/rawframes/ \ --rgb-prefix '0' --num-split 1 --level 1 --subset val --format rawframes --shufflevideos 格式则把路径换成data/sthv1/videos/、格式换成--format videos。各参数含义如下:
| 参数 | 说明 |
|---|---|
sthv1(位置参数) | 数据集名,决定使用parse_sthv1_splits()解析官方 train/val/test 划分 |
src_folder(位置参数) | 帧目录(rawframes 格式)或视频目录(videos 格式) |
--rgb-prefix '0' | RGB 帧前缀。官方帧为00001.jpg,即数字开头,前缀记为'0'(默认img_);光流前缀保持默认flow_x_/flow_y_ |
--num-split 1 | 按 1 个划分生成列表(STH-V1 官方只有 train/val 两分,不使用 UCF-101 那样的 3-split) |
--level 1 | 数据目录为单层结构 |
--subset train/val | 分别生成训练、验证列表,执行两次 |
--format rawframes/videos | 列表内容格式 |
--shuffle | 对列表做随机打散 |
从实现看,生成流程分为两步(build_file_list.py 的 main()):
- 扫描目录建立
frame_info:rawframes 模式调用 parse_directory(),按rgb_prefix、flow_x_prefix、flow_y_prefix统计每个视频目录下的 RGB 帧数与光流帧数,并校验flow_x与flow_y文件数是否一致,不一致会抛出ValueError——这意味着若你只提取了 x 方向光流,此步骤会直接报错;videos 模式则用 glob 收集 mp4 文件列表。 - 解析官方划分并写入列表:
parse_sthv1_splits(1)读取 Step 1 的 4 个 CSV 标注文件,将每条记录映射为(视频相对路径, 类别索引),再按格式写入不同行。
最终输出的文件列表格式为:
- rawframes:
<video_id> <rgb帧数> <类别索引>,例如0000001 33 43; - videos:
<video相对路径> <类别索引>,例如0000001.mp4 43。
由于--num-split 1,输出文件命名为{dataset}_{subset}_list_{format}.txt,即:
data/sthv1/sthv1_train_list_rawframes.txt data/sthv1/sthv1_val_list_rawframes.txt data/sthv1/sthv1_train_list_videos.txt data/sthv1/sthv1_val_list_videos.txt这正是各 STH-V1 模型配置中ann_file_train/ann_file_val所引用的文件,例如 tanet_imagenet-pretrained-r50_8xb6-1x1x16-50e_sthv1-rgb.py 与 tin_imagenet-pretrained-r50_8xb6-1x1x8-40e_sthv1-rgb.py 均指向上述文件。
另外值得一提的是 STH-V1 特有的标签翻转处理:由于数据集中存在方向对偶的动作对,TANet 的 sthv1 配置 定义了sthv1_flip_label_map = {2: 4, 4: 2, 30: 41, 41: 30, 52: 66, 66: 52}并传给Flip变换——水平翻转样本时同步交换对应类别标签(如 "Turning the camera left/right while filming something" 互为镜像),这是数据增强阶段与 Step 1 类别映射直接呼应的一处细节。
Step 6. 检查目录结构
完成全部数据处理后,项目根目录下应得到如下结构(仅针对 STH-V1 部分):
mmaction2 ├── mmaction ├── tools ├── configs ├── data │ ├── sthv1 │ │ ├── sthv1_{train,val}_list_rawframes.txt │ │ ├── sthv1_{train,val}_list_videos.txt │ │ ├── annotations │ | ├── videos │ | | ├── 1.mp4 │ | | ├── 2.mp4 │ | | ├──... │ | ├── rawframes │ | | ├── 1 │ | | | ├── 00001.jpg │ | | | ├── 00002.jpg │ | | | ├── ... │ | | | ├── flow_x_00001.jpg │ | | | ├── flow_x_00002.jpg │ | | | ├── ... │ | | | ├── flow_y_00001.jpg │ | | | ├── flow_y_00002.jpg │ | | | ├── ... │ | | ├── 2 │ | | ├── ...对照检查要点:
data/sthv1/下存在两份列表文件(rawframes 与 videos 各一份 train/val);data/sthv1/annotations/下有 4 个 CSV 标注文件;data/sthv1/rawframes/<video_id>/内同时包含{:05}.jpgRGB 帧与(可选的)flow_x_*/flow_y_*光流帧;- (若执行了 Step 4)
data/sthv1/videos/下存在对应 mp4 文件。
后续:训练与评测
数据准备完成后,即可使用仓库内现成的 STH-V1 模型配置进行训练与评测,仓库提供了多套现成配置,例如:
- tin_imagenet-pretrained-r50_8xb6-1x1x8-40e_sthv1-rgb.py(TiN + ImageNet 预训练 ResNet50,
num_classes=174) - tanet_imagenet-pretrained-r50_8xb6-1x1x16-50e_sthv1-rgb.py、tanet_imagenet-pretrained-r50_8xb8-1x1x8-50e_sthv1-rgb.py
- trn_imagenet-pretrained-r50_8xb16-1x1x8-50e_sthv1-rgb.py
- tpn-tsm_imagenet-pretrained-r50_8xb8-1x1x8-150e_sthv1-rgb.py
基本的训练/测试入口为:
python tools/train.py configs/recognition/tin/tin_imagenet-pretrained-r50_8xb6-1x1x8-40e_sthv1-rgb.py python tools/test.py configs/recognition/tin/tin_imagenet-pretrained-r50_8xb6-1x1x8-40e_sthv1-rgb.py --checkpoint <ckpt_path>完整训练与评测流程参见仓库文档 Training and Test Tutorial。
常见问题排查
- 报错
x and y direction have different number of flow images:parse_directory()在生成 rawframes 列表前会校验每个视频目录下flow_x_*与flow_y_*的文件数量是否相等。出现此错误说明光流提取不完整,请检查extract_flow.sh运行日志并重跑失败目录。 - 模型加载后报文件不存在 / 帧数异常:确认配置文件中的
filename_tmpl是否为'{:05}.jpg'。若误用默认的img_{:05}.jpg,RawframeDecode将无法定位 STH-V1 的帧文件。 - 光流列表帧数为 0 或列表缺失视频:检查
--rgb-prefix '0'是否与实际帧名一致,以及--level 1是否匹配目录层级(STH-V1 官方帧为单层目录,若自行整理成两级目录需改为--level 2并同步调整编码与列表脚本参数)。 - 视频 fps 设置:
encode_videos.sh使用--fps 12,与 STH-V1 官方帧率一致;若修改帧率,VideoDataset相关配置中的frame_interval、SampleFrames等采样参数需相应调整。
小结
STH-V1 的数据准备是 mmaction2 中"从原始帧起步"的典型范例:与提供 mp4 的数据集不同,它的起点是官方 JPEG 帧序列。整个流程可以概括为六步——下载标注(Step 1)、解压 RGB 帧(Step 2)、可选提取 TV-L1 光流(Step 3)、可选编码 mp4(Step 4)、生成 train/val 文件列表(Step 5)、核对目录结构(Step 6)。核心注意点有三个:官方帧名模板{:05}.jpg必须在配置中显式声明;光流与视频均为可选产物,视模型输入需求取舍;文件列表由通用工具 build_file_list.py 结合官方 CSV 划分生成,--rgb-prefix '0'与--level 1是 STH-V1 区别于其他数据集的关键参数。完成后即可直接使用configs/recognition/下的 STH-V1 模型配置开展训练与评测。
- 人工智能
- 计算机视觉
- 深度学习
【免费下载链接】mmaction2
OpenMMLab's Next Generation Video Understanding Toolbox and Benchmark
相关推荐
MMAction2 中 Diving48 数据集的完整准备流程:从官方源下载到 RGB/光流帧抽取与文件列表生成
MMAction2 中 Diving48 数据集的完整准备流程:从官方源下载到 RGB/光流帧抽取与文件列表生成 本文基于 MMAction2 仓库中 Divi
人工智能计算机视觉深度学习mmaction2 中 MultiSports 数据集准备实战:从原始标注到时空动作检测训练的全流程解析
mmaction2 中 MultiSports 数据集准备实战:从原始标注到时空动作检测训练的全流程解析 本篇指南基于 mmaction2 仓库中 MultiS
人工智能计算机视觉深度学习mmaction2 准备 Moments in Time 数据集:从视频落盘到 RGB/Flow 抽帧与文件列表生成的完整实战指南
mmaction2 准备 Moments in Time 数据集:从视频落盘到 RGB/Flow 抽帧与文件列表生成的完整实战指南 本文基于 mmaction2
人工智能计算机视觉深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考