{"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":"code","source":"\"\"\"Notebook to visualize star reef annotations; can pass in an image number/video or a full video for mp4 output.\nCreated for the 2022 \"TensorFlow - Help Protect the Great Barrier Reef\" Kaggle contest.\n\n\"\"\"\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom PIL import Image, ImageDraw\nimport matplotlib.pyplot as plt\nimport ast\nimport os\nimport cv2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-28T19:31:26.709918Z","iopub.execute_input":"2022-01-28T19:31:26.710206Z","iopub.status.idle":"2022-01-28T19:31:26.714890Z","shell.execute_reply.started":"2022-01-28T19:31:26.710178Z","shell.execute_reply":"2022-01-28T19:31:26.714256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\nDraws a red box over given image, where the box is defined by top left and bottom right coordinates.\n\"\"\"\ndef draw_box(top_left, bot_right, img):\n    img_d = ImageDraw.Draw(img)\n    img_d.rectangle((top_left, bot_right), fill=None, outline=\"red\", width=4)\n\n\"\"\"\nTakes an image and video number, and returns a red box annotated image.\nvideo_n - video number\nimage_n - frame number for given video_n\ndata_path - kaggle input folder\ndisplay - if true, display inline matplotlib image of annotated image\nsave_outp - if true, saves annotated image to output folder as image_{video_n}-{image_n}_annotated.jpg\n\"\"\"\ndef annotate_image(video_n, image_n, data_path, display=False, save_outp=False): \n    data_path = \"/kaggle/input/tensorflow-great-barrier-reef\"\n    img = Image.open(data_path + \"/train_images/video_{}/{}.jpg\".format(video_n, image_n))\n    train_df = pd.read_csv(data_path + \"/train.csv\", converters={'annotations': ast.literal_eval})\n    curr_entry = train_df[train_df[\"image_id\"] == \"{}-{}\".format(video_n, image_n)]\n    annot_list = curr_entry[\"annotations\"].iloc[0]\n\n    for i in range(len(annot_list)):\n        json_box = annot_list[i]\n        box_coords = ((json_box[\"x\"],json_box[\"y\"]),\n                      (json_box[\"x\"] + json_box[\"width\"], json_box[\"y\"] + json_box[\"height\"]))\n        draw_box(*box_coords, img)\n    if display:\n        plt.imshow(img)\n    if save_outp:\n        img.save(\"/kaggle/working/image_{}-{}_annotated.png\".format(video_n, image_n))\n    return img\n\n\"\"\"\nLoops over video, annotates frames, and saved new video with annotated output.\nBy default, loops over entire video, and has a framerate of 10.\nIf you have specefic start/end frames you'd look to focus on, you can change those\nusing the start_frame/end_frame kwargs, and similarly may change the framerate.\n\nsave_frames will save each individual frame, but be careful, as it can give a lot of\noutput.\n\"\"\"\ndef annotate_video(video_n, data_path, start_frame=0, \n                   end_frame=-1, framerate=10, save_frames=False):\n    if end_frame == -1:\n        total_frames = len(os.listdir(data_path + \"/train_images/video_{}\".format(video_n)))\n    else:\n        total_frames = end_frame\n        \n    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')\n    video_dim = (1280, 720)\n    video = cv2.VideoWriter(\"/kaggle/working/video_{}_annotated.mp4\".format(video_n),fourcc,framerate,video_dim)\n    \n    for frame_n in range(start_frame, total_frames):\n        try:\n            img = annotate_image(video_n, frame_n, data_path, display=True)\n        except FileNotFoundError:\n            print(\"Image no. {} not found\".format(frame_n))\n            continue\n        video.write(cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR))\n        img.close()\n            \n    video.release()","metadata":{"execution":{"iopub.status.busy":"2022-01-28T20:06:56.850790Z","iopub.status.idle":"2022-01-28T20:06:56.851517Z","shell.execute_reply.started":"2022-01-28T20:06:56.851266Z","shell.execute_reply":"2022-01-28T20:06:56.851296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = \"/kaggle/input/tensorflow-great-barrier-reef\"\nimg = annotate_image(0, 39, data_path, display=True, save_outp=True)\nimg.close()\n","metadata":{"execution":{"iopub.status.busy":"2022-01-28T19:31:43.823512Z","iopub.execute_input":"2022-01-28T19:31:43.823785Z","iopub.status.idle":"2022-01-28T19:31:44.820219Z","shell.execute_reply.started":"2022-01-28T19:31:43.823756Z","shell.execute_reply":"2022-01-28T19:31:44.819358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = \"/kaggle/input/tensorflow-great-barrier-reef\"\n\nannotate_video(video_n, data_path)","metadata":{"execution":{"iopub.status.busy":"2022-01-28T20:12:00.347379Z","iopub.status.idle":"2022-01-28T20:12:00.348333Z","shell.execute_reply.started":"2022-01-28T20:12:00.348055Z","shell.execute_reply":"2022-01-28T20:12:00.348128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-01-28T19:00:31.430882Z","iopub.execute_input":"2022-01-28T19:00:31.431765Z","iopub.status.idle":"2022-01-28T19:00:32.189822Z","shell.execute_reply.started":"2022-01-28T19:00:31.431726Z","shell.execute_reply":"2022-01-28T19:00:32.188797Z"},"trusted":true},"execution_count":null,"outputs":[]}]}