{"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":"# References\n* Thanks to DIEGO GOMEZ & BAEK KYUN SHIN\n* https://www.kaggle.com/diegoalejogm/great-barrier-reefs-eda-with-animations\n* https://www.kaggle.com/werooring/basic-eda-starter-for-everyone","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-26T06:16:23.028234Z","iopub.execute_input":"2021-11-26T06:16:23.028539Z","iopub.status.idle":"2021-11-26T06:16:23.033526Z","shell.execute_reply.started":"2021-11-26T06:16:23.028507Z","shell.execute_reply":"2021-11-26T06:16:23.032644Z"}}},{"cell_type":"markdown","source":"# Imports","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport matplotlib.gridspec as gridspec \nimport seaborn as sns\nfrom PIL import ImageDraw\nfrom matplotlib import animation, rc\nrc('animation', html='jshtml')\n\nimport ast","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:21:08.688375Z","iopub.execute_input":"2021-11-29T19:21:08.690274Z","iopub.status.idle":"2021-11-29T19:21:08.695158Z","shell.execute_reply.started":"2021-11-29T19:21:08.690241Z","shell.execute_reply":"2021-11-29T19:21:08.694551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load data","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\ntest = pd.read_csv('../input/tensorflow-great-barrier-reef/test.csv')\nsample = pd.read_csv('../input/tensorflow-great-barrier-reef/example_sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:21:37.842969Z","iopub.execute_input":"2021-11-29T19:21:37.843428Z","iopub.status.idle":"2021-11-29T19:21:37.908694Z","shell.execute_reply.started":"2021-11-29T19:21:37.843382Z","shell.execute_reply":"2021-11-29T19:21:37.908027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Analyze","metadata":{}},{"cell_type":"code","source":"train.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:22:03.499630Z","iopub.execute_input":"2021-11-29T19:22:03.500303Z","iopub.status.idle":"2021-11-29T19:22:03.505078Z","shell.execute_reply.started":"2021-11-29T19:22:03.500268Z","shell.execute_reply":"2021-11-29T19:22:03.504424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:21:41.144484Z","iopub.execute_input":"2021-11-29T19:21:41.144796Z","iopub.status.idle":"2021-11-29T19:21:41.164699Z","shell.execute_reply.started":"2021-11-29T19:21:41.144758Z","shell.execute_reply":"2021-11-29T19:21:41.164132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.tail()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:21:41.751757Z","iopub.execute_input":"2021-11-29T19:21:41.752206Z","iopub.status.idle":"2021-11-29T19:21:41.761864Z","shell.execute_reply.started":"2021-11-29T19:21:41.752160Z","shell.execute_reply":"2021-11-29T19:21:41.761152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:21:42.524809Z","iopub.execute_input":"2021-11-29T19:21:42.525241Z","iopub.status.idle":"2021-11-29T19:21:42.549296Z","shell.execute_reply.started":"2021-11-29T19:21:42.525198Z","shell.execute_reply":"2021-11-29T19:21:42.548661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Checking Duplicates","metadata":{}},{"cell_type":"code","source":"train.duplicated().sum()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:22:59.278579Z","iopub.execute_input":"2021-11-29T19:22:59.279181Z","iopub.status.idle":"2021-11-29T19:22:59.297507Z","shell.execute_reply.started":"2021-11-29T19:22:59.279146Z","shell.execute_reply":"2021-11-29T19:22:59.296719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['video_id'].nunique()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:23:00.404628Z","iopub.execute_input":"2021-11-29T19:23:00.404889Z","iopub.status.idle":"2021-11-29T19:23:00.410094Z","shell.execute_reply.started":"2021-11-29T19:23:00.404863Z","shell.execute_reply":"2021-11-29T19:23:00.409562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['video_id'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:25:47.654315Z","iopub.execute_input":"2021-11-29T19:25:47.654608Z","iopub.status.idle":"2021-11-29T19:25:47.662240Z","shell.execute_reply.started":"2021-11-29T19:25:47.654577Z","shell.execute_reply":"2021-11-29T19:25:47.661497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### As you can see, we have totally 3 videos in the training dataset. Now lets see row count for each videos","metadata":{}},{"cell_type":"code","source":"sns.set_theme(style=\"whitegrid\")\nax = sns.countplot(x='video_id', data=train)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:23:06.913072Z","iopub.execute_input":"2021-11-29T19:23:06.913503Z","iopub.status.idle":"2021-11-29T19:23:07.152355Z","shell.execute_reply.started":"2021-11-29T19:23:06.913459Z","shell.execute_reply":"2021-11-29T19:23:07.151585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Not all the images have Crown-Of-Thorns Starfish (COTS) for which we have annotations as []","metadata":{}},{"cell_type":"code","source":"for i in range(3):\n    print(\"Video \" + str(i))\n    print(\"Frames with Annotations : \" + str((train[train['video_id'] == i]['annotations'] != '[]').sum()) )\n    print(\"Frames without Annotations : \" + str((train[train['video_id'] == i]['annotations'] == '[]').sum()) )\n    print(\"---------\")","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:25:12.895680Z","iopub.execute_input":"2021-11-29T19:25:12.896001Z","iopub.status.idle":"2021-11-29T19:25:12.915835Z","shell.execute_reply.started":"2021-11-29T19:25:12.895972Z","shell.execute_reply":"2021-11-29T19:25:12.915006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Feature Engineering","metadata":{}},{"cell_type":"code","source":"train.iloc[16].annotations\n# Note the below result is string. We need to convert it to list","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:26:28.194043Z","iopub.execute_input":"2021-11-29T19:26:28.195035Z","iopub.status.idle":"2021-11-29T19:26:28.204803Z","shell.execute_reply.started":"2021-11-29T19:26:28.194981Z","shell.execute_reply":"2021-11-29T19:26:28.201328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert String to List Type\ntrain['annotations'] = train['annotations'].apply(ast.literal_eval)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:26:36.340893Z","iopub.execute_input":"2021-11-29T19:26:36.341427Z","iopub.status.idle":"2021-11-29T19:26:36.734465Z","shell.execute_reply.started":"2021-11-29T19:26:36.341392Z","shell.execute_reply":"2021-11-29T19:26:36.733640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.iloc[16].annotations\n","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:26:50.355948Z","iopub.execute_input":"2021-11-29T19:26:50.356206Z","iopub.status.idle":"2021-11-29T19:26:50.362950Z","shell.execute_reply.started":"2021-11-29T19:26:50.356180Z","shell.execute_reply":"2021-11-29T19:26:50.362225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Lets create a feature which have info about number of annotations per image","metadata":{}},{"cell_type":"code","source":"train['num_bboxes'] = train['annotations'].apply(lambda x: len(x))","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:27:08.935607Z","iopub.execute_input":"2021-11-29T19:27:08.936380Z","iopub.status.idle":"2021-11-29T19:27:08.951972Z","shell.execute_reply.started":"2021-11-29T19:27:08.936339Z","shell.execute_reply":"2021-11-29T19:27:08.951229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['num_bboxes'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:27:36.711684Z","iopub.execute_input":"2021-11-29T19:27:36.712421Z","iopub.status.idle":"2021-11-29T19:27:36.719579Z","shell.execute_reply.started":"2021-11-29T19:27:36.712385Z","shell.execute_reply":"2021-11-29T19:27:36.718612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Total rows without annotations : {}'.format(train[train['num_bboxes'] == 0]['num_bboxes'].count()))","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:27:17.548312Z","iopub.execute_input":"2021-11-29T19:27:17.548951Z","iopub.status.idle":"2021-11-29T19:27:17.557949Z","shell.execute_reply.started":"2021-11-29T19:27:17.548910Z","shell.execute_reply":"2021-11-29T19:27:17.557017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Lets see the distribution of number of COTS per image","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize = (15,8))\nsns.countplot(x=train[train['num_bboxes'] > 0].num_bboxes,data=train)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:27:54.526435Z","iopub.execute_input":"2021-11-29T19:27:54.526843Z","iopub.status.idle":"2021-11-29T19:27:54.883488Z","shell.execute_reply.started":"2021-11-29T19:27:54.526812Z","shell.execute_reply":"2021-11-29T19:27:54.882728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[train['annotations'].str.len() > 2]","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:28:05.856089Z","iopub.execute_input":"2021-11-29T19:28:05.856377Z","iopub.status.idle":"2021-11-29T19:28:05.895421Z","shell.execute_reply.started":"2021-11-29T19:28:05.856346Z","shell.execute_reply":"2021-11-29T19:28:05.894695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Validate Images","metadata":{}},{"cell_type":"code","source":"from os import listdir\nfrom PIL import Image\n\ndef validate_images(video_id):\n    path = '/kaggle/input/tensorflow-great-barrier-reef/train_images/video_{}/'.format(video_id)\n    \n    print(\"Verifying that video {} frames are valid...\".format(video_id))\n    for filename in listdir(path):\n        if filename.endswith('.jpg'):\n            try:\n                img = Image.open(path+filename)\n                img.verify() # Verify it is in fact an image\n            except (IOError, SyntaxError) as e:\n                print('Bad file:', filename) # Print out the names of corrupt files\n    print(\"Verified! Video {} has all valid images\".format(video_id))\n\n# for video_id in range(3):\n#     validate_images(video_id)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:29:06.172477Z","iopub.execute_input":"2021-11-29T19:29:06.173397Z","iopub.status.idle":"2021-11-29T19:29:06.180374Z","shell.execute_reply.started":"2021-11-29T19:29:06.173350Z","shell.execute_reply":"2021-11-29T19:29:06.179407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fetch_image(df, video_id, frame_id):\n    # get frame\n    frame = df[(df['video_id'] == video_id) & (df['video_frame'] == frame_id)].iloc[0]\n    # get bounding_boxes\n    bounding_boxes = frame['annotations']\n    # open image\n    img = Image.open('/kaggle/input/tensorflow-great-barrier-reef/' + f'train_images/video_{video_id}/{frame_id}.jpg')\n\n    for box in bounding_boxes:\n        x0, y0, x1, y1 = (box['x'], box['y'], box['x']+box['width'], box['y']+box['height'])\n        draw = ImageDraw.Draw(img)\n        draw.rectangle( (x0, y0, x1, y1), outline=180, width=5)\n    return img\n\ndef fetch_image_list(df, video_id, num_images, start_frame_idx):\n    image_list = [np.array(fetch_image(df, video_id, start_frame_idx + index)) for index in range(num_images)]\n\n    return image_list","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:29:07.018592Z","iopub.execute_input":"2021-11-29T19:29:07.018862Z","iopub.status.idle":"2021-11-29T19:29:07.027014Z","shell.execute_reply.started":"2021-11-29T19:29:07.018834Z","shell.execute_reply":"2021-11-29T19:29:07.025866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# images = fetch_image_list(train, video_id=2, num_images=5000, start_frame_idx=100)\nimages = fetch_image_list(train, video_id=0, num_images=200, start_frame_idx=100)\n\n\nprint(f'Number of images: {len(images)}')","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:45:15.466942Z","iopub.execute_input":"2021-11-29T19:45:15.467362Z","iopub.status.idle":"2021-11-29T19:45:20.951571Z","shell.execute_reply.started":"2021-11-29T19:45:15.467331Z","shell.execute_reply":"2021-11-29T19:45:20.950726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualize COTS Annimation","metadata":{}},{"cell_type":"code","source":"grid = gridspec.GridSpec(4, 2) \nplt.figure(figsize=(18, 20))\n\nidx_list = [0, 5, 10, 15, 20, 25, 30, 35] \n\nfor i, idx in enumerate(idx_list): \n    ax = plt.subplot(grid[i])\n    plt.imshow(images[idx], interpolation='nearest')\n    ax.set_title(f'frame index {idx}')\n    plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:45:20.953424Z","iopub.execute_input":"2021-11-29T19:45:20.953848Z","iopub.status.idle":"2021-11-29T19:45:22.706182Z","shell.execute_reply.started":"2021-11-29T19:45:20.953806Z","shell.execute_reply":"2021-11-29T19:45:22.705331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_animation(imgs, frame_interval=130):\n    fig = plt.figure(figsize=(7, 4))\n    plt.axis('off')\n    img = plt.imshow(imgs[0])\n\n    def animate(i):\n        img.set_array(imgs[i])\n        return [img]\n\n    return animation.FuncAnimation(fig, animate, frames=len(imgs), interval=frame_interval)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:45:22.707274Z","iopub.execute_input":"2021-11-29T19:45:22.707488Z","iopub.status.idle":"2021-11-29T19:45:22.712498Z","shell.execute_reply.started":"2021-11-29T19:45:22.707464Z","shell.execute_reply":"2021-11-29T19:45:22.711976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frame_interval = 190 # set smaller number if you want to play fast, otherwise set bigger\n\ncreate_animation(images, frame_interval=frame_interval)","metadata":{"execution":{"iopub.status.busy":"2021-11-29T19:45:22.713610Z","iopub.execute_input":"2021-11-29T19:45:22.714228Z","iopub.status.idle":"2021-11-29T19:45:43.589882Z","shell.execute_reply.started":"2021-11-29T19:45:22.714198Z","shell.execute_reply":"2021-11-29T19:45:43.589001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}