文章目录

  • 0. 前言
  • 1. AVA简介
    • 1.1. 基本情况
    • 1.2. 如何获取
    • 1.3. 数据集构建过程
    • 1.4. annotations 解析
  • 2. SlowFast
    • 2.1. 构建 `Ava` 对象
    • 2.3. 读取某个keyframe信息
  • 3. MMAction

0. 前言

  • 要基于AVA数据集做一些工作,网上的文章都不能满足我的要求,所以自己写一篇记录一下。
  • 参考资料:
    • 官网(需要翻墙)
    • 相关论文
  • 感想:
    • 行为识别数据集下载真的困难,国内搞过的都懂……
    • 作为组里第一个吃螃蟹的,到现在还在跟 Kinetics-700、ActivityNet 等数据集死磕,辛酸泪。
    • AVA 已经是最容易的了,毕竟可以用迅雷下载。
  • 本文主要内容:
    • 第一章:介绍AVA,如何获取、标注过程、annotations解析。
    • 第二章:SlowFast中解析AVA的过程。
    • 第三章:mmaction中解析AVA的过程。(尚未完成)

1. AVA简介

1.1. 基本情况

  • 数据集类别:Spatio-Temporal Action Detection,即时空行为检测。

    • 举个例子,就是检测出视频中所有人的位置以及对应的行为类别。
  • 数据集形式(这里是简单介绍,后面会有更详细的说明):
    • 要标记的内容包括人物bbox,以及每个人的行为类别,同一时间同一人可能有多个行为

      • 标记的内容还有还有每个实体编号,即相邻关键帧中的人物如果是同一个人,则拥有相同的实体编号。换句话说,“实体编号”其实就是目标跟踪的标签。
    • 并不是对视频中的每一帧进行标记,而只是对关键帧进行标记。
    • 所谓关键帧,按我的理解就是每秒取1帧作为关键帧,对该帧进行标记。
  • 行为类别:标签一共有80类,(但验证时只用到其中的60类)。80类标签分为三类(person movement, object manipulation, person interaction),具体信息如下。
    • person movement

      • bend/bow (at the waist)
      • crawl
      • crouch/kneel
      • dance
      • fall down
      • get up
      • jump/leap
      • lie/sleep
      • martial art
      • run/jog
      • sit
      • stand
      • swim
      • walk
    • object manipulation
      • answer phone
      • brush teeth
      • carry/hold (an object)
      • catch (an object)
      • chop
      • climb (e.g., a mountain)
      • clink glass
      • close (e.g., a door, a box)
      • cook
      • cut
      • dig
      • dress/put on clothing
      • drink
      • drive (e.g., a car, a truck)
      • eat
      • enter
      • exit
      • extract
      • fishing
      • hit (an object)
      • kick (an object)
      • lift/pick up
      • listen (e.g., to music)
      • open (e.g., a window, a car door)
      • paint
      • play board game
      • play musical instrument
      • play with pets
      • point to (an object)
      • press
      • pull (an object)
      • push (an object)
      • put down
      • read
      • ride (e.g., a bike, a car, a horse)
      • row boat
      • sail boat
      • shoot
      • shovel
      • smoke
      • stir
      • take a photo
      • text on/look at a cellphone
      • throw
      • touch (an object)
      • turn (e.g., a screwdriver)
      • watch (e.g., TV)
      • work on a computer
      • write
    • person interaction
      • fight/hit (a person)
      • give/serve (an object) to (a person)
      • grab (a person)
      • hand clap
      • hand shake
      • hand wave
      • hug (a person)
      • kick (a person)
      • kiss (a person)
      • lift (a person)
      • listen to (a person)
      • play with kids
      • push (another person)
      • sing to (e.g., self, a person, a group)
      • take (an object) from (a person)
      • talk to (e.g., self, a person, a group)
      • watch (a person)

