• 问答
  • 技术
  • 实践
  • 资源
【以赛代练】Kaggle: NFL Helmet Assignment (Top8%铜牌区) 方案分享
技术讨论

作者丨Ai
来源丨宅码
编辑丨极市平台

NFL赛程3个月...导致鸽了这么久。这是今年目前我参加的最有意思的比赛-Kaggle: NFL Health & Safety - Helmet Assignment[1],比赛打完仍意犹未尽,特此分享我们团队的解决方案与高分选手的思路(有对比才有伤害),不足之处,还望批评指正。

一、大赛简介

【背景】美国国家橄榄球联盟 (NFL) 和亚马逊网络服务 (AWS) 正在合作开发最佳的运动损伤监测和缓解计划。去年Kaggle NFL比赛是做头盔目标检测,今年难度升级。在今年的比赛中,赛方希望选手能从视频片段中识别和分配足球运动员的头盔。特别是,构建能够通过跟踪信息(Tracking Dataset,即NGS信息)将检测到的头盔分配给正确玩家的算法。我先介绍下NGS追踪数据是什么?NFL 的 Next Gen Stats (NGS) 程序采用复杂的跟踪技术通过每个球员肩垫中的RFID设备和嵌在每个体育场中的设备收集数据。这些设备会捕获多种数据,包括特定时间内上场球员名单、精准到英尺的球员位置、球员移动速度和方向等。[2],NGS追踪数据如下图所示:

图1:NGS追踪数据样例图

由于追踪数据是在每个球员垫肩上装设备采集到的数据,所以图1中每个点可以知道对应的球员ID是什么,而赛方希望我们做的事情是,基于追踪数据,给下面视频画面中的球员头盔匹配上正确的球员ID(注意:每场NFL比赛,有两个视角录制的视频):

图2:NFL视频画面样例图

【数据】关于数据集,总结有以下几类:

  1. images文件夹内的jpg文件和image_labels.csv:补充数据,可用于自行训练头盔目标检测器。
  2. [train/test]_baseline_helmets.csv:若不想头盔检测,可以直接用官方给的头盔检测baseline模型(仅用images和image_labels训练)的检测结果,包含vedio_frame下bbox和conf。
  3. [train/test]文件夹内的mp4文件:记录每场play,每个play有两份: Endzone和Sideline (两个视角)。这两份视频每帧能按时间匹配上。但在不同视角下,可能不同球手的可见程度不一样,你只需要预测真实可见的选手即可。
  4. [train/test]_player_tracking.csv:NGS追踪数据,每个球员都佩戴一个传感器,让我们可以在场上精确定位他们。
  5. train_labels.csv:训练集中,头盔追踪和碰撞标签。

【评估指标】由于赛方更关注头盔撞击的bbox有无正确分配到正确的球员ID,评估函数对撞击头盔的检测结果做加权,权重是无撞击头盔的1000倍。

$$Weighted Accuracy = \frac{TotalCorrect{nonimp}+(TotalCorrect{imp} 1000)}{TotalHelmets{nonimp}+(TotalHelmets{imp} 1000)}$$

二、团队方案

【时间】2021年8月16日-2021年11月2日(近3个月)。

【排名】48(Public)/64(Private),总共825支队伍,Top8%铜牌区。

【代码】https://github.com/AlvinAi96/kaggle-NLF-helmet-assignment

【团队】团队Baseline Plus Pro共三人:

  • Shao Eric: 邵兄,江南大学研究生,研究方向: 知识蒸馏,知乎id: 闪电侠的右手。
  • Leonrain: 刘兄,德国软件工程师,工作方向: 目标检测。
  • Alvin.ai: 我,ML研究员,工作方向:机器学习。

我们整体方案流程图如下所示:

图3:团队Baseline Plus Pro的整体解决方案流程图

1. 机位预测

