{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# ⚽DFL - Bundesliga Data Shootout⚽ - Exploratory Data Analysis\n\nIdentify plays based upon video footage\n\nQuick Exploratory Data Analysis for [DFL - Bundesliga Data Shootout](https://www.kaggle.com/competitions/dfl-bundesliga-data-shootout) challenge    \n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/37244/logos/header.png?t=2022-06-30-22-25-12)\n","metadata":{}},{"cell_type":"markdown","source":"<a id=\"top\"></a>\n\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h3 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='color:white; background:green; border:0' role=\"tab\" aria-controls=\"home\"><center>Quick Navigation</center></h3>\n\n* [Overview](#1)\n* [EVENT: throwin](#2)\n* [EVENT: play](#3)\n* [EVENT: challenge](#4)\n* [Process Video](#5)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n<h2 style='background:green; border:0; color:white'><center>Overview<center><h2>","metadata":{}},{"cell_type":"code","source":"!pip install moviepy -q","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:07.996996Z","iopub.execute_input":"2022-08-04T15:46:07.997574Z","iopub.status.idle":"2022-08-04T15:46:40.383805Z","shell.execute_reply.started":"2022-08-04T15:46:07.997453Z","shell.execute_reply":"2022-08-04T15:46:40.382360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sn\nfrom moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip\nfrom IPython.display import Video","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:40.387434Z","iopub.execute_input":"2022-08-04T15:46:40.388837Z","iopub.status.idle":"2022-08-04T15:46:41.513945Z","shell.execute_reply.started":"2022-08-04T15:46:40.388782Z","shell.execute_reply":"2022-08-04T15:46:41.512191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Train folder containing videos to be used as training data, comprising video recordings from eight games. Both halves are included for four of the games, while only one half is included for the other four games.","metadata":{}},{"cell_type":"code","source":"print(os.listdir(\"../input/dfl-bundesliga-data-shootout/train/\"))","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.516764Z","iopub.execute_input":"2022-08-04T15:46:41.517342Z","iopub.status.idle":"2022-08-04T15:46:41.530156Z","shell.execute_reply.started":"2022-08-04T15:46:41.517288Z","shell.execute_reply":"2022-08-04T15:46:41.528873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Test folder containing videos to be used as test data. The test data for the public leaderboard comprises video recordings from one full game and four half-games, the other half of each game being in the training set.   \n\nNote that this is a Code Competition, which means you will submit a notebook that makes predictions against a hidden test set. The test set visible here is only an example to help you author submission code. When you submit your notebook for scoring, this example data will be replaced by the actual test data.","metadata":{}},{"cell_type":"code","source":"print(os.listdir(\"../input/dfl-bundesliga-data-shootout/test/\"))","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.532737Z","iopub.execute_input":"2022-08-04T15:46:41.533445Z","iopub.status.idle":"2022-08-04T15:46:41.546649Z","shell.execute_reply.started":"2022-08-04T15:46:41.533404Z","shell.execute_reply":"2022-08-04T15:46:41.545476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Short clips from ten additional games, provided without event annotations. You may wish to use these clips to help your model generalize to environments not represented in the training data.","metadata":{}},{"cell_type":"code","source":"print(os.listdir(\"../input/dfl-bundesliga-data-shootout/clips/\"))","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.548307Z","iopub.execute_input":"2022-08-04T15:46:41.549795Z","iopub.status.idle":"2022-08-04T15:46:41.621001Z","shell.execute_reply.started":"2022-08-04T15:46:41.549747Z","shell.execute_reply":"2022-08-04T15:46:41.620136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"../input/dfl-bundesliga-data-shootout/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.622339Z","iopub.execute_input":"2022-08-04T15:46:41.622841Z","iopub.status.idle":"2022-08-04T15:46:41.659122Z","shell.execute_reply.started":"2022-08-04T15:46:41.622811Z","shell.execute_reply":"2022-08-04T15:46:41.658130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.660430Z","iopub.execute_input":"2022-08-04T15:46:41.660957Z","iopub.status.idle":"2022-08-04T15:46:41.695403Z","shell.execute_reply.started":"2022-08-04T15:46:41.660923Z","shell.execute_reply":"2022-08-04T15:46:41.693914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 5))\nsn.countplot(data=df, y=\"event\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.696865Z","iopub.execute_input":"2022-08-04T15:46:41.697275Z","iopub.status.idle":"2022-08-04T15:46:41.967591Z","shell.execute_reply.started":"2022-08-04T15:46:41.697242Z","shell.execute_reply":"2022-08-04T15:46:41.966033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 5))\nsn.countplot(data=df, y=\"video_id\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:41.969428Z","iopub.execute_input":"2022-08-04T15:46:41.970048Z","iopub.status.idle":"2022-08-04T15:46:42.250316Z","shell.execute_reply.started":"2022-08-04T15:46:41.970013Z","shell.execute_reply":"2022-08-04T15:46:42.248987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 5))\nsn.countplot(data=df[(df[\"event\"] != \"start\") & (df[\"event\"] != \"end\")], y=\"video_id\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:42.255643Z","iopub.execute_input":"2022-08-04T15:46:42.256043Z","iopub.status.idle":"2022-08-04T15:46:42.528120Z","shell.execute_reply.started":"2022-08-04T15:46:42.256010Z","shell.execute_reply":"2022-08-04T15:46:42.526979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2\"></a>\n<h2 style='background:green; border:0; color:white'><center>EVENT: throwin<center><h2>","metadata":{"execution":{"iopub.status.busy":"2022-07-29T22:57:53.824078Z","iopub.execute_input":"2022-07-29T22:57:53.824481Z","iopub.status.idle":"2022-07-29T22:57:53.832435Z","shell.execute_reply.started":"2022-07-29T22:57:53.824449Z","shell.execute_reply":"2022-07-29T22:57:53.831317Z"}}},{"cell_type":"markdown","source":"A Throw-In refers to a situation where the game is restarted after the ball went out of play over the sideline following the touch of the opposite team. The ball must be thrown with hands, from behind and over the head of executing player.","metadata":{}},{"cell_type":"code","source":"df_throwin = df[df[\"event\"] == \"throwin\"].reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:42.529609Z","iopub.execute_input":"2022-08-04T15:46:42.529919Z","iopub.status.idle":"2022-08-04T15:46:42.538942Z","shell.execute_reply.started":"2022-08-04T15:46:42.529891Z","shell.execute_reply":"2022-08-04T15:46:42.537562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 3))\nsn.countplot(data=df_throwin, y=\"event_attributes\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:42.540634Z","iopub.execute_input":"2022-08-04T15:46:42.541074Z","iopub.status.idle":"2022-08-04T15:46:42.744008Z","shell.execute_reply.started":"2022-08-04T15:46:42.541019Z","shell.execute_reply":"2022-08-04T15:46:42.742774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 6))\nsn.countplot(data=df_throwin, x=\"video_id\", hue=\"event_attributes\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:42.746246Z","iopub.execute_input":"2022-08-04T15:46:42.747164Z","iopub.status.idle":"2022-08-04T15:46:43.098216Z","shell.execute_reply.started":"2022-08-04T15:46:42.747117Z","shell.execute_reply":"2022-08-04T15:46:43.095251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def vis_event(row, before=5, after=5):\n    print(row[\"event_attributes\"])\n    filename = f\"test_{row['index']}.mp4\"\n    ffmpeg_extract_subclip(\n        f\"../input/dfl-bundesliga-data-shootout/train/{row['video_id']}.mp4\", \n        int(row['time']) - before, \n        int(row['time']) + after, \n        targetname=filename,\n    )\n    \n    return Video(filename, width=800)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.100176Z","iopub.execute_input":"2022-08-04T15:46:43.100944Z","iopub.status.idle":"2022-08-04T15:46:43.108930Z","shell.execute_reply.started":"2022-08-04T15:46:43.100894Z","shell.execute_reply":"2022-08-04T15:46:43.107725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### [\"pass\"]\n\nPass, defined to be any attempt to switch ball control to another team member that doesn’t satisfy cross definition.","metadata":{}},{"cell_type":"code","source":"vis_event(df_throwin.iloc[0])","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.110495Z","iopub.execute_input":"2022-08-04T15:46:43.110861Z","iopub.status.idle":"2022-08-04T15:46:43.355477Z","shell.execute_reply.started":"2022-08-04T15:46:43.110826Z","shell.execute_reply":"2022-08-04T15:46:43.354263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### [\"cross\"]\n\nWhether a play is a Cross depends upon the positions of the acting player and of the possible recipient. The player playing the cross must be located approx. inside one of the four crossing zones. The four zones are marked by the touchlines, the extended sides of the penalty area, the goal lines and the imaginary quarter-way lines, which would be drawn at a quarter of the length of the pitch parallel to the half-way line (see figure below). The possible cross recipient must be located approx. inside the penalty area. Furthermore, the distance of the ball played must be medium-length (from 10 to 30 meters) or long (more than 30 meters) and the height of the ball played must be high (played above knee height). In order to classify a ball played as a cross if the ball is blocked by an opposing player, it is not the actual height or distance travelled that is decisive, but the intended height or distance.\n\n![](https://i.imgur.com/dvHxE1s.png)","metadata":{}},{"cell_type":"code","source":"vis_event(df_throwin.iloc[2])","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.357315Z","iopub.execute_input":"2022-08-04T15:46:43.357700Z","iopub.status.idle":"2022-08-04T15:46:43.647434Z","shell.execute_reply.started":"2022-08-04T15:46:43.357665Z","shell.execute_reply":"2022-08-04T15:46:43.645657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n<h2 style='background:green; border:0; color:white'><center>EVENT: play<center><h2>","metadata":{}},{"cell_type":"markdown","source":"A Play describes a player’s attempt to switch ball control to another member of his team. A play event may be executed as a Pass or as a Cross.","metadata":{}},{"cell_type":"code","source":"df_play = df[df[\"event\"] == \"play\"].reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.649982Z","iopub.execute_input":"2022-08-04T15:46:43.651672Z","iopub.status.idle":"2022-08-04T15:46:43.661450Z","shell.execute_reply.started":"2022-08-04T15:46:43.651611Z","shell.execute_reply":"2022-08-04T15:46:43.660475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 3))\nsn.countplot(data=df_play, y=\"event_attributes\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.663621Z","iopub.execute_input":"2022-08-04T15:46:43.665313Z","iopub.status.idle":"2022-08-04T15:46:43.921637Z","shell.execute_reply.started":"2022-08-04T15:46:43.665261Z","shell.execute_reply":"2022-08-04T15:46:43.920011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 6))\nsn.countplot(data=df_play, x=\"video_id\", hue=\"event_attributes\")\nplt.ylim(0, 50);","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:43.923828Z","iopub.execute_input":"2022-08-04T15:46:43.924672Z","iopub.status.idle":"2022-08-04T15:46:44.442734Z","shell.execute_reply.started":"2022-08-04T15:46:43.924631Z","shell.execute_reply":"2022-08-04T15:46:44.441299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_play","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:44.444369Z","iopub.execute_input":"2022-08-04T15:46:44.444726Z","iopub.status.idle":"2022-08-04T15:46:44.464404Z","shell.execute_reply.started":"2022-08-04T15:46:44.444693Z","shell.execute_reply":"2022-08-04T15:46:44.462981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"pass\", \"openplay\"]\n\nAn Open Play refers to any Play that is executed in-play and not from a dead ball situation (like corner kick, free kick or any other set piece).","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[0], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:44.466097Z","iopub.execute_input":"2022-08-04T15:46:44.466501Z","iopub.status.idle":"2022-08-04T15:46:44.560754Z","shell.execute_reply.started":"2022-08-04T15:46:44.466469Z","shell.execute_reply":"2022-08-04T15:46:44.559142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"cross\", \"openplay\"]","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[15], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:44.562789Z","iopub.execute_input":"2022-08-04T15:46:44.563254Z","iopub.status.idle":"2022-08-04T15:46:44.682710Z","shell.execute_reply.started":"2022-08-04T15:46:44.563209Z","shell.execute_reply":"2022-08-04T15:46:44.681512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"pass\", \"freekick\"]\n\nA Free Kick refers to a situation where the Play is executed to restart the game after the referee had stopped it due to an infringement of the rules. The ball must be kicked and be stationary on the ground when it's kicked off.","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[27], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:44.684117Z","iopub.execute_input":"2022-08-04T15:46:44.684476Z","iopub.status.idle":"2022-08-04T15:46:44.854686Z","shell.execute_reply.started":"2022-08-04T15:46:44.684444Z","shell.execute_reply":"2022-08-04T15:46:44.853397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"cross\", \"freekick\"]","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[1105], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:44.856797Z","iopub.execute_input":"2022-08-04T15:46:44.857210Z","iopub.status.idle":"2022-08-04T15:46:45.044669Z","shell.execute_reply.started":"2022-08-04T15:46:44.857175Z","shell.execute_reply":"2022-08-04T15:46:45.042766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"pass\", \"corner\"]\n\nA Corner Kick refers to a situation where the Play is executed to restart the game after the ball went out of play over the goal line following the touch of the defending team player. The ball must be kicked from the closest field corner and be stationary on the ground when it’s kicked off.","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[1955], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:45.046832Z","iopub.execute_input":"2022-08-04T15:46:45.047409Z","iopub.status.idle":"2022-08-04T15:46:45.236631Z","shell.execute_reply.started":"2022-08-04T15:46:45.047372Z","shell.execute_reply":"2022-08-04T15:46:45.235124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"cross\", \"corner\"]","metadata":{}},{"cell_type":"code","source":"vis_event(df_play.iloc[108], before=2, after=2)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:45.239098Z","iopub.execute_input":"2022-08-04T15:46:45.239548Z","iopub.status.idle":"2022-08-04T15:46:45.392939Z","shell.execute_reply.started":"2022-08-04T15:46:45.239508Z","shell.execute_reply":"2022-08-04T15:46:45.391453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"4\"></a>\n<h2 style='background:green; border:0; color:white'><center>EVENT: challenge<center><h2>","metadata":{"execution":{"iopub.status.busy":"2022-07-29T23:28:45.137203Z","iopub.execute_input":"2022-07-29T23:28:45.137594Z","iopub.status.idle":"2022-07-29T23:28:45.146090Z","shell.execute_reply.started":"2022-07-29T23:28:45.137559Z","shell.execute_reply":"2022-07-29T23:28:45.144241Z"}}},{"cell_type":"markdown","source":"A Challenge is a player action during which two players of opposing teams are physically capable of either gaining or receiving ball control and attempt to do so. A Challenge requires one of the two players to touch the ball or to foul the opposing player.","metadata":{}},{"cell_type":"code","source":"df_challenge = df[df[\"event\"] == \"challenge\"].reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:45.395221Z","iopub.execute_input":"2022-08-04T15:46:45.395614Z","iopub.status.idle":"2022-08-04T15:46:45.406443Z","shell.execute_reply.started":"2022-08-04T15:46:45.395576Z","shell.execute_reply":"2022-08-04T15:46:45.405213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 3))\nsn.countplot(data=df_challenge, y=\"event_attributes\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:45.415850Z","iopub.execute_input":"2022-08-04T15:46:45.416264Z","iopub.status.idle":"2022-08-04T15:46:45.649336Z","shell.execute_reply.started":"2022-08-04T15:46:45.416230Z","shell.execute_reply":"2022-08-04T15:46:45.648517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 5))\nsn.countplot(data=df_challenge, x=\"video_id\", hue=\"event_attributes\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:45.650703Z","iopub.execute_input":"2022-08-04T15:46:45.651431Z","iopub.status.idle":"2022-08-04T15:46:46.154979Z","shell.execute_reply.started":"2022-08-04T15:46:45.651386Z","shell.execute_reply":"2022-08-04T15:46:46.153784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_challenge[\"event_attributes\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.156358Z","iopub.execute_input":"2022-08-04T15:46:46.156698Z","iopub.status.idle":"2022-08-04T15:46:46.167715Z","shell.execute_reply.started":"2022-08-04T15:46:46.156667Z","shell.execute_reply":"2022-08-04T15:46:46.166210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, x in df_challenge.iterrows():\n    if x[\"event_attributes\"] == \"['possession_retained']\":\n        print(i, x)\n        break","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.169446Z","iopub.execute_input":"2022-08-04T15:46:46.169801Z","iopub.status.idle":"2022-08-04T15:46:46.183006Z","shell.execute_reply.started":"2022-08-04T15:46:46.169771Z","shell.execute_reply":"2022-08-04T15:46:46.181189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"opponent_rounded\"]\n\nOpponent rounded: a player in ball control stays in ball control after the challenge, having left the opposing player behind him. Situations where the opponent is not able to gain possession (e.g. when the ball is “flicked” over the opponent) are also to be recorded as challenges.","metadata":{}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[11], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.187079Z","iopub.execute_input":"2022-08-04T15:46:46.188287Z","iopub.status.idle":"2022-08-04T15:46:46.465923Z","shell.execute_reply.started":"2022-08-04T15:46:46.188243Z","shell.execute_reply":"2022-08-04T15:46:46.464817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"ball_action_forced\"]\n\nBall action carried out: applies when none of the players involved in the challenge are in ball control at the start of the challenge (e.g. aerial challenges, challenges for the first touch of the ball) and one player determines the direction of the ball at the end of the challenge.","metadata":{}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[0], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.467887Z","iopub.execute_input":"2022-08-04T15:46:46.469230Z","iopub.status.idle":"2022-08-04T15:46:46.725985Z","shell.execute_reply.started":"2022-08-04T15:46:46.469158Z","shell.execute_reply":"2022-08-04T15:46:46.724325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"fouled\"]\n\nFouled: the referee called a foul.","metadata":{}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[8], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.728303Z","iopub.execute_input":"2022-08-04T15:46:46.729566Z","iopub.status.idle":"2022-08-04T15:46:46.931547Z","shell.execute_reply.started":"2022-08-04T15:46:46.729521Z","shell.execute_reply":"2022-08-04T15:46:46.930173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"opponent_dispossessed\"]\n\nOpponent dispossessed: a player not in ball control dispossesses the opposing player in ball control.","metadata":{}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[1], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:46.933713Z","iopub.execute_input":"2022-08-04T15:46:46.935315Z","iopub.status.idle":"2022-08-04T15:46:47.077172Z","shell.execute_reply.started":"2022-08-04T15:46:46.935268Z","shell.execute_reply":"2022-08-04T15:46:47.076020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"challenge_during_ball_transfer\"]\n\nChallenge during release of the ball: applies when shots or balls played are forced or blocked during challenges. A challenge is only recorded, if the ball played or shot travels through the area that the defending player is attempting to cover from a tactical perspective. All other cases are not recorded as challenges.","metadata":{}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[45], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:47.079238Z","iopub.execute_input":"2022-08-04T15:46:47.079609Z","iopub.status.idle":"2022-08-04T15:46:47.279216Z","shell.execute_reply.started":"2022-08-04T15:46:47.079575Z","shell.execute_reply":"2022-08-04T15:46:47.278022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [\"possession_retained\"]\n\nPossession retained during challenge: applies when one of the players involved in the challenge has certain ball control at the start of the challenge and manages to retain it, despite the efforts to dispossess him of the opponent involved in the challenge.","metadata":{"execution":{"iopub.status.busy":"2022-07-30T22:06:34.545825Z","iopub.execute_input":"2022-07-30T22:06:34.546254Z","iopub.status.idle":"2022-07-30T22:06:34.554853Z","shell.execute_reply.started":"2022-07-30T22:06:34.546195Z","shell.execute_reply":"2022-07-30T22:06:34.553079Z"}}},{"cell_type":"code","source":"vis_event(df_challenge.iloc[2], before=3, after=3)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:47.280733Z","iopub.execute_input":"2022-08-04T15:46:47.281107Z","iopub.status.idle":"2022-08-04T15:46:47.472933Z","shell.execute_reply.started":"2022-08-04T15:46:47.281073Z","shell.execute_reply":"2022-08-04T15:46:47.471825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"5\"></a>\n<h2 style='background:green; border:0; color:white'><center>Process Video<center><h2>","metadata":{}},{"cell_type":"code","source":"import cv2","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:47.474449Z","iopub.execute_input":"2022-08-04T15:46:47.474819Z","iopub.status.idle":"2022-08-04T15:46:47.666901Z","shell.execute_reply.started":"2022-08-04T15:46:47.474784Z","shell.execute_reply":"2022-08-04T15:46:47.665404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vidcap = cv2.VideoCapture(\"test_130.mp4\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:47.669305Z","iopub.execute_input":"2022-08-04T15:46:47.670371Z","iopub.status.idle":"2022-08-04T15:46:47.767644Z","shell.execute_reply.started":"2022-08-04T15:46:47.670321Z","shell.execute_reply":"2022-08-04T15:46:47.766296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"success, image = vidcap.read()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:47.768855Z","iopub.execute_input":"2022-08-04T15:46:47.770073Z","iopub.status.idle":"2022-08-04T15:46:48.221467Z","shell.execute_reply.started":"2022-08-04T15:46:47.770015Z","shell.execute_reply":"2022-08-04T15:46:48.220566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\nplt.figure(figsize=(16, 8))\nplt.imshow(image);","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:48.222796Z","iopub.execute_input":"2022-08-04T15:46:48.223440Z","iopub.status.idle":"2022-08-04T15:46:48.959079Z","shell.execute_reply.started":"2022-08-04T15:46:48.223402Z","shell.execute_reply":"2022-08-04T15:46:48.958106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vidcap = cv2.VideoCapture(\"test_130.mp4\")\n\nfps = vidcap.get(cv2.CAP_PROP_FPS)\nprint(f\"fps: {fps}\")\nframe_count = vidcap.get(cv2.CAP_PROP_FRAME_COUNT)\nprint(f\"frame_count: {frame_count}\")\n\ncount = 0\nsuccess, image = vidcap.read()\nwhile success:\n    count += 1\n    success, image = vidcap.read()\n\nprint(f\"{count} frames.\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:48.960161Z","iopub.execute_input":"2022-08-04T15:46:48.960490Z","iopub.status.idle":"2022-08-04T15:46:50.197754Z","shell.execute_reply.started":"2022-08-04T15:46:48.960459Z","shell.execute_reply":"2022-08-04T15:46:50.196530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 48))\n\nvidcap = cv2.VideoCapture(\"test_130.mp4\")\nnp_video = []\n\nsuccess, image = vidcap.read()\ncount = 0\nstep = 10\nwhile success:\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    np_video.append(image)\n    if not count % step:\n        plt.subplot(8, 2, count // step + 1)\n        plt.imshow(image)\n        plt.axis(\"off\")\n    success, image = vidcap.read()\n        \n    count += 1","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:50.198952Z","iopub.execute_input":"2022-08-04T15:46:50.199727Z","iopub.status.idle":"2022-08-04T15:46:58.793758Z","shell.execute_reply.started":"2022-08-04T15:46:50.199673Z","shell.execute_reply":"2022-08-04T15:46:58.792253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import animation, rc\nrc('animation', html='jshtml')\n\n\ndef create_animation(ims):\n    fig = plt.figure(figsize=(6, 6))\n    plt.axis('off')\n    im = plt.imshow(ims[0], cmap=\"gray\")\n\n    def animate_func(i):\n        im.set_array(ims[i])\n        return [im]\n\n    return animation.FuncAnimation(fig, animate_func, frames=len(ims), interval=1000 // 24)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:58.795621Z","iopub.execute_input":"2022-08-04T15:46:58.796477Z","iopub.status.idle":"2022-08-04T15:46:58.808325Z","shell.execute_reply.started":"2022-08-04T15:46:58.796435Z","shell.execute_reply":"2022-08-04T15:46:58.807251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_animation(np_video)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:46:58.810168Z","iopub.execute_input":"2022-08-04T15:46:58.810532Z","iopub.status.idle":"2022-08-04T15:47:45.767526Z","shell.execute_reply.started":"2022-08-04T15:46:58.810499Z","shell.execute_reply":"2022-08-04T15:47:45.766639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image = np_video[0]\n\nplt.figure(figsize=(16, 8))\nplt.imshow(test_image)\n\nplt.figure(figsize=(16, 8))\ngray_image = cv2.cvtColor(test_image, cv2.COLOR_RGB2GRAY)\nplt.imshow(gray_image, cmap=\"gray\")\n\nplt.figure(figsize=(16, 8))\nplt.imshow(gray_image >= 182, cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:47:45.768741Z","iopub.execute_input":"2022-08-04T15:47:45.769925Z","iopub.status.idle":"2022-08-04T15:47:47.413461Z","shell.execute_reply.started":"2022-08-04T15:47:45.769885Z","shell.execute_reply":"2022-08-04T15:47:47.412148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://towardsdatascience.com/football-players-tracking-identifying-players-team-based-on-their-jersey-colors-using-opencv-7eed1b8a1095\n\ncolor_list = [\"red\", \"blue\", \"white\"]\n\nboundaries = [\n    ((17, 15, 75), (50, 56, 200)),\n    ((43, 31, 4), (250, 88, 50)),\n    ((187, 169, 112), (255, 255, 255)),\n]","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:47:47.415095Z","iopub.execute_input":"2022-08-04T15:47:47.415457Z","iopub.status.idle":"2022-08-04T15:47:47.423353Z","shell.execute_reply.started":"2022-08-04T15:47:47.415424Z","shell.execute_reply":"2022-08-04T15:47:47.421850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for color, boundary in zip(color_list, boundaries):\n    mask = cv2.inRange(test_image, boundary[0], boundary[1])\n    \n    output = cv2.bitwise_and(test_image, test_image, mask=mask)\n    \n    plt.figure(figsize=(16, 12))\n    plt.subplot(2, 2, 1)\n    plt.imshow(test_image)\n    plt.subplot(2, 2, 3)\n    plt.imshow(output)\n    plt.subplot(2, 2, 2)\n    plt.imshow(mask)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-04T15:47:47.425326Z","iopub.execute_input":"2022-08-04T15:47:47.426723Z","iopub.status.idle":"2022-08-04T15:47:51.304870Z","shell.execute_reply.started":"2022-08-04T15:47:47.426677Z","shell.execute_reply":"2022-08-04T15:47:51.303386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}