1.2. 如何获取

  • 两种获取方式

    • 标签可以在官网上下载标签,视频可以通过 youtube-dl 获取。
    • 官方提供了aws数据源,具体可以参考这里。
      • 可以用迅雷,可以用迅雷,可以用迅雷,重要的事说三遍。写个脚本写上所有视频链接地址,然后批量传入迅雷,美滋滋。(如果Kinetics和ActivityNet都能这么下就好了)
      • 可以用百度云离线下载,不过好像不能批量导入下载链接,没仔细研究。
  • SlowFast/MMAction 中都提供了 AVA 数据预处理相关脚本,具体在后续章节会介绍,可以参考。

1.3. 数据集构建过程

  • 这部分内容主要参考了 数据集论文
  • 第一步:Action vocabulary generation
    • 任务:确定要标注的行为类别以及继承关系。
    • 选择/设置“行为类别”时有三个准则:
      • generality,即通用性,而不是特定环境下的特定动作(如“在篮球场打篮球”)。
      • atomicity,即原子性。每个动作都有其特点,且与交互的物体无关(如行为 hold 且不要指定hold的物体)。
      • exhaustivity,即类别尽可能丰富。
  • 第二步:Movie and segment selection
    • 任务:构建原始视频数据集,为后续标注工作做准备。
    • AVA的数据源来自电影片段
    • 每个电影只标注第15-30分钟内的视频
    • 每个长度为15分钟的视频都转换为897个长度为3s的视频片段(clip)。
      • 15分钟共900秒,窗口长度为3秒,stride为1秒,滑动897次得到897个clip。
      • 每个clip对对应一个keyframe(关键帧),关键帧是1.5秒位置。
    • 搞了一个各个国家顶尖演员列表,然后在Youtube中对每个演员进行搜索,寻找符合条件的电影。
      • 条件包括:有 file/television 标签,时长超过30分钟,发布时间超过1年,观看人数超过1000,且不包含黑白、低清晰度、卡通等类别的电影。
  • 第三步:Person bounding box annotation
    • 任务:针对每个keyframe标注人物bbox。
    • 使用了混合标注法:
      • 先用Faster-RCNN标注,(说是 set operating point 从而保证高精度,不知道啥意思,猜测就是提高了阈值吧)。
      • 之后在人工标注遗漏的bbox。
    • bbox对最终结果影响很大,所以这一步会比较注意。
  • 第四步:Person link annotation
    • 任务:对相邻keyframe中的任务bbox进行关联。
    • 方法:
      • 先机器标注一波:通过计算相邻两帧不同bbox之间的相似度,然后根据匈牙利算法进行匹配。
      • 再手动处理一波:手工删除FP样本。
  • 第五步:Action annotation
    • 任务:标注行为类别。
    • 通过众包实现。不可避免的,标注人会少标行为(因为行为太多了)。
    • 参考界面如下:

1.4. annotations 解析

  • 以 v2.2 为例,解压 ava_v2.1.zip 得到的结果如下。

    • V2.1 和 V2.2 的区别:

      • 标签内容没细看,可能v2.2细化了吧。
      • 视频源没有任何变化,即V2.1与V2.2的 train/val/test 的视频是完全相同的。
  • 行为类别文件:
    • ava_action_list_v2.1_for_activitynet_2018.pbtxt:60类行为,Evaluate时使用
    • ava_action_list_v2.1.pbtxt:80类行为
  • 行为标签文件:
    • ava_train_v2.1.csvava_val_v2.1.csvava_test_v2.1.txt
    • 其中,train/val有标签,test只是视频名称列表。
    • train/val 每行代表一个样本,共有5个部分
      • video_id:视频名称,不包括文件后缀,即Youtube对应url
      • middle_Frame_timestamp:关键帧所在位置(第几秒)
      • person_box:包括了四列,(x1, y1, x2, y2),分别代表左上、右下点的位置。
      • action_id:即ava_action_list_v2.1.pbtxt中对应的id。
      • person_id:bbox中人物的编号,即 person link 时产生的标签,每个人的id不同。
  • ava_included_timestamps_v2.2.txt:每个视频要检测的位置,即第902到1798秒。
  • 不需要进行检测的timestamp
    • ava_train_excluded_timestamps_v2.1.csv
    • ava_val_excluded_timestamps_v2.1.csv
    • ava_test_excluded_timestamps_v2.1.csv
    • 即 train/val/test 数据集中每个视频不需要进行检测的timestamp。