我们有两个视角,分别是Sideline和Endzone,而每个视频可能处于不同侧,例如图1,Sideline的视频可能是在Home或Visitor一侧录制的,而Endzone也一样。因为后面要基于球员位置,将追踪数据中的球员ID匹配到视频头盔上,所以搞清楚当前视频下的摄像机在主/客队哪一侧是很有帮助的。我们针对Sideline和Endzone使用并尝试了不同的机位预测方法。

(1) Sideline机位预测

我们尝试了三种Sideline机位预测方法:

(a) x mapping:基于@tito开源的思路[3],分别对视频首帧画面头盔位置x和追踪数据中球员位置x进行的距离排序,然后根据排序结果,依次匹配球员,计算匹配距离。若视频画面180旋转后,与追踪数据的匹配距离最小,说明当前机位为Visitor Sideline,而不是Home Sideline。这也是我们最终采用的方法,线下准确率:59/60,错误的视频是存在某个场外替补球员没法很好的剔除,导致破坏了匹配位置的对应性。

图4:基于x位置的Sideline机位预测

(b) 基于地标线斜率和球员分布:这是@Adrian 开源的方法[4],首先,我们得留意一个背景:NFL比赛场上主客队上场球员各自是11个,可实际上,由于摄像机的位置和操作(旋转/位移/缩放)且头盔存在遮挡,导致实际头盔目标检测后的头盔数量,有三种情况:

  • 视频画面上头盔检测数>22个:多数是由于场外替补球员的头盔/观众的头或帽子被检测出来,少数是由于场内球员头盔被过度检测了。
  • 视频画面上头盔检测数=22个:绝大多数是画面涵盖了所有场内22个球员。
  • 视频画面上头盔检测数<22个:摄像机放大视角,记录的局部画面内球员数较少。

针对头盔检测数>22个的Sideline场景,Muresan使用了球员中心点和地标线斜率,具体步骤如下,流程可见图5:

  • 检测出第4帧视频画面中的白色地标线(BGR转灰阶→Blur→Canny边缘检测→HoughLinesP检测直线端点)。
  • 根据地标线端点计算斜率slope,以便知道摄像机朝向。
  • 计算追踪数据中,所有球员位置x的平均值x_center,以便知道球员聚集的中心位置。
  • 若(x_center-60)*slope<0,说明机位为Home Sideline,否则为Endzone Sideline。

图5:基于地标线斜率和球员中心点的Sideline机位预测

针对头盔检测数≤22个,则用球员在xy轴上的偏度skew,具体步骤如下,流程可见图6:

  • 计算视频画面内,球员在x和y轴的偏度(sk_x_he和sk_y_he)。
  • 计算追踪数据内,球员在x和y轴的偏度(sk_x_tr和sk_y_he)。
  • 若sk_x_he和sk_x_tr同sign,且sk_y_he和sk_y_he同sign,说明机位为Home Sideline,否则为Endzone Sideline。

图6:基于xy轴偏度的Sideline机位预测

当时我用Muresan的方案,在线下测试,准确率100%,但用在线上发现分数掉的很厉害,后来在评论区问了他,他的回复我说:“If the video contains many helmets on the sides, outside the playing field, I expect trouble to show up.”,对此,我们团队后面有做场外球员/观众的剔除(具体方法放后面讲)。

(c) 基于球衣颜色:我们观察到,主队一般都是白色球衣,客队是深色球衣。然后想着基于球衣颜色直方图做机位预测,具体步骤如下,流程可见图7:

  • 对视频画面球员进行目标检测,获取球员bbox后,对绿色背景mask掉后,计算颜色直方图。
  • 基于各球员颜色直方图做Kmeans聚类,分为2类,获取各自的中心点直方图。
  • 计算各队中心点直方图与纯白色直方图的cosine距离,距离的中心点认为是主队。
  • 对比追踪数据球队的位置,判断Sideline机位。

图7:基于球衣颜色的Sideline机位预测

这个方法预测出来结果很糟糕,因为直方图提取的颜色特征不具备明显的区分度,导致预测不确定性很大。

(2) Endzone机位预测

