AVA数据集标注实战指南:从零开始掌握高效标注技巧

1次阅读
没有评论

共计 2776 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

AVA 数据集结构解析

AVA 数据集的核心在于时空定位(spatio-temporal localization)和行为识别。它的标注包含两个关键部分:

AVA 数据集标注实战指南:从零开始掌握高效标注技巧

  • 边界框(bounding box):以 [x1, y1, x2, y2] 格式存储,表示人物在视频帧中的位置
  • 行为标签(action label):来自 80 类预定义动作(如 ”walk”、”hand shake”),每个边界框可对应多个动作

标注文件通常为 CSV 格式,关键字段包括:

  1. video_id:视频唯一标识
  2. frame_id:时间戳(每秒 30 帧)
  3. person_id:同一人物的跨帧追踪 ID
  4. bbox:归一化坐标(0- 1 范围)
  5. action_ids:分号分隔的动作 ID 列表

主流标注工具对比

CVAT(Computer Vision Annotation Tool)

  • 优势
  • 内置视频插值功能,标注关键帧后自动生成中间帧
  • 支持多人协作和任务分配
  • 可直接导出 AVA 标准格式

  • 劣势

  • 部署需要 Docker 环境
  • 对长视频支持较差

Label Studio

  • 优势
  • 网页版即开即用
  • 灵活的标签配置界面
  • 支持主动学习工作流

  • 劣势

  • 视频标注需要安装插件
  • 多人标注管理功能较弱

VGG Image Annotator (VIA)

  • 优势
  • 纯前端工具,无需安装
  • 极简的 JSON 标注格式

  • 劣势

  • 缺乏视频专用功能
  • 无法处理大体积文件

推荐选择:CVAT(适合团队生产环境)或Label Studio(适合快速原型开发)

标注规范制定要点

动作边界判定原则

  1. 起始帧:动作特征首次明确出现的帧
  2. 结束帧:动作特征完全消失的下一帧
  3. 模糊区间:当存在疑问时,遵循 ” 宁可漏标,不要错标 ” 原则

多人交互场景处理

  • 独立标注:每人单独标记 bounding box
  • 关联标注 :使用相同的person_id 追踪交互对象
  • 组合动作:为双方同时添加交互类标签(如 ”hand shake”)

Python 标注校验示例

import cv2
import pandas as pd
from typing import List, Tuple

class AVAValidator:
    def __init__(self, csv_path: str):
        self.df = pd.read_csv(csv_path)
        self.error_log = []

    def check_bbox(self, bbox: List[float]) -> bool:
        """验证边界框是否合法"""
        x1, y1, x2, y2 = bbox
        if not (0 <= x1 < x2 <= 1 and 0 <= y1 < y2 <= 1):
            self.error_log.append(f"Invalid bbox coordinates: {bbox}")
            return False
        return True

    def visualize(self, video_path: str, output_path: str):
        """标注可视化工具"""
        cap = cv2.VideoCapture(video_path)
        fps = cap.get(cv2.CAP_PROP_FPS)

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            # 绘制当前帧所有标注
            frame_id = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
            annotations = self.df[self.df['frame_id'] == frame_id]

            for _, row in annotations.iterrows():
                x1, y1, x2, y2 = eval(row['bbox'])
                h, w = frame.shape[:2]
                pt1 = (int(x1*w), int(y1*h))
                pt2 = (int(x2*w), int(y2*h))
                cv2.rectangle(frame, pt1, pt2, (0,255,0), 2)

            cv2.imshow('Validation', frame)
            if cv2.waitKey(int(1000/fps)) == 27:
                break

        cap.release()
        cv2.destroyAllWindows()

质量保障方案

多人标注一致性检验

  1. Krippendorff’s Alpha 系数:衡量不同标注者间的一致性

    from sklearn.metrics import cohen_kappa_score
    
    def calculate_agreement(annotator1, annotator2):
        return cohen_kappa_score(annotator1, annotator2)

  2. 冲突解决流程

  3. 第一阶段:标注员自行讨论达成共识
  4. 第二阶段:由资深标注员仲裁
  5. 第三阶段:剔除无法达成一致的样本

标签分布分析

import matplotlib.pyplot as plt

def plot_label_distribution(df):
    action_counts = df['action_ids'].str.split(';').explode().value_counts()
    plt.bar(action_counts.index, action_counts.values)
    plt.xticks(rotation=90)
    plt.show()

避坑指南

帧偏移错误解决方案

  1. 问题现象:动作标签与视觉内容出现时间差
  2. 解决方法
  3. 预处理阶段统一视频帧率
  4. 使用 ffmpeg 精确提取关键帧
  5. 在标注工具中启用帧同步预览

  6. 检测代码

    def detect_frame_shift(video_df, threshold=5):
        """检测连续帧间的人物位移异常"""
        shifts = []
        for person_id in video_df['person_id'].unique():
            person_df = video_df[video_df['person_id'] == person_id].sort_values('frame_id')
            for i in range(1, len(person_df)):
                prev_bbox = eval(person_df.iloc[i-1]['bbox'])
                curr_bbox = eval(person_df.iloc[i]['bbox'])
                dx = abs((prev_bbox[0]+prev_bbox[2])/2 - (curr_bbox[0]+curr_bbox[2])/2)
                dy = abs((prev_bbox[1]+prev_bbox[3])/2 - (curr_bbox[1]+curr_bbox[3])/2)
                if dx > threshold or dy > threshold:
                    shifts.append((person_df.iloc[i]['frame_id'], dx, dy))
        return shifts

延伸思考

  1. 如何处理视频中部分遮挡的人物标注?
  2. 当同一人物同时执行多个动作时,标签权重应如何分配?
  3. 如何设计增量学习策略来优化长期视频的标注效率?
正文完
 0
评论(没有评论)