2. SlowFast

  • 相关源码:

    • 数据集预处理
    • 数据集解析(结果用于模型训练)
  • 数据集解析源码主要模块
    • 构建 Ava 对象,解析标签文件,设置数据预处理参数,以 clip 为单位保存相关信息。
    • 读取某个 clip 的相关信息。
  • 流水账,没兴趣的跳过。

2.1. 构建 Ava 对象

  • 第一步:为每个视频进行编号,并保存对应的帧绝对路径的列表。

    • 从代码角度看保存了两个列表

      • _video_idx_to_name

        • 每个视频原来有个 video_name,即youtube中对应url后缀,如 1j20qq1JyX4
        • 在代码中,video_name用起来不方便,所以对视频进行编号,即每个 video_name 对应一个 video_id(从0开始编号)。
        • 本对象是 list,index就是 video_id,value就是video_name
      • _image_paths
        • 保存每个视频对应帧的绝对路径。
        • 本对象是list,index是 video_id,value是一个list(中每个元素是帧绝对路径,注意,这个list中帧文件的顺序必须是从小到大,不然后面代码有问题)。
    • 源码细节:主要输入数据就是 frame_lists 文件
      • 该文件不是AVA官方提供的,而是FAIR提供的,可以自己生成。
      • 该文件中保存有video_name以及对应所有帧的相对路径,且帧文件的顺序就是从小到大。
    • 主要就是 ava_helper.load_image_lists 实现。
  • 第二步:解析行为标签文件。
    • 从代码角度看,就是构建了一个list boxes_and_labels

      • 该数据类型是:boxes_and_labels[video_id][frame_sec_int] = list([box_i, box_i_labels])

        • boxes_and_labels[video_id].keys() 就是所有可用的时间点,即range(902, 1799)
        • len(boxes_and_labels[video_id][frame_sec_int]) 就是这个时间点 box 的数量。
      • boxes_and_labels 整体是一个列表,index是 video_id,value是一个字典。
      • 该字典的 key 是 frame_sec_int,即 [902, 1798],表示视频中的第几帧。
      • 该字典的 value 是列表,取名为 value_list
      • value_list通过列表形式保存 bbox(x1, y1, x2, y2形式) 以及对应的
      • labels(同一个box可能有多个标签)两部分信息。
      • 其中,box_i 的形式是 x1, y1, x2, y2
    • 源码细节:
      • 这一步的输入数据主要包括GT与Predict两部分。
      • GT指的就是AVA官方提供的标签文件,如ava_train_v2.1.csv
      • Predict指的是验证/测试时用的数据,只包括每个视频每一帧的人物bbox以及对应的score,不包括行为类别。包括 video_name, frame_sec, bbox_x1, bbox_y1, bbox_x2, bbox_y2, category, score。在使用Predict数据时会根据 score 筛选一部分数据。
    • 主要通过 ava_helper.load_boxes_and_labels 实现。
  • 第三步:构建关键帧数据。
    • 从源码上看,就是构建了 _keyframe_indices_keyframe_boxes_and_labels 两个列表。

      • 这两个对象是配合使用的。两个列表中相同index的元素就是后续构建 clip 样本的输入数据。
      • 保存了所有可用关键帧相关信息。
    • _keyframe_indices
      • 是个list对象,index的作用就是与 _keyframe_boxes_and_labels 对应。
      • 主要保存四个数据 video_idx, sec_idx, sec, frame_idx
      • sec_idx 指的是当前关键帧在这个视频中所有关键帧的idx,从0开始取值
      • sec 指的是当前关键帧在这个视频中的位置,从902开始取值
      • frame_idx 指的是当前关键帧的具体编号,计算方法(sec-900)*FPS,其实就是每个clip的中心frame编号。
    • _keyframe_boxes_and_labels
      • 是个list对象,index的作用就是与 _keyframe_indices 对应。
      • 其实就是将上一步中的 boxes_and_labels[video_id][frame_sec_int] 直接保存下来。
    • 主要通过 ava_helper.get_keyframe_data 实现。