Endzone机位预测时基于OCR识别出的球衣号,在追踪数据中哪一侧,由此判断摄像机位置。如图8所示。比如我对首帧画面检测到26号和2号(一般来说,背对摄像机的球员被检测出号码的可能性更大),然后在追踪数据里找26号和2号的位置,发现他们更靠近Visitor Endzone,因此判断视频是在客场Endzone下拍摄的。但有时候首帧画面OCR是检测不出号码的(不知道为什么,肉眼是很清晰的,可能是OCR需要fine tune吧),这时候我们允许它一直搜索到80帧(太后面的帧里球员会抱在一团,机位预测风险很大,不具有位置参考性),准确率能达到54/60,效果远没有Sideline的好,机位预测难度较大。

图8:基于OCR检测的球衣号码的Endzone机位预测

注意,机位预测的好处在于减少后面匹配的搜索空间,坏处在于,一旦预测错误,对匹配的影响也是致命的。

2. 距离匹配

(1)边框裁剪

前面也提到,会出现如下图所示的球员冗余问题,多数是由于场外替补球员和观众被误检导致的。为了解决这个问题,我们采用了边框裁剪冗余球员的方法,主要是对画面边缘的bbox不断剔除,直到场内球员数是在一个合理范围内。这样增大了我们后面匹配的正确性搜索范围。 边缘最多允许裁剪4轮,每轮裁剪宽度为40pixel。

图9:裁剪画面边缘冗余bbox

(2)球员抽样

即使是剔除了边框冗余球员,场内也会因为检测到裁判、头盔误检和摄像机视角缩放,导致视频画面的球员头盔数与追踪数据的球员数对不齐。对于这种情况,我们会有以下处理方法:

(a) 视频球员数>追踪球员数:做边框裁剪完,基于头盔检测置信度,优先剔除低置信度头盔的球员。

(a) 视频球员数<追踪球员数:若视频中球员数有20个,而追踪球员有22个,那么从22个追踪球员中遍历出不同球员的组合(每个组合只有2个球员),然后从追踪球员中删除不同组合内的2个球员,计算视频和NGS的球员的匹配距离,取匹配距离最小的采样组合,然后将其从22个追踪球员中删除。但问题在于视频缺失球员越多,需要遍历搜索的组合空间就越大,为此,设置了搜索组合的次数上限为2000次。

(3) 画面旋转

由于不同机位姿态导致视频画面属于鸟瞰图,而非俯视图,这样导致与NGS标准图的球员位置存在扭曲。为此,我们对视频头盔点经过旋转矩阵变换后,再与NGS图做球员匹配。图10展示了球员旋转的流程,我们设置的最小旋转角为-30,最大旋转角为30,然后间隔3个角度,抽取一个旋转角度旋转球员位置,最后选择能使后续球员匹配总体距离最小的旋转角度。

图10:利用旋转矩阵旋转球员

(4) xy Mapping

我们分别针对球员在x轴和y轴的位置分别做球员ID匹配,然后选择整体匹配距离最小的匹配结果,如下图所示:

图11:xy Mapping

3. 球员追踪

前面的工作在于匹配上球员ID,现在我们使用DeepSORT[5]对球员进行跨帧的追踪,DeepSORT是2017年提出的一种多目标跟踪算法,相比于SORT,它提取了目标的外观特征放入最近邻匹配中,能有效提高目标追踪的效果,也减少ID Switch问题的发生。由于追踪目标时需要度量目标距离,Deepsort便提供了两种距离度量方式[6]:

  • 马氏距离:适用于运动不确定性很低的场景,在图像空间中使用kalman滤波进行运动状态估计只是一个比较粗糙的预测。特别是相机存在运动时会使得马氏距离的关联方法失效,造成出现ID switch的现象。作者lambda=0即不使用马氏距离作为最终的度量方式。
  • 余弦距离:作者对每一个追踪目标构建一个gallary,存储每一个追踪目标成功关联的最近100帧的特征向量。那么第二种度量方式就是计算第i个追踪器的最近100个成功关联的特征集与当前帧第j个检测结果的特征向量间的最小余弦距离。

