{"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 Ball Detection\n<img src=\"https://media.dfl.de/sites/3/2019/02/Spielball-Derbystar-1200x675.jpg\" alt=\"DFL Bundesliga (source: dfl.de)\" width=\"1024px\">\n<i>Source: dfl.de</i>\n<br><br>\nGoal! In this competition, we'll detect football (soccer) passes—including throw-ins and crosses—and challenges in original Bundesliga matches  ([read the event description here](https://www.kaggle.com/competitions/dfl-bundesliga-data-shootout/overview/event-descriptions)). We'll develop a computer vision model that can automatically classify these events in long video recordings.\n<br><br>\nWe will develop using Yolov5 to detect ball in the clips. I am learning and use a lot how to do it from [this notebook by Shinmurashinmura](https://www.kaggle.com/code/shinmurashinmura/dfl-yolov5-ball-detection), and [Yolov5 site](https://github.com/ultralytics/yolov5).","metadata":{}},{"cell_type":"code","source":"!pip install moviepy -q","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:12:04.359050Z","iopub.execute_input":"2022-08-14T11:12:04.359727Z","iopub.status.idle":"2022-08-14T11:12:27.612784Z","shell.execute_reply.started":"2022-08-14T11:12:04.359639Z","shell.execute_reply":"2022-08-14T11:12:27.611652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd ../\n!mkdir tmp\n%cd tmp","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:12:43.066267Z","iopub.execute_input":"2022-08-14T11:12:43.067102Z","iopub.status.idle":"2022-08-14T11:12:44.072172Z","shell.execute_reply.started":"2022-08-14T11:12:43.067059Z","shell.execute_reply":"2022-08-14T11:12:44.070938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load Yolov5\n\nWe use Yolov5 to detect the ball in video clips.","metadata":{}},{"cell_type":"code","source":"!git clone https://github.com/ultralytics/yolov5  # clone repo\n%cd yolov5\n%pip install -qr requirements.txt  # install dependencies\n%cd ../\nimport torch\nprint(f\"Setup complete. Using torch {torch.__version__} ({torch.cuda.get_device_properties(0).name if torch.cuda.is_available() else 'CPU'})\")","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:12:49.796388Z","iopub.execute_input":"2022-08-14T11:12:49.796986Z","iopub.status.idle":"2022-08-14T11:13:04.717134Z","shell.execute_reply.started":"2022-08-14T11:12:49.796949Z","shell.execute_reply":"2022-08-14T11:13:04.715820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load Dependencies","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nfrom shutil import copyfile\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nimport subprocess","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:13:11.204829Z","iopub.execute_input":"2022-08-14T11:13:11.205490Z","iopub.status.idle":"2022-08-14T11:13:11.622384Z","shell.execute_reply.started":"2022-08-14T11:13:11.205453Z","shell.execute_reply":"2022-08-14T11:13:11.621402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/\n!cp -r input/dfl-yolov5l6-ball-detection/yolov5l6_trained_600images.pt tmp/yolov5/\n!cp -r input/dfl-bundesliga-data-shootout/clips/0bfacc_1.mp4 tmp/yolov5/\n%cd tmp/yolov5/","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:13:16.826986Z","iopub.execute_input":"2022-08-14T11:13:16.827592Z","iopub.status.idle":"2022-08-14T11:13:22.180122Z","shell.execute_reply.started":"2022-08-14T11:13:16.827546Z","shell.execute_reply":"2022-08-14T11:13:22.178867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Inference with random clip: clips/0bfacc_1.mp4","metadata":{}},{"cell_type":"code","source":"!python detect.py --img 1280 \\\n                  --weights yolov5l6_trained_600images.pt \\\n                  --source 0bfacc_1.mp4 \\\n                  --project DFL","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:13:27.471500Z","iopub.execute_input":"2022-08-14T11:13:27.471886Z","iopub.status.idle":"2022-08-14T11:14:40.926421Z","shell.execute_reply.started":"2022-08-14T11:13:27.471852Z","shell.execute_reply":"2022-08-14T11:14:40.925207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r ./DFL/exp/ /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:14:44.638729Z","iopub.execute_input":"2022-08-14T11:14:44.639195Z","iopub.status.idle":"2022-08-14T11:14:45.677892Z","shell.execute_reply.started":"2022-08-14T11:14:44.639132Z","shell.execute_reply":"2022-08-14T11:14:45.676534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import subprocess\n\ncap = cv2.VideoCapture(\"./DFL/exp/0bfacc_1.mp4\")\n\nframes = []\nwhile True:\n    ret, img = cap.read()\n    if ret == False:\n        break\n    frames.append(img)\n    width = img.shape[1]\n    height = img.shape[0]\ncap.release()\n\nvideo = cv2.VideoWriter(\"/kaggle/working/tmp.mp4\", cv2.VideoWriter_fourcc(*'MP4V'),\n                                25, (width,height))\nfor img in frames:\n    video.write(img)\n\nvideo.release()   \n\nsubprocess.run([\"ffmpeg\", \"-i\", \"/kaggle/working/tmp.mp4\", \"-crf\", \"18\", \"-preset\", \"veryfast\",\n                \"-vcodec\",\"libx264\", \"/kaggle/working/output.mp4\",])","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:14:52.503229Z","iopub.execute_input":"2022-08-14T11:14:52.503915Z","iopub.status.idle":"2022-08-14T11:15:48.428534Z","shell.execute_reply.started":"2022-08-14T11:14:52.503876Z","shell.execute_reply":"2022-08-14T11:15:48.427453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip\nfrom IPython.display import Video\n\nfilename = \"Output.mp4\"\nffmpeg_extract_subclip(\"/kaggle/working/output.mp4\", 0, 30, targetname=filename)\n    \nVideo(filename, width=800, embed=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-14T11:16:04.334221Z","iopub.execute_input":"2022-08-14T11:16:04.334985Z","iopub.status.idle":"2022-08-14T11:16:05.909825Z","shell.execute_reply.started":"2022-08-14T11:16:04.334946Z","shell.execute_reply":"2022-08-14T11:16:05.908266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Thank you for visiting this notebook!\nThanks for reading this notebook. If you have any feedback or comments please write it down the comment section below.","metadata":{}},{"cell_type":"markdown","source":" # References:<br>\n https://www.kaggle.com/code/shinmurashinmura/dfl-yolov5-ball-detection<br>\n https://github.com/ultralytics/yolov5<br>","metadata":{}}]}