2.3. 读取某个keyframe信息

  • 这里,每个keyframe的信息就是对应一个clip数据,主要就是通过 __getitem__ 实现。

    • 输入的idx其实就是 2.2. 中第三步 _keyframe_indices 中的下标。
  • 第一步:获取 _keyframe_indices 对应 idx 下标信息。
    • video_idx, sec_idx, sec, center_idx,sec_idx 从0开始取值,sec从902开始取值。
  • 第二步:根据输入数据,进行数据采样。
    • center_idx 为中心,根据输入数据 _seq_len_sample_rate 进行采样。
    • 采样细节:
      • center_idx - _seq_len // 2开始,在 [center_idx - _seq_len // 2, center_idx + _seq_len // 2) 范围内,根据 _sample_rate 进行采样。
      • _seq_len 的取值其实是 _sample_rate * _sample_frames_length 得到的。
      • 刚开始在想,为什么这个采样刚好就能用。列了不等式算了算,刚刚好,这个样子采样其实刚好能得到 _sample_frames_length 个帧下标。
  • 第三步:获取 _keyframe_boxes_and_labels 获取该关键帧的所有boxes与对应label信息。
  • 第四步:根据采样结果以及 _image_paths 读取帧文件绝对路径,并读取对应图片。
    • _image_paths[video_idx][frame] for frame in seq,其中 seq 就是上面采样得到的结果。
  • 第五步:图片数据预处理。
    • 有pytorch与cv2两种模式,预处理的过程是一样的,只是调用的库不同。
    • 得到的结果都是 C, T, H, W 结构。
    • 预处理过程包括:
      • 数据类型/范围转换:[0, 255] -> [0, 1]
      • resize/crop操作:训练集 随机短边resize -> random crop -> random flip;验证集 短边resize -> center crop;测试集 短边resize。
        • 随机短边resize通过 transform.random_short_side_scale_jitter 实现,根据输入参数 TRAIN_JITTER_SCALES 指定短边范围,随机获取其中数值作为短边的size,然后进行resize。
      • 随机色彩变换,主要通过 transform.color_jittertransform.lighting_jitter 实现。
      • 图像标准化,减去平均数除以标准差。
  • 第六步:构建行为识别 one-hot 形式label。
    • label的shape为 [num_boxes, num_classes]
    • 注意,每行可能不止一个类别为1。
  • 第七步:分别为不同分支构建输入数据。
    • 对于I3D模型,这一步其实也没做什么。
    • 对于SlowFast模型,这一步会分别对 Slow 分支与 Fast 分支构建对应的输入图片。
      • Fast分支就是之前输入的。
      • Slow分支就是在T纬度上进行sample rate为SLOWFAST.ALPHA的采样。
  • 第八步:构建输出数据。
    • 输出数据包括四部分 imgs, labels, idx, extra_data
    • imgs 是第七步图像预处理的结果,是个list,分别对应每个分支的结果,每个分支的shape为 [C, T, H, W]
    • labels 就是第六步的结果,shape为 [num_boxes, num_classes]
    • idx__getitem__ 的输入数据。
    • extra_data 是个字典,包括三个数据:
      • boxes 经过数据预处理后的bbox。
      • ori_boxes 原始 boxes,即在resize/crop等操作前的bbox。
      • metadata 元数据列表,列表长度与 boxes 相同,每个元素都是 [video_id, sec]。sec从902开始取值。

3. MMAction

  • 相关源码:

    • 数据集预处理
    • 数据集解析(结果用于模型训练)
  • 等待补充