距离度量(M distance)对短期的预测和匹配效果很好,但对于长时间的遮挡的情况,使用外观特征的度量(cosine distance)比较有效。对于存在相机运动的情况,作者建议置λ=0。当一个目标长时间被遮挡之后,kalman滤波(想要深入了解的朋友建议阅读:卡尔曼滤波)预测的不确定性就会大大增加,状态空间内的可观察性就会大大降低。假如此时两个追踪器竞争同一个检测结果的匹配权,往往遮挡时间较长的那条轨迹因为长时间未更新位置信息,追踪预测位置的不确定性更大,即协方差会更大,马氏距离计算时使用了协方差的倒数,因此马氏距离会更小,因此使得检测结果更可能和遮挡时间较长的那条轨迹相关联,这种不理想的效果往往会破坏追踪的持续性。总结来说,KF碰到目标长时间遮挡问题,会“放弃”追踪后面遮挡完出来的目标,因此作者设lambda为0,即不考虑马氏距离的度量。

回到我们的赛题,我们会发现,如果只是追踪头盔bbox的外观内容,是非常不友好的,因为头盔遮挡住面部特征,而且同一支球队的头盔外观是一样的,那DeepSORT基于外观特征的相似度做度量,是存在很大风险的。本来我们是想去修改源代码中lambda参数的设置(增加lambda),但发现作者开源代码中并没有把lambda给实现出来,而是直接忽略了它。为此,我们除了基于头盔度量,还对球员bbox(通过头盔bbox外扩得到)做DeepSORT追踪,因为相比于头盔bbox,球员bbox更适配Deepsort的预训练好的行人特征抽取器,同时球员的体态特征或球衣号特征可能也会被捕捉到。但我们对比实验后,发现,有些部分视频下,头盔DeepSORT结果更好,部分视频是球员DeepSORT结果更好,但所有视频的总体评分是头盔DeepSORT更高一些。猜测原因是:相比于球员,头盔被遮挡的可能性更小,增大目标暴露的可能,所以某些时候比球员DeepSORT好。

为了平衡头盔DeepSORT和球员DeepSORT的结果,我们做了融合,当某球员的label分组计数*0.6还大于头盔的label分组计数,我们认为信赖该球员的球员追踪结果,而不是头盔追踪结果。对了,我们对Sideline和EndZone还分别调了对应的两套参数。

三、其它尝试与想法

前面其实已经输出了很多额外尝试的内容,这里补充下。

1. 头盔检测器

我们中途尝试过使用YoloV5训练头盔检测器,而不是用官方提供的baseline头盔模型检测结果,但在线上提交代码运行报错,后面发现存在视频画面里头盔过于小,而检测不出来,导致无头盔bbox匹配而报错。后面对比高分方案,发现是自己训练时图片尺寸设为736,导致模型对小目标检测难度很大(我的锅),所以就没获取到这部分的收益。

2. 距离匹配

在球员采样部分,我们尝试局限采样范围为中心球员周边范围内,但发现效果不好,原因可能是:场内中间球员存在多检测的头盔bbox,如果保留它们去做匹配,会破坏匹配的连续性。在xy Mapping上,我们尝试过基于头盔(x,y)的几何距离匹配,但速度会受影响,就没用上。还有我们还试过Passos的点云法[7],使用梯度下降去收敛转换矩阵H,其实线下拿单个测试,效果是比上面提到用旋转矩阵的方法好,可惜即使后面我们优化成batch操作,遍历各帧做梯度下降还是速度太慢。后面看了前排的思路,也叫ICP(Iterative Closest Points, 迭代最近点)算法,他们采用了一些方法解决的速度上的问题(后面会讲)。

3. 球员追踪

追踪模型选择DeepSORT是因为主持人开源了它的baseline,上手很容易。后面也有选手开源了ByteTrack,但效果没有提升。我们也试了FairMOT,但是因为线上运行代码不允许联网,导致所有依赖得本地装好,打包成数据集上传调用才行,辛苦刘兄在FairMOT上搞依赖搞了半天,特别是线上如何编译DCNv2上,花了好多心力,但由于FariMOT是将检测和跟踪进行了端对端的训练,我们这边便来不及上线调整代码架构,便没用上。

