{"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":"### In this notebook, extraction of difference in each frame is demonstrated to emphasize the movement of players and the ball.\n### I recommend to resize the videos by encoding methods such as [@YOKUYAMA's work](https://www.kaggle.com/code/yokuyama/fast-video-resizing-with-ffmpeg-384x216).","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport cv2\nfrom tqdm import tqdm\nfrom PIL import Image\nfrom IPython.display import Video","metadata":{"execution":{"iopub.status.busy":"2022-08-04T12:19:25.774822Z","iopub.execute_input":"2022-08-04T12:19:25.775504Z","iopub.status.idle":"2022-08-04T12:19:25.819250Z","shell.execute_reply.started":"2022-08-04T12:19:25.775436Z","shell.execute_reply":"2022-08-04T12:19:25.817876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create frames from a video file.\n### And execute difference extraction.","metadata":{}},{"cell_type":"code","source":"path = \"../input/dfl-bundesliga-data-shootout/train/1606b0e6_0.mp4\"\nsave_dir = path.split(\"/\")[-1].replace(\".mp4\",\"\")\nos.makedirs(save_dir, exist_ok=True)\n\nfilelist=[]\ndef frame_sub(frame1, frame2, frame3):\n    diff1 = cv2.absdiff(frame1, frame2)\n    diff2 = cv2.absdiff(frame2, frame3)\n    diff = cv2.bitwise_and(diff1, diff2)\n    mask = cv2.medianBlur(diff, 3) # Median filter\n    return  mask\nvideo = cv2.VideoCapture(path)\n\n#n_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) #Save all frames\nn_frames = 200\n\nfps = video.get(cv2.CAP_PROP_FPS)\nprint(fps, \"fps\")\nstart_time = 660 # Read from 11:00\nvideo.set(cv2.CAP_PROP_POS_FRAMES, start_time * fps)\n\nframe1 = cv2.cvtColor(video.read()[1], cv2.COLOR_RGB2GRAY)\nframe2 = cv2.cvtColor(video.read()[1], cv2.COLOR_RGB2GRAY)\nfor frame in tqdm(range(n_frames-2)):\n    frame3 = cv2.cvtColor(video.read()[1], cv2.COLOR_RGB2GRAY)\n    mask = frame_sub(frame1, frame2, frame3)\n    \n    c = 40\n    mask2 = np.where(mask>255/c,255,mask*c) # Adjust brightness\n\n    filename = save_dir+\"/\"+f\"{frame}.jpg\"\n    cv2.imwrite(filename, mask2)\n    \n    #filelist.append(Image.fromarray(np.uint8(mask2)).convert('P')) # If saving as gif\n    filelist.append(mask2)\n    \n    frame1 = frame2\n    frame2 = frame3\nvideo.release()\nheight, width = mask2.shape[:2]\nprint('h:',height,' w:',width)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T12:19:25.826231Z","iopub.execute_input":"2022-08-04T12:19:25.826711Z","iopub.status.idle":"2022-08-04T12:19:36.214421Z","shell.execute_reply.started":"2022-08-04T12:19:25.826593Z","shell.execute_reply":"2022-08-04T12:19:36.213053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save as mp4 or gif.","metadata":{}},{"cell_type":"code","source":"#Save as mp4\n#fourcc = cv2.VideoWriter_fourcc('m','p','4', 'v') \nfourcc = cv2.VideoWriter_fourcc(*'VP90') # I use VP90 here just for showing the movie in IPython. Otherwise, just specifying mp4 as above is better because processing VP90 is very slow.\n\nmovie  = cv2.VideoWriter(f'{save_dir}_diff.mp4', fourcc, fps, (width, height), 0)\nfor frame in tqdm(filelist):\n    movie.write(frame)\nmovie.release()\n\n#Save as gif.\n#filelist[0].save(\"animation.gif\",save_all=True, append_images=filelist[1:], optimize=False, duration=1000/fps, loop=0)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T12:19:36.215895Z","iopub.execute_input":"2022-08-04T12:19:36.216402Z","iopub.status.idle":"2022-08-04T12:26:19.710123Z","shell.execute_reply.started":"2022-08-04T12:19:36.216350Z","shell.execute_reply":"2022-08-04T12:26:19.708806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let's watch it in animation.","metadata":{}},{"cell_type":"code","source":"Video(f'{save_dir}_diff.mp4', width=960)","metadata":{"execution":{"iopub.status.busy":"2022-08-04T12:26:19.712635Z","iopub.execute_input":"2022-08-04T12:26:19.713841Z","iopub.status.idle":"2022-08-04T12:26:19.723863Z","shell.execute_reply.started":"2022-08-04T12:26:19.713795Z","shell.execute_reply":"2022-08-04T12:26:19.722746Z"},"trusted":true},"execution_count":null,"outputs":[]}]}