AVA Actions Dataset 详解相关推荐

  1. mutations vuex 调用_Vuex的mutations与actions使用详解

    这次给大家带来Vuex的mutations与actions使用详解,mutations与actions使用的注意事项有哪些,下面就是实战案例,一起来看一下. 区分 actions 和 mutation ...

  2. mutations vuex 调用_Vuex的mutations与actions使用详解 -

    这次给大家带来vuex使用步骤详解,vuex使用的注意事项有哪些,下面就是实战案例,一起来看一下.vuex是一个专门为vue.js设计的集中式状态管理架构.状态?我把它理解为在data中的属性需要共享 ...

  3. 1.11.Flink DataSetAPI、DataSet API之Data Sources、DataSet API之Transformations、DataSet Sink部分详解

    1.11.Flink DataSetAPI 1.11.1.DataSet API之Data Sources 1.11.2.DataSet API之Transformations 1.11.3.Data ...

  4. 详解协同感知数据集OPV2V: An Open Benchmark Dataset and Fusion Pipeline for Perception with V2V Communication

    在<详解自动驾驶仿真框架OpenCDA: An Open Cooperative Driving Automation Framework Integrated with Co-Simulati ...

  5. actions的使用详解

    actions的使用详解 为何要有actions环节 我们之前学了vuex状态管理,组件可以引用state,但是不能直接修改state,比如发送操作到actions,在此执行异步操作,然后再提交mut ...

  6. 《Spark商业案例与性能调优实战100课》第15课:商业案例之纯粹通过DataSet进行电商交互式分析系统中各种类型TopN分析实战详解

    <Spark商业案例与性能调优实战100课>第15课:商业案例之纯粹通过DataSet进行电商交互式分析系统中各种类型TopN分析实战详解

  7. ava虚拟机详解--GC算法和种类【重要】

    [声明] 欢迎转载,但请保留文章原始出处→_→ 本文主要内容: GC的概念 GC算法  引用计数法(无法解决循环引用的问题,不被java采纳) 根搜索算法 现代虚拟机中的垃圾搜集算法: 标记-清除 复 ...

  8. FFmpeg入门详解之82:FFmpeg转码器Java版之ava编码

    创建数据库:db_webavtc 创建数据表:avcategory(素材类别) id int primary key, pid int , cname varchar(255), cmemo varc ...

  9. Redis配置文件redis.conf文件详解

    Redis配置文件redis.conf文件详解 唠嗑 这里面的意思只要看得差不多其实就是已经对redis有熟悉的感觉,就比如 推塔已经推到别人家的大门~~~~~~~~废话不多说直接开始了 知道大家都不 ...

最新文章

  1. relay.build调用关系
  2. Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for i
  3. WP8中 ListBox x下拉刷新 以及 ScrollViewer/ListBox 的ManipulationCompleted 失效的解决方案
  4. Centos7 ping不了百度
  5. 去除编译警告@SuppressWarnings注解用法详解(转)
  6. tensorflow中关于vgg16的项目
  7. MapReduce改造fp-growth算法
  8. saiku连mysql 使用_saiku应用的调试
  9. 《OpenGL编程指南(原书第9版)》——3.2 OpenGL缓存数据
  10. 如何在MVC中下载模板和上传word文件
  11. [翻译]AKKA笔记 - DEATHWATCH -7
  12. 【movable-area、movable-view】 可移动区域组件说明
  13. python是什么类型的编程语言-Python是个什么语言?
  14. Layui官网文档备份, Layui文档站点,LayuiAdmin
  15. 【速达软件】【速达5000】需求采购订单数量不能大于(请购数量-已订数量)
  16. 暗黑破坏神2 符文自动合成--按键精灵源码
  17. Excel教程:从头认识Excel数据透视表【网盘分享108集教程】
  18. 计算机四级数据库分值分布,计算机四级数据库工程师考试成绩查询注意事项
  19. 单片机STM32低功耗
  20. 文件夹删不掉,显示有文件打开怎么办

热门文章

  1. 数字逻辑 易错点 地线 GROUND 与 GND/DGND
  2. 什么是Ground-truth,Ground-truth什么意思
  3. 《王道计算机组成原理》学习笔记和总目录导航
  4. vue 3D轮播展示 --vue-carousel-3d
  5. Java 当前日期判断节假日
  6. ISO26262第二版发布
  7. 笨方法学python 习题29-31
  8. [瓦尔登湖]一颗璀璨的明珠
  9. java斗地主案例,没有界面
  10. 斗地主农民手牌的58684015种可能性