四、前排高分思路

压轴的终于来了,我跟队友花了3小时复盘了前排高分思路,收获很大。接下来,你能欣赏到K神的杰作,他的方案完整性高,发paper应该问题不大。还有老牌选手猫哥的方案,相比于K神的巧夺天工的学术气息,猫哥的方案工程气息更重,有做拿简单的操作收获最大利益,读来有点大道至简的感觉。希望对大家有所启发。

1. 第1名[8](@K_mat)

K_mat的pipeline(Detector → Converter → Classifier → Registration → Tracker)如下:

  • 训练头盔Detector;
  • 使用Converter将视频图像映射到2D图上(鸟瞰视角);
  • 训练Classifier去分类球员2团队(主客队H/V);
  • 对在2D地图上被检测的球员,注册(Registration)到提供的跟踪数据上;
  • 跟踪检测bbox和球员重分配。

K_mat认为他与其它选手拉开距离的地方在于mapping和registration模块。

图12:第一名方案pipeline

(1) 头盔Detector

采用了2阶检测器寻找头盔:

第1阶检测器:用EfficientNetV2s检测头盔,计算被检测出的头盔的平均尺寸,然后基于头盔平均尺寸,缩放图片让头盔尺寸在25*25附近。

第2阶检测器:在第1阶检测器输出的高分辨率图片上再检测头盔(作者认为检测相同尺寸的头盔比检测不同尺寸的头盔更容易)。

图13:K_mat的二阶Detector思路

读后感:这个思路很赞,就像前面提到,我们也做过Yolov5头盔检测器,想要替换官方的头盔检测结果,但后面发现存在个别视频的机位拉的太远,导致头盔变成极小目标,增大头盔漏检风险,最后提交分数很不理想。而该思路结合业务特性设计了基于检测头盔bbox去调整图片尺寸的操作,进而减少第2个检测器的检测难度,从而解决了这个问题(这不比费劲心思为小目标调anchor box size、搞多尺度训练和预测等香吗?)

(2) Image2Map Converter
  • 使用CNN(基于U-Net)将图片中的头盔bbox转为2D map。它预测在相机位置下球员的2D位置(x和y),可以理解为NGS Map上的位置。
  • 它从bottleneck输出全局位置,从decoder输出小的残差。
  • 头盔检测框的attention提高了准确性。

图14:Image2Map Converter

读后感:GT是NGS坐标。Pred是视频坐标,设计损失函数去使GT和pred点匹配距离最小。关于delta x/y和global x/y,作者绘图解释如下所示,简单来说global坐标是球员在NGS的坐标,delta x/y是球员头盔bbox中心点和垫肩传感器采集位置的相对距离偏差。

图15:球员绝对位置和相对位置

(3) 点对点Registration

将2D Map上预测的球员匹配到提供的跟踪数据上(Tracking Data):

  • 以ICP(Iterative Closest Points, 迭代最近点)算法为基础,通过最小二乘迭代拟合,求解最近邻搜索和正规方程,得到4个未知参数的解(xy平移距离、旋转角度和缩放比例)。
  • 使用预/后处理删除不合适的Sideline球员。

图16:Points2Points Registration

读后感:注意这里的随机初始化很重要,因为不同初始化话去做ICP效果更好,而之前我们没做图像变化后去直接做ICP,导致匹配过于局限,影响分数。而且每次初始化,如果跑几轮发现ICP错误很大,就立刻止损,减少了不必要搜素的可能性。

图17:Points2Points Registration的后处理

读后感:之前我们尝试开源的点云代码时,面临的问题就是参数搜索的时间成本太大,但由于点云效果很不错,想着说每帧参数搜索前,先拿历史帧的搜索结果做初始化,这样迭代收敛速度会不断加快,虽然最后嫌麻烦没实现,但看到K_mat的方案里类似的做法,还是比较开心自己有这样的想法的。

