使用Sportsvu数据创建NBA动作视频

本文介绍如何利用SportVU系统提供的JSON数据,结合Python和WebGL技术,重建NBA比赛中的具体场景。数据可以从neilmj的GitHub上获取。作者展示了创建篮球比赛视频的过程,并提供了Jupyter Notebook实现。
摘要由CSDN通过智能技术生成

All basketball teams have a camera system called SportVU installed in their arenas. These camera systems track players and the ball throughout a basketball game.

所有篮球队在赛场上安装了名为SportVU的摄像头系统。 这些摄像机系统在整个篮球比赛中跟踪球员和球。

The data produced by sportsvu camera systems used to be freely available on NBA.com, but was recently removed (I have no idea why). Luckily, the data for about 600 games are available on neilmj’s github. In this post, I show how to create a video recreation of a given basketball play using the sportsvu data.

sportsvu摄像机系统产生的数据曾经可以在NBA.com上免费获得,但是最近被删除了(我不知道为什么)。 幸运的是,可以在neilmj的github找到大约600场比赛的数据。 在本文中,我将展示如何使用sportsvu数据为给定的篮球比赛创建视频娱乐。

This code is also available as a jupyter notebook on my github.

此代码也可以在我的github上作为jupyter笔记本使用。

1
1
2
2
3
3
4
4
5
5

The data is provided as a json. Here’s how to import the python json library and load the data. I’m a T-Wolves fan, so the game I chose is a wolves game.

数据作为json提供。 这是导入python json库和加载数据的方法。 我是T-狼队的球迷,所以我选择的游戏是狼队游戏。

1
1
2
2
3
3

Let’s take a quick look at the data. It’s a dictionary with three keys: gamedate, gameid, and events. Gamedate and gameid are the date of this game and its specific id number, respectively. Events is the structure with data we’re interested in.

让我们快速看一下数据。 这是一本具有三个键的字典:gamedate,gameid和events。 Gamedate和gameid分别是该游戏的日期及其特定的ID号。 事件是我们感兴趣的数据结构。

1
1
[u'gamedate', u'gameid', u'events']
[u'gamedate', u'gameid', u'events']
 

Lets take a look at the first event. The first event has an associated eventid number. We will use these later. There’s also data for each player on the visiting and home team. We will use these later too. Finally, and most importantly, there’s the “moments.” There are 25 moments for each second of the “event” (the data is sampled at 25hz).

让我们看一下第一个事件。 第一个事件具有关联的事件ID号。 我们稍后将使用它们。 还有来访和主队中每个球员的数据。 我们也将在以后使用它们。 最后,最重要的是,存在“时刻”。 “事件”的每一秒有25个瞬间(数据以25hz采样)。

data['events'][0].keys()
data [ 'events' ][ 0 ] . keys ()
 

Here’s the first moment of the first event. The first number is the quarter. The second number is the time of the event in milliseconds. The third number is the number of seconds left in the quarter (the 1st quarter hasn’t started yet, so 12 * 60 = 720). The fourth number is the number of seconds left on the shot clock. I am not sure what fourth number (None) represents.

这是第一场比赛的第一刻。 第一个数字是四分之一。 第二个数字是事件的时间(以毫秒为单位)。 第三个数字是该季度剩余的秒数(第一个季度尚未开始,因此12 * 60 = 720)。 第四个数字是射击时钟上剩余的秒数。 我不确定第四个数字(无)代表什么。

The final matrix is 11×5 matrix. The first row describes the ball. The first two columns are the teamID and the playerID of the ball (-1 for both because the ball does not belong to a team and is not a player). The 3rd and 4th columns are xy coordinates of the ball. The final column is the height of the ball (z coordinate).

最终矩阵是11×5矩阵。 第一行描述了球。 前两列是球的teamID和玩家ID(对于两个都为-1,因为球不属于团队且不是玩家)。 第三和第四列是球的xy坐标。 最后一列是球的高度(z坐标)。

The next 10 rows describe the 10 players on the court. The first 5 players belong to the home team and the last 5 players belong to the visiting team. Each player has his teamID, playerID, xy&z coordinates (although I don’t think players’ z coordinates ever change).

接下来的10行描述了球场上的10位玩家。 前5名球员属于主队,后5名球员属于客队。 每个玩家都有自己的teamID,playerID,xy&z坐标(尽管我认为玩家的z坐标不会改变)。

1
1
[1,
 1452903036782,
 720.0,
 24.0,
 None,
 [[-1, -1, 44.16456, 26.34142, 5.74423],
  [1610612760, 201142, 45.46259, 32.01456, 0.0],
  [1610612760, 201566, 10.39347, 24.77219, 0.0],
  [1610612760, 201586, 25.86087, 25.55881, 0.0],
  [1610612760, 203460, 47.28525, 17.76225, 0.0],
  [1610612760, 203500, 43.68634, 26.63098, 0.0],
  [1610612750, 708, 55.6401, 25.55583, 0.0],
  [1610612750, 2419, 47.95942, 31.66328, 0.0],
  [1610612750, 201937, 67.28725, 25.10267, 0.0],
  [1610612750, 203952, 47.28525, 17.76225, 0.0],
  [1610612750, 1626157, 49.46814, 24.24193, 0.0]]]
[1,
 1452903036782,
 720.0,
 24.0,
 None,
 [[-1, -1, 44.16456, 26.34142, 5.74423],
  [1610612760, 201142, 45.46259, 32.01456, 0.0],
  [1610612760, 201566, 10.39347, 24.77219, 0.0],
  [1610612760, 201586, 25.86087, 25.55881, 0.0],
  [1610612760, 203460, 47.28525, 17.76225, 0.0],
  [1610612760, 203500, 43.68634, 26.63098, 0.0],
  [1610612750, 708, 55.6401, 25.55583, 0.0],
  [1610612750, 2419, 47.95942, 31.66328, 0.0],
  [1610612750, 201937, 67.28725, 25.10267, 0.0],
  [1610612750, 203952, 47.28525, 17.76225, 0.0],
  [1610612750, 1626157, 49.46814, 24.24193, 0.0]]]
 

Alright, so we have the sportsvu data, but its not clear what each event is. Luckily, the NBA also provides play by play (pbp) data. I write a function for acquiring play by play game data. This function collects (and trims) the play by play data for a given sportsvu data set.

好了,所以我们有了sportsvu数据,但不清楚每个事件是什么。 幸运的是,NBA还提供逐场比赛(pbp)数据。 我编写了一个通过玩游戏数据获取玩游戏的功能。 此功能针对给定的sportsvu数据集按播放数据收集(和修剪)该播放。

def acquire_gameData(data):
    import requests
    header_data = {
             #I pulled this header from the py goldsberry library
        'Accept-Encoding': 'gzip, deflate, sdch',
        'Accept-Language': 'en-US,en;q=0.8',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'
        ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 '
        'Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9'
        ',image/webp,*/*;q=0.8',
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值