返回列表

9th place solution

461. NFL Health & Safety - Helmet Assignment | nfl-health-and-safety-helmet-assignment

开始: 2021-08-10 结束: 2021-11-02 运动员表现 数据算法赛
第9名解决方案

第9名解决方案

首先,我要感谢主办方举办了如此精彩的比赛!这个问题非常有趣,让我在整整3个月的时间里全身心投入其中。

在这里,我将展示我是如何解决这个问题的。解决方案流程由4个部分组成:

  1. YOLO-v5 头盔检测
  2. 追踪数据 <-> 边界框 单应性矩阵估计
    1. 使用形状上下文估计第1帧的单应性矩阵
    2. 修改前一帧的单应性矩阵以获取当前帧的矩阵
  3. 使用估计的单应性矩阵进行第一次头盔分配
  4. 使用 DeepSort 和先前获得的单应性矩阵进行第二次头盔分配

1. YOLO v5 头盔检测

众所周知,主办方提供了基准头盔检测结果。起初,我认为检测性能已经足够,并使用了一段时间。然而,我注意到一些涉及撞击的头盔缺失了。因此,我尝试训练一个 YOLO 检测器来减少这种漏检。训练设置如下:

  • 训练数据:"images" 文件夹中的 jpg 图像,分辨率为 1280px
  • 模型:yolov5x
  • Batch size:16
  • Epochs:20(固定)
  • 混合精度:开启
  • 环境:AWS SageMaker p3.8xlarge
  • 无验证集
  • 其他设置(学习率、优化器等):默认

效果非常显著,当时分数跃升了约 0.1。

编辑:我在最终提交中用基准检测替换了我的检测结果,并进行了延迟提交。我得到了 0.803(私有)/ 0.841(公有)的成绩,这表明 YOLO 使分数提高了 0.057。

2.1 使用形状上下文估计初始帧单应性矩阵

为了将传感器数据与第1帧中的边界框匹配,我使用了形状上下文。形状上下文是点相对位置的直方图。它可以为每个点计算,并用于点集配准。关于形状上下文的详细信息,请自行搜索。详细过程如下:

  1. 归一化边界框(置信度 > 0.25)和传感器数据的坐标。作为归一化因子,我使用了 np.median(np.sort(cdist(points,points),axis=1)[:,1])。这个量表示最近球员之间的中位数距离。
  2. 按一定比例缩放和旋转传感器数据坐标(稍后提及)。
  3. 计算追踪数据中每个点的形状上下文和边界框质心的形状上下文。
  4. 计算传感器描述符和边界框描述符之间的余弦距离矩阵。
  5. 使用 scipy.optimize.linear_sum_assignment 进行匈牙利算法匹配。此时,匹配结果通常包含错误分配的对。
  6. 使用 cv2.findHomography 计算单应性矩阵。我像迭代最近点(ICP)算法一样进行此计算。在前几次迭代中,我使用 cv2.LMEDS 来修复错误分配的对。如果代价函数停止改善,则关闭 LMEDS 并切换到正常的单应性估计。
  7. 如果代价函数停止改善,停止迭代。

下图描述了从 2.3 到 2.7 的流程。

流程图

代价函数

我使用以下代码评估单应性变换的拟合度。这个代价函数可以解释为边界框与变换后追踪坐标之间的均方根(RMS)距离。

dist=cdist(homography_transformed_tracking_points,bbox_points)**2
row_ind,col_ind=linear_sum_assignment(dist)
score=np.sqrt(dist[row_ind,col_ind].sum()/len(row_ind))

旋转/缩放因子的暴力优化

我优化了 2.1.2 中使用的旋转/缩放因子。换句话说,我多次改变旋转/缩放因子执行上述过程,并选择最佳因子。优化范围如下:

  • 旋转角度:[0, 2pi],分辨率为 pi/500
  • X 缩放因子:{0.5, 1.25, 3}
  • Y 缩放因子:{0.5, 1.25, 3}

2.2 修改前一帧的单应性变换以获取当前帧的变换

由于相邻帧的球员位置相似,

同比赛其他方案