(4) 队伍Classifier

队伍信息对提高Registration准确性很重要。XY位置和队伍可以在点对点Registraion中结合。CNN分类器预测出相似矩阵去表示每一对球员是否为同队。使用arcface和伪标签可以提高准确性,验证集分数大约在97%左右。

图18:队伍Classifier

读后感:对比我基于球员mask的颜色直方图特征做相似队伍聚类,明显K_mat的队伍分类器是高配版了,Arcface将类间距拉大,增加分类准确性。

(5) Tracker

追踪器记录了所有帧下的球员分配结果,然后再分配到bbox上。作者使用了简单的IoU追踪器,因为它快且足够准确。再分配时,不止参考标签出现次数,还有追踪置信度和帧间距离。分配结果如果远离目标帧,将不被给予权重。

图19:Tracking和结果融合

读后感:这是将WBF应用在追踪结果的融合上。

(6) Ensemble

WBF(Weighted Box Fusion)被用在追踪器再分配阶段中,它集成了多帧多模型的预测结果。将每个模型的球员分配矩阵进行加权平均,然后通过匈牙利算法选择最终分配结果,比常规使用WBF集成bbox和检测置信度更有用。再最终提交中,集成了4个检测器的结果。

图20:WBF集成策略

我们来看下,K_mat实验记录:

图21:第一名的消融实验记录

K_mat最后除了无私地开源了代码[9],同时,他分享了他的成功拿下第一的原因:

Fortunately, I have the experience of the object detection, depth estimation, pointcloud registration and tracking. I think this is the reason why I could win this competition.
I started learning programming and machine learning at kaggle 3 years ago, and most of my knowledge comes from kaggle. Thanks again to the whole of kaggle community!

我看了K_mat的kaggle profile,3年前他的战绩还是1k名左右徘徊,修炼了3年重归kaggle,solo凭49次提交一举拿下第一,令人叹服。

2. 第2名[10](@tito)

(1) 头盔检测器:使用YoloV5训练头盔检测器,由于小头盔检测效果不好,将图片从1280上采样到1664训练。

(2) 头盔聚类(队伍分类):使用2阶K-means做头盔聚类。第1个Kmeans从整个视频帧下,所有头盔图片的每个像素集中提取出20个代表性颜色(相当于对所有颜色做聚类20个类)。第2个Kmeans,利用头盔颜色特征向量进行聚类。

(3) 特征抽取(用于距离匹配):除了2D信息(上/下,左/右,主队/客队,球员朝向),头盔和传感器位置的偏差也被用作球员距离匹配当中。

  • 球员朝向:tito构建一个模型预测tracking数据中的球员朝向,然后如果在匹配时,用于惩罚朝向角度差距过大的匹配结果。

图22:球员朝向预测 红色和橙色:对应主队和客队的预测值 浅蓝色和深蓝色:对应主队和客队的真实值

  • 头盔与传感器位置偏差:举例,即使是相同坐标,但因为球员站着或蹲着,都会导致头盔位置改变。为此tito构建模型去预测头盔的偏移,他先提前将真实位置和头盔bbox匹配在一起去获取位置偏差,然后训练模型预测距离偏差。

(4) 坐标转换:选手使用OpenCV检测地标线,然后将视频图片和tracking数据的地标线对齐,实现球员坐标系统一。

图23:基于地标线的坐标转换

(5) 球员分配:由于视频中球员数常小于22个,我裁剪掉上下左右的边缘球员(读后感:跟我们一样的做法),在去除冗余球员时,我会选择保留跟其他球员近的球员。

(6) 球员追踪:现在的目标追踪模型是基于图片特征做距离相似度量,然而tito认为此方法也许不适用此比赛,因为同一个队的所有头盔都是同一种头盔,所以tito用了基于SORT的模型(基于KF,而没基于外观特征),然后他也将头盔图片特征作为step-function,用于避免跨球队追踪球员,这里用的图片特征是之前Kmeans队伍聚类时的特征。

读后感:果然猫哥(tito头像是只猫)是老牌选手了,他的方案让人体现了大道至简这四个字。头盔聚类那边的颜色特征提取比我们好,很好的利用了球员朝向数据,同样在头盔与传感器的位置偏差的细节也处理的很好,基于地标线的坐标轴转换很妙,弃DeepSORT改用低配版SORT也非常明智,再一次说明了:最好的不一定是最适合的。

3. 第3名[11](@fantastic_hirarin)

第3名方案流程如下:

  • (阶段1)使用Yolov5检测头盔。
  • (阶段2)使用deepsort追踪头盔。
  • (阶段3)使用ICP(迭代最近点)和匈牙利算法将头盔bbox分配给每一帧的跟踪数据。
  • (阶段4)基于头盔的颜色,使用kmeans将头盔分为两个类。
  • (阶段5)考虑deepsort和头盔颜色信息的结果,使用ICP(迭代最近点)和匈牙利算法分配头盔bbox再次跟踪数据。
  • (阶段6)使用匈牙利算法来确定最终的标签。

(1)阶段1: 头盔检测器:基于1280尺寸的图片,训练yolov516和yolov5x,由于担心检测到边缘球员,sideline的头盔不会被用于训练。此外推理时,采用水平翻转做TTA。由于头盔会出现部分可见,为此降低了IOU的置信度阈值。

(2)阶段2:头盔deepsort:基于头盔,用deeposrt追踪器。为了减少假阳样本,删去了连续多帧无法被追踪到的头盔。另外,修改了deepsort代码,让它返回了ReID的抽取特征和置信度。特征会被用在阶段4,置信度会用在阶段3和5。

(3)阶段3:使用ICP和匈牙利算法分配头盔归属:基于检测头盔位置和tracking的球员位置,做ICP尽可能对齐拉近两者位置。然后使用匈牙利算法匹配。同样地,选手也面临假阳样本问题,解决手段是依次删除某个<0.5置信度的样本做ICP(选择匹配距离最小的可能组合),同时也会删除视频画面中边缘多余的检测目标。由于ICP对初始化值有强以来,选手会将上下左右翻转产生多种模式后再进行ICP和匈牙利算法的分配。

图24:使用ICP和匈牙利算法分配头盔归属(阶段3)

(4)阶段4:基于头盔颜色,使用Kmeans聚类:使用了阶段2中deepsort里提取的特征做的聚类。

(5)阶段5:基于头盔bbox和颜色,再做ICP和匈牙利算法匹配:这增加了相同颜色的头盔配分配到相同队伍上的概率。

(6)阶段6:使用匈牙利算法决定最终标签:这里的损失度量标准是在同一个deepsort头盔的标签百分比。显然标签百分比出现最高的,更优先分配。这里没用ICP,是因为此时ICP没法解决头盔检测位置和传感器位置的偏差。

4. 第4名[12](@Ahmet Erdem)

选手先基于额外图片数据(size=640)训练yolov5头盔检测器,再剔除场外球员H00和V00的视频帧图片(size=1280)fine tune检测器,检测置信权重设为0.03和IOU阈值为0.2。效果好于baseline头盔数据。在Deepsort部分,修改了merge_asof逻辑成贪婪最小距离分配法。加总同一个cluster下的头盔检测置信度作为头盔跟踪置信度,用于选择2D匹配中top22的头盔。Erdem的亮点在于使用resnet34训练球衣号,球衣框是基于头盔bbox外扩得到的,由于模型很小,容易过拟合。选手做了数据增强(cutmix, paste random digit, convert black and white , invert colors),最后球衣号检测器recall小,但precision高,这被加入到2D mapping中,用于重改错误匹配。另外,还针对每个头盔的置信度,由高到低做追踪分配。

对于为什么不用官方提供的baseline头盔预测bbox,原因是他们发现:错误的bbox比缺少bbox 的破坏性更大(因为错误的bbox会破坏整个映射)。所以队员@rytisva88做了两件事:

(1)假设前面一帧的bbox是正确的,那么如果后一帧出现新的bbox,那么你会循环遍历每个新的bbox,然后检查这个新bbox是否修复了前一帧正确bboxes的匹配,如果没有,我们会删掉这个bbox。

(2)检查是否一个bbox从一帧到另外一帧会有消失的情况。做法很类似,就是把你认为是新的bbox,加回来,与未分配的tracking point计算距离,如果距离近,说明这个新的点是“确有其人”。

5. 其它高分选手

第5名@Kyle Lee[13]训练了yolov5头盔检测器。在标签分配上,基于加权最小xy距离,使用匈牙利算法。同时,对头50帧做机位投票。deepsort参数偏向于低max age,高iou。其它的基本没看懂(可能是我太菜了)。 第9名[14]的K-NKSM[]用shape context初始化帧homography matrix还蛮新奇的(虽然没太看懂),第10名nvnn[15]建了一个类似分割网络的回归网络,专门用于匹配视频头盔和tracking数据的球员,非常神奇。第11名[16]的D.Imanishi使用了上一次NFL比赛的光流预测下一帧的bbox,目的是增加头盔数,从而减少bbox的false negatives。

五、参赛心得

首先,一如既往的感谢队友邵兄和刘兄,从谷歌定位赛再到合作NFL球员分配赛,都很愉快。这次比赛也学到很多,从上面的内容也能看出,这是我今年目前为止打的最有意思,花的最多精力的一次笔试了。前几天我跟队友复盘完,想说如果重来,我们会补充哪些工作,那便是:头盔检测+ICP+匈牙利算法。希望这篇文章能给一些朋友带来乐趣和帮助。

这次也打怪升级成Kaggle Competitions Expert了,希望明年有机会更进一步,摘个银牌。加油!

参考资料

[1] NFL Health & Safety - Helmet Assignment - Kaggle, 赛题官网: https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/overview

[2] NFL 如何通过机器学习和分析技术实现转型 - AWS, 文章: https://aws.amazon.com/cn/machine-learning/customers/innovators/nfl/

[3] NFL Baseline - Simple Helmet Mapping - tito, Code: https://www.kaggle.com/its7171/nfl-baseline-simple-helmet-mapping/notebook

[4] NFL assign label camera orientation - Adrian Muresan https://www.kaggle.com/louisbunuel/nfl-assign-label-camera-orientation/notebook

[5] Wojke, N., Bewley, A., & Paulus, D. (2017, September). Simple online and realtime tracking with a deep association metric. In 2017 IEEE international conference on image processing (ICIP) (pp. 3645-3649). IEEE.

[6] DeepSort论文学习 - cdknight_happy, 文章: https://blog.csdn.net/cdknight_happy/article/details/79731981

[7] Camera-Tracking Matching with Gradient Descent - Adriano Passos, 代码:https://www.kaggle.com/coldfir3/camera-tracking-matching-with-gradient-descent

[8] 1st Place Solution - K_mat, 讨论: ****https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/284975

[9] nfl-1stplace-inference - K_mat, 讨论: **** https://www.kaggle.com/kmat2019/nfl-1stplace-inference

[10] 2nd place solution - tito, 讨论: ****https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/285112

[11] [3rd place solution] YOLOv5 + DeepSort + ICP + Hungarian algorithm - fantastic_hirarin, 讨论: **** https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/285076

[12] 4th Place Solution - Ahmet Erdem, 讨论: **** https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/285007

[13] 5th Place Solution - Kyle Lee, 讨论: **** https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/285286

[14] 9th place solution - K-NKSM, 讨论: **** https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/284940

[15] 10th place solution - nvnn, 讨论: **** https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/284945

[16] 11th place solution - D.Imanishi, 讨论: [https://www.kaggle.com/c/nfl-health-and-safety-helmet-assignment/discussion/285156](

  • 0
  • 0
  • 194
收藏
暂无评论