{"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":"# Great Barrier Reefs\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## Notebook d'exploration des données \nPlan:\n* Exloration et visualisation des données \n* Explication sur le F2-score avec exemples","metadata":{}},{"cell_type":"markdown","source":"# Référence\n* https://www.kaggle.com/diegoalejogm/great-barrier-reefs-eda-with-animations","metadata":{}},{"cell_type":"code","source":"!pip install pycodestyle\n!pip install --index-url https://test.pypi.org/simple/ nbpep8","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:16.575609Z","iopub.execute_input":"2022-02-25T17:58:16.576871Z","iopub.status.idle":"2022-02-25T17:58:35.340202Z","shell.execute_reply.started":"2022-02-25T17:58:16.576825Z","shell.execute_reply":"2022-02-25T17:58:35.339039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from nbpep8.nbpep8 import pep8\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:35.342603Z","iopub.execute_input":"2022-02-25T17:58:35.342960Z","iopub.status.idle":"2022-02-25T17:58:35.349074Z","shell.execute_reply.started":"2022-02-25T17:58:35.342919Z","shell.execute_reply":"2022-02-25T17:58:35.347781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nPour toujours être dans les standards PEP8, on utilise la commmande pep8(_ih) dans chaque cellule de code afin de contôler notre code.\nPar exemple dans le code a=1, il manque les espaces autour de l'opérateur  :\n(Ainsi que la première ligne de commentaire est trop longue)\n'''\na=1\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:35.350796Z","iopub.execute_input":"2022-02-25T17:58:35.351557Z","iopub.status.idle":"2022-02-25T17:58:35.568486Z","shell.execute_reply.started":"2022-02-25T17:58:35.351495Z","shell.execute_reply":"2022-02-25T17:58:35.566991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Installation des outils et des chemins\n","metadata":{}},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom matplotlib import image\nimport matplotlib.patches as patches\nfrom PIL import Image\nimport pickle\nimport cv2\nimport ast\nimport sys\nfrom tqdm.notebook import tqdm\nimport warnings\nwarnings.filterwarnings('ignore')\nplt.style.use('seaborn')\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:35.571759Z","iopub.execute_input":"2022-02-25T17:58:35.572191Z","iopub.status.idle":"2022-02-25T17:58:35.781261Z","shell.execute_reply.started":"2022-02-25T17:58:35.572137Z","shell.execute_reply":"2022-02-25T17:58:35.780228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = '../input/tensorflow-great-barrier-reef'\n!ls {data_path}\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:35.785486Z","iopub.execute_input":"2022-02-25T17:58:35.785808Z","iopub.status.idle":"2022-02-25T17:58:36.793351Z","shell.execute_reply.started":"2022-02-25T17:58:35.785770Z","shell.execute_reply":"2022-02-25T17:58:36.792576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# greatbarrierreef/ : image delivery api\n!ls {os.path.join(data_path, 'greatbarrierreef/')}\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:36.795189Z","iopub.execute_input":"2022-02-25T17:58:36.795628Z","iopub.status.idle":"2022-02-25T17:58:37.789646Z","shell.execute_reply.started":"2022-02-25T17:58:36.795594Z","shell.execute_reply":"2022-02-25T17:58:37.788548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_images/ : training data folders, containing 3 videos folders : video_{video_id}\n!ls {os.path.join(data_path, 'train_images/')}\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:37.791787Z","iopub.execute_input":"2022-02-25T17:58:37.792478Z","iopub.status.idle":"2022-02-25T17:58:38.809855Z","shell.execute_reply.started":"2022-02-25T17:58:37.792424Z","shell.execute_reply":"2022-02-25T17:58:38.808680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploration","metadata":{}},{"cell_type":"markdown","source":"****Exploration des données de la compétition pour comprendre comment se répartissent les annotations dans les vidéos****","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv(os.path.join(data_path, 'train.csv'))\ndf_train[12:22]","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:38.811858Z","iopub.execute_input":"2022-02-25T17:58:38.812117Z","iopub.status.idle":"2022-02-25T17:58:38.886395Z","shell.execute_reply.started":"2022-02-25T17:58:38.812086Z","shell.execute_reply":"2022-02-25T17:58:38.885776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.info()\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:38.887407Z","iopub.execute_input":"2022-02-25T17:58:38.888167Z","iopub.status.idle":"2022-02-25T17:58:39.114312Z","shell.execute_reply.started":"2022-02-25T17:58:38.888113Z","shell.execute_reply":"2022-02-25T17:58:39.113489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# size\nvideo_ids = df_train['video_id'].unique()\nprint(f'Video count : {len(video_ids)}')\nfor video_id in video_ids:\n    img_path = os.path.join(data_path, 'train_images',\n                            f'video_{video_id}', '0.jpg')\n    im = Image.open(img_path)\n    print(f'Video {video_id} : {im.size}, {im.mode}')\nSIZE = (1280, 720)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:39.116221Z","iopub.execute_input":"2022-02-25T17:58:39.116516Z","iopub.status.idle":"2022-02-25T17:58:39.400089Z","shell.execute_reply.started":"2022-02-25T17:58:39.116484Z","shell.execute_reply":"2022-02-25T17:58:39.399224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_video_data(df_train):\n    video_data = {}\n    for video_id in df_train['video_id'].unique():\n        df_video = df_train.loc[df_train['video_id'] == video_id]\n        data_sequence = {}\n        video_data[video_id] = {}\n        video_data[video_id]['frames_count'] = 0\n        video_data[video_id]['frames_with_annot_count'] = 0\n        for sequence in df_video['sequence'].unique():\n            df_sequence = df_video.loc[df_video['sequence'] == sequence]\n            seq_annotations = {}\n            seq_annotations['frames_count'] = len(df_sequence)\n            seq_annotations['frames_with_annot_count'] = df_sequence.loc[df_train['annotations'] != '[]']['annotations'].count()\n            data_sequence[sequence] = seq_annotations\n            video_data[video_id]['frames_count'] += seq_annotations['frames_count']\n            video_data[video_id]['frames_with_annot_count'] += seq_annotations['frames_with_annot_count']\n        video_data[video_id]['sequence'] = data_sequence\n    return video_data\n\n\ndef print_video_data(video_data):\n    for video_id in video_data.keys():\n        frames_count = video_data[video_id]['frames_count']\n        frames_with_annot_count = video_data[video_id]['frames_with_annot_count']\n        print(f'Video {video_id} : {frames_count} frames, {frames_with_annot_count} frames with annotation(s)')\n        for sequence_id in video_data[video_id]['sequence'].keys():\n            frames_count = video_data[video_id]['sequence'][sequence_id]['frames_count']\n            annotations_count = video_data[video_id]['sequence'][sequence_id]['frames_with_annot_count']\n            print(f'  Sequence {sequence_id} : {frames_count} frames, {annotations_count} with annotation(s)')\n        print('\\n')\n\n\nvideo_data = get_video_data(df_train)\nprint_video_data(video_data)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:39.402051Z","iopub.execute_input":"2022-02-25T17:58:39.402630Z","iopub.status.idle":"2022-02-25T17:58:39.768245Z","shell.execute_reply.started":"2022-02-25T17:58:39.402580Z","shell.execute_reply":"2022-02-25T17:58:39.767001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_video_data(video_data):\n    plt.style.use('seaborn')\n    fig, axs = plt.subplots(1, 3, figsize=((15, 5)))\n    frames = {f'Video {key}': value['frames_count'] for key, value in video_data.items()}\n    axs[0].bar(frames.keys(), frames.values(), width=0.3)\n    axs[0].set_ylabel('frames')\n    axs[0].set_title('Frames count per video')\n    seq = {f'Video {key}': len(value['sequence']) for key, value in video_data.items()}\n    axs[1].bar(seq.keys(), seq.values(), width=0.3)\n    axs[1].set_ylabel('sequences')\n    axs[1].set_title('Sequences count per video')\n    annot = {f'Video {key}': value['frames_with_annot_count'] for key, value in video_data.items()}\n    axs[2].bar(annot.keys(), annot.values(), width=0.3)\n    axs[2].set_ylabel('annotations')\n    axs[2].set_title('Annotations count per video')\n\n\nplot_video_data(video_data)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:39.770227Z","iopub.execute_input":"2022-02-25T17:58:39.770577Z","iopub.status.idle":"2022-02-25T17:58:40.469290Z","shell.execute_reply.started":"2022-02-25T17:58:39.770540Z","shell.execute_reply":"2022-02-25T17:58:40.467846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_frame_data(video_data):\n    fig, axs = plt.subplots(1, len(video_data.keys()), figsize=((15, 5)))\n    for video_id in video_data.keys():\n        annot = {f'Seq. {key}': value['frames_with_annot_count'] for key, value in video_data[video_id]['sequence'].items()}\n        no_annot = {f'Seq. {key}': value['frames_count'] - value['frames_with_annot_count'] for key, value in video_data[video_id]['sequence'].items()}\n        width = 0.5 * len(annot) / 8\n        axs[video_id].bar(annot.keys(), annot.values(), width=width, label='annotation(s)')\n        axs[video_id].bar(no_annot.keys(), no_annot.values(), width=width, label='no annotation', bottom=list(annot.values()))\n        axs[video_id].set_ylabel('frames')\n        axs[video_id].tick_params(axis='x', labelrotation=90)\n        axs[video_id].set_title(f'Video {video_id} : annotations count per sequence')\n        axs[video_id].legend()\n\n\nplot_frame_data(video_data)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:40.471692Z","iopub.execute_input":"2022-02-25T17:58:40.472039Z","iopub.status.idle":"2022-02-25T17:58:41.392990Z","shell.execute_reply.started":"2022-02-25T17:58:40.472000Z","shell.execute_reply":"2022-02-25T17:58:41.391973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_annotation_count(df_train):\n    df_train = df_train.sort_values(by=['video_id', 'sequence', 'sequence_frame'])\n    df_train['annots_count'] = df_train['annotations'].apply(lambda annots: len(eval(annots)))\n    return df_train\n\n\ndf_train = get_annotation_count(df_train)\ndf_annot = df_train['annots_count'].value_counts()\n\n\ndef plot_annot_distrib(df_annot):\n    fig, ax = plt.subplots(1, 1, figsize=(8, 5))\n    ax.bar(df_annot.index, df_annot, tick_label=df_annot.index)\n    ax.set_ylabel('frames')\n    ax.set_xlabel('annotation count per frame')\n\n\nplot_annot_distrib(df_annot)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:41.397145Z","iopub.execute_input":"2022-02-25T17:58:41.397387Z","iopub.status.idle":"2022-02-25T17:58:42.491036Z","shell.execute_reply.started":"2022-02-25T17:58:41.397359Z","shell.execute_reply":"2022-02-25T17:58:42.489960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_annotation_time(df_train):\n    annot_data = {}\n    for video_id in df_train['video_id'].unique():\n        df_video = df_train.loc[df_train['video_id'] == video_id]\n        annot_data[video_id] = {}\n        for sequence in df_video['sequence'].unique():\n            df_annot_time = df_video.loc[df_video['sequence'] == sequence]\n            df_annot_time = df_annot_time.sort_values(by='sequence_frame')['annots_count']\n            annot_data[video_id][sequence] = df_annot_time.values\n    return annot_data\n\n\nannotation_time = get_annotation_time(df_train)\n\n\ndef plot_annotation_time(annotation_time):\n    for video_id, sequences in annotation_time.items():\n        for sequence, annot in sequences.items():\n            fig, ax = plt.subplots(1, 1, figsize=(15, 2))\n            ax.plot(annot)\n            ax.set_ylabel('annotation count')\n            ax.set_xlabel('time (frame)')\n            ax.set_title(f'Video {video_id}, sequence : {sequence}')\n\n\nplot_annotation_time(annotation_time)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:42.494148Z","iopub.execute_input":"2022-02-25T17:58:42.495011Z","iopub.status.idle":"2022-02-25T17:58:46.918913Z","shell.execute_reply.started":"2022-02-25T17:58:42.494954Z","shell.execute_reply":"2022-02-25T17:58:46.917645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_annotation_pos_and_size(df_train):\n    annot_data = {}\n    for video_id in df_train['video_id'].unique():\n        df_video = df_train.loc[df_train['video_id'] == video_id]\n        annot_data[video_id] = {}\n        for sequence in df_video['sequence'].unique():\n            annots = []\n            df_annot_time = df_video.loc[df_video['sequence'] == sequence]\n            raw_annots = df_annot_time['annotations'].apply(lambda annots: eval(annots)).values\n            annots = [annot for sublist in raw_annots for annot in sublist]\n            annots = [list(annot.values()) for annot in annots]\n            annots = np.array(annots)\n            annot_data[video_id][sequence] = annots\n    return annot_data\n\n\nannotation_pos_and_size = get_annotation_pos_and_size(df_train)\n\n\ndef plot_annotation_pos(annotation_pos_and_size):\n    for video_id, sequences in annotation_pos_and_size.items():\n        for sequence, annot in sequences.items():\n            if annot.shape[0] != 0:\n                fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n                ax.scatter(annot[:, 0], annot[:, 1], alpha=0.5)\n                ax.set_ylabel('height')\n                ax.set_xlabel('width')\n                ax.set_xbound(0, SIZE[0])\n                ax.set_ybound(0, SIZE[1])\n                ax.set_title(f'Starfish position (video {video_id}, sequence: {sequence})')\n\n\ndef plot_annotation_size(annotation_pos_and_size):\n    fig, axs = plt.subplots(3, len(df_train['video_id'].unique()), figsize=(15, 15))\n    idx = 0\n    for video_id, sequences in annotation_pos_and_size.items():\n        width = []\n        height = []\n        ratio_wh = []\n        sequence_id = []\n        for sequence, annot in sequences.items():\n            if annot.shape[0] != 0:\n                sequence_id.append(sequence)\n                width.append(annot[:, 2])\n                height.append(annot[:, 3])\n                ratio_wh.append(annot[:, 2] / annot[:, 3])\n        # plot width\n        axs[0, idx].boxplot(width, labels=sequence_id)\n        axs[0, idx].set_ylabel('height')\n        axs[0, idx].tick_params(axis='x', labelrotation=90)\n        axs[0, idx].set_xlabel('sequence')\n        axs[0, idx].set_title(f'Bounding box width (video {video_id})')\n        # plot height\n        axs[1, idx].boxplot(height, labels=sequence_id)\n        axs[1, idx].set_ylabel('height')\n        axs[1, idx].tick_params(axis='x', labelrotation=90)\n        axs[1, idx].set_xlabel('sequence')\n        axs[1, idx].set_title(f'Bounding box height (video {video_id})')\n        # plot ratio width / height\n        axs[2, idx].boxplot(ratio_wh, labels=sequence_id)\n        axs[2, idx].set_ylabel('ratio')\n        axs[2, idx].tick_params(axis='x', labelrotation=90)\n        axs[2, idx].set_xlabel('sequence')\n        axs[2, idx].set_title(f'Bounding box ratio width / height (video {video_id})')\n        idx += 1\n    fig.tight_layout()\n\n\nplot_annotation_size(annotation_pos_and_size)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:46.921777Z","iopub.execute_input":"2022-02-25T17:58:46.922185Z","iopub.status.idle":"2022-02-25T17:58:50.000914Z","shell.execute_reply.started":"2022-02-25T17:58:46.922134Z","shell.execute_reply":"2022-02-25T17:58:49.999494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualisation ","metadata":{}},{"cell_type":"markdown","source":"#### On veut visualiser les images issues des vidéos, on va écrire une fonction pour nous permettre de visualiser une image et son histogramme.\n#### Comme nos images sont en couleur, on va passer d'abord par une représentation avec luminance et chrominance puis faire l'égalisation uniquement sur la luminance Y pour avoir un histogramme égalisée, et donc de meilleur qualité pour la visualisation","metadata":{}},{"cell_type":"code","source":"img_0 = plt.imread(data_path+\"/train_images/video_0/0.jpg\")\nplt.axis(\"off\")\nplt.imshow(img_0)\nplt.show()\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:50.003068Z","iopub.execute_input":"2022-02-25T17:58:50.003579Z","iopub.status.idle":"2022-02-25T17:58:50.559910Z","shell.execute_reply.started":"2022-02-25T17:58:50.003529Z","shell.execute_reply":"2022-02-25T17:58:50.558307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Histogram equalization","metadata":{}},{"cell_type":"code","source":"def Histogram_equalization(img):\n    f = plt.figure(figsize=(25, 25))\n    # original\n    ax1 = f.add_subplot(521)\n    plt.axis(\"off\")\n    ax2 = f.add_subplot(522)\n    ax1.imshow(img)\n    ax1.set_title('img')\n    ax2.hist(img.flatten(), bins=range(256), color='navy')\n    ax2.set_title('Original histogram')\n    # RGB\n    ax3 = f.add_subplot(523)\n    plt.axis(\"off\")\n    ax4 = f.add_subplot(524)\n    img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)\n    ax3.imshow(img_yuv)\n    ax3.set_title('img YUV')\n    plt.axis(\"off\")\n    ax4.hist(img_yuv.flatten(), bins=range(256), color='navy')\n    ax4.set_title('Histogram img YUV')\n    # YUV\n    ax5 = f.add_subplot(525)\n    plt.axis(\"off\")\n    ax6 = f.add_subplot(526)\n    img_yuv[:, :, 0] = cv2.equalizeHist(img_yuv[:, :, 0])\n    img_output = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)\n    ax5.imshow(img_output)\n    ax5.set_title('img equalized')\n    ax6.hist(img_output.flatten(), bins=range(256), color='navy')\n    ax6.set_title('Histograme qualized')\n\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:50.562793Z","iopub.execute_input":"2022-02-25T17:58:50.563194Z","iopub.status.idle":"2022-02-25T17:58:50.775373Z","shell.execute_reply.started":"2022-02-25T17:58:50.563144Z","shell.execute_reply":"2022-02-25T17:58:50.774260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Histogram_equalization(img_0)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:50.777867Z","iopub.execute_input":"2022-02-25T17:58:50.778216Z","iopub.status.idle":"2022-02-25T17:58:54.402661Z","shell.execute_reply.started":"2022-02-25T17:58:50.778171Z","shell.execute_reply":"2022-02-25T17:58:54.401650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# img_bgr = cv2.cvtColor(img_0,cv2.COLOR_BGR2RGB)\nplt.axis(\"off\")\nimg_yuv = cv2.cvtColor(img_0, cv2.COLOR_BGR2YUV)\nimg_yuv[:, :, 0] = cv2.equalizeHist(img_yuv[:, :, 0])\nimg_output = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)\nplt.imshow(img_output)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:54.404327Z","iopub.execute_input":"2022-02-25T17:58:54.404605Z","iopub.status.idle":"2022-02-25T17:58:54.985783Z","shell.execute_reply.started":"2022-02-25T17:58:54.404572Z","shell.execute_reply":"2022-02-25T17:58:54.984464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Filter","metadata":{}},{"cell_type":"code","source":"''' Appliquer le non-local means filter sur l'image test 0\npour essayer d'améliorer l'image'''\nimg_flt = cv2.fastNlMeansDenoisingColored(src=img_0, dst=None, h=10, hColor=10, templateWindowSize=7, searchWindowSize=21)\nfig = plt.figure(figsize=(16, 6))\nplt.subplot(1, 2, 1)\nplt.imshow(img_0)\nplt.title(\"frame\")\nplt.axis(\"off\")\nplt.subplot(1, 2, 2)\nplt.imshow(img_flt)\nplt.title(\"img filter\")\nplt.axis(\"off\")\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:54.987967Z","iopub.execute_input":"2022-02-25T17:58:54.988607Z","iopub.status.idle":"2022-02-25T17:58:57.252626Z","shell.execute_reply.started":"2022-02-25T17:58:54.988564Z","shell.execute_reply":"2022-02-25T17:58:57.251787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_sample_frames(df_train):\n    samples = []\n    for video_id in df_train['video_id'].unique():\n        df_video = df_train.loc[df_train['video_id'] == video_id]\n        for sequence in df_video['sequence'].unique():\n            df_sample = df_video.loc[df_video['sequence'] == sequence]\n            try:\n                df_sample = df_sample.loc[df_sample['annotations'] != '[]'].sample(1)\n            except:\n                df_sample = df_sample.sample(1)\n            samples.append(df_sample)\n    return samples\n\ndef process_frame(sample):\n    # frame\n    video_id = sample['video_id'].values[0]\n    frame = sample['video_frame'].values[0]\n    sequence = sample['sequence'].values[0]\n    img_path = os.path.join(data_path, 'train_images', f'video_{video_id}', f'{frame}.jpg')\n    frame = np.array(Image.open(img_path))\n    # bounding boxes\n    try:\n        bboxs = eval(sample['annotations'].values[0])\n        bboxs = [list(values.values()) for values in bboxs]\n        bboxs = np.array(bboxs)\n    except: # no bounding box in sequence\n        bboxs = None\n    return frame, bboxs, video_id, sequence\n\ndef display_frame(frame, bboxs, video_id, sequence):\n    plt.style.use('seaborn-dark')\n    fig, ax = plt.subplots(1, 1, figsize=(12, 8))\n    # frame\n    ax.imshow(frame)\n    ax.set_ylabel('height')\n    ax.set_xlabel('width')\n    ax.set_xbound(0, SIZE[0])\n    ax.set_ybound(0, SIZE[1])\n    ax.set_title(f'Frame sample from video {video_id}, sequence : {sequence}')\n    # bounding boxes\n    for bbox in bboxs:\n        rect = patches.Rectangle((bbox[0], bbox[1]), bbox[2], bbox[3], linewidth=3, edgecolor='r', facecolor='none')\n        ax.add_patch(rect)\n    return\n\nsample_frames = get_sample_frames(df_train)\n\nfor sample in sample_frames:\n    frame, bboxs, video_id, sequence = process_frame(sample)\n    display_frame(frame, bboxs, video_id, sequence)\n","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:58:57.254665Z","iopub.execute_input":"2022-02-25T17:58:57.255306Z","iopub.status.idle":"2022-02-25T17:59:10.105336Z","shell.execute_reply.started":"2022-02-25T17:58:57.255262Z","shell.execute_reply":"2022-02-25T17:59:10.104455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image, ImageDraw\n\ndef fetch_image_list(df_tmp, video_id, num_images, start_frame_idx):\n    def fetch_image(frame_id):\n        path_base = '/kaggle/input/tensorflow-great-barrier-reef/train_images/video_{}/{}.jpg'\n        raw_img = Image.open(path_base.format(video_id, frame_id))\n\n        row_frame = df_tmp[(df_tmp.video_id == video_id) & (df_tmp.video_frame == frame_id)].iloc[0]\n        bounding_boxes = ast.literal_eval(row_frame.annotations)\n\n        for box in bounding_boxes:\n            draw = ImageDraw.Draw(raw_img)\n            x0, y0, x1, y1 = (box['x'], box['y'], box['x']+box['width'], box['y']+box['height'])\n            draw.rectangle( (x0, y0, x1, y1), outline=180, width=3)\n        return raw_img\n\n    return [np.array(fetch_image(start_frame_idx + index)) for index in range(num_images)]\n\nimages = fetch_image_list(df_train, video_id = 0, num_images = 80, start_frame_idx = 25)\n\nprint(\"Num images: \", len(images))\nplt.imshow(images[0], interpolation='nearest')\nplt.axis('off')\nplt.show()\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:10.106754Z","iopub.execute_input":"2022-02-25T17:59:10.107019Z","iopub.status.idle":"2022-02-25T17:59:14.965142Z","shell.execute_reply.started":"2022-02-25T17:59:10.106986Z","shell.execute_reply":"2022-02-25T17:59:14.964061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Vidéos avec annotations ","metadata":{}},{"cell_type":"code","source":"def add_annotations(img, annotations, color=\"red\", thickness=3):\n    \"\"\"\n    Adds annotations to an image using cv2.\n\n    annotations: [list] of dictionaries with the annoation details\n    \"\"\"\n    if color == \"red\":\n        box_color = (0, 0, 255)  # Red\n    elif color == \"black\":\n        box_color = (0, 0, 0)  # Black\n    for a in annotations:\n        cv2.rectangle(\n            img,\n            (a[\"x\"], a[\"y\"]),\n            (a[\"x\"] + a[\"width\"], a[\"y\"] + a[\"height\"]),\n            box_color,\n            thickness=thickness,\n        )\n\n    return img\n\n\ndef create_reef_video(\n    train,\n    video_id,\n    start_video_frame,\n    end_video_frame,\n    annotate=True,\n    output_filename=\"./test.mp4\",\n    FPS=30,\n    image_dir=\"../input/tensorflow-great-barrier-reef/train_images/\",\n):\n\n    width = 1280\n    height = 720\n\n    fourcc = VideoWriter_fourcc(*\"mp4v\")\n\n    temp_fn = output_filename.replace(\".mp4\", \"\") + \"_temp.mp4\"\n\n    video_file = VideoWriter(temp_fn, fourcc, float(FPS), (width, height))\n\n    subset_df = (\n        train.query(\n            \"video_id == @video_id and video_frame >= @start_video_frame and video_frame <= @end_video_frame\"\n        )\n        .reset_index(drop=True)\n        .copy()\n    )\n    for i, example in tqdm(subset_df.iterrows(), total=len(subset_df)):\n        video = example[\"video_id\"]\n        frame = example[\"video_frame\"]\n        image_fn = f\"{image_dir}video_{video}/{frame}.jpg\"\n        img = cv2.imread(image_fn)\n        if annotate:\n            annotations = eval(example[\"annotations\"])\n            img = add_annotations(img, annotations)\n        video_file.write(img)\n\n    video_file.release()\n\n    subprocess.run(\n        [\n            \"ffmpeg\",\n            \"-i\",\n            temp_fn,\n            \"-crf\",\n            \"18\",\n            \"-preset\",\n            \"veryfast\",\n            \"-vcodec\",\n            \"libx264\",\n            output_filename,\n            \"-loglevel\",\n            \"error\",\n        ]\n    )\n\n    os.remove(temp_fn)\n\n    return output_filename\n\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:14.967002Z","iopub.execute_input":"2022-02-25T17:59:14.967243Z","iopub.status.idle":"2022-02-25T17:59:15.206244Z","shell.execute_reply.started":"2022-02-25T17:59:14.967214Z","shell.execute_reply":"2022-02-25T17:59:15.205066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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\")\nss = pd.read_csv(\"../input/tensorflow-great-barrier-reef/example_sample_submission.csv\")\n\ntrain.shape, test.shape\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:15.207980Z","iopub.execute_input":"2022-02-25T17:59:15.208272Z","iopub.status.idle":"2022-02-25T17:59:15.489834Z","shell.execute_reply.started":"2022-02-25T17:59:15.208234Z","shell.execute_reply":"2022-02-25T17:59:15.488855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from cv2 import VideoWriter, VideoWriter_fourcc\nimport subprocess\nfrom IPython.display import Video\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:15.493678Z","iopub.execute_input":"2022-02-25T17:59:15.494097Z","iopub.status.idle":"2022-02-25T17:59:15.707159Z","shell.execute_reply.started":"2022-02-25T17:59:15.494062Z","shell.execute_reply":"2022-02-25T17:59:15.706210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_reef_video(\n    train,\n    output_filename=\"example-1.mp4\",\n    annotate=True,\n    video_id=1,\n    start_video_frame=9090,\n    end_video_frame=9172,\n)\nVideo(\"example-1.mp4\", width=800)\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:15.708661Z","iopub.execute_input":"2022-02-25T17:59:15.708937Z","iopub.status.idle":"2022-02-25T17:59:20.347018Z","shell.execute_reply.started":"2022-02-25T17:59:15.708909Z","shell.execute_reply":"2022-02-25T17:59:20.345635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_reef_video(\n    train,\n    output_filename=\"example-2.mp4\",\n    annotate=True,\n    video_id=2,\n    start_video_frame=5600,\n    end_video_frame=5800,\n)\nVideo(\"example-2.mp4\", width=900)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:20.349230Z","iopub.execute_input":"2022-02-25T17:59:20.350196Z","iopub.status.idle":"2022-02-25T17:59:29.811514Z","shell.execute_reply.started":"2022-02-25T17:59:20.350150Z","shell.execute_reply":"2022-02-25T17:59:29.810451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_reef_video(\n    train,\n    output_filename=\"example-3.mp4\",\n    annotate=True,\n    video_id=0,\n    start_video_frame=4500,\n    end_video_frame=4700,\n)\nVideo(\"example-3.mp4\", width=900)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:29.813467Z","iopub.execute_input":"2022-02-25T17:59:29.814413Z","iopub.status.idle":"2022-02-25T17:59:38.204212Z","shell.execute_reply.started":"2022-02-25T17:59:29.814363Z","shell.execute_reply":"2022-02-25T17:59:38.203434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## F2-score","metadata":{}},{"cell_type":"markdown","source":" #### La métrique de la compétition est le f2-score dont la formule est: $$F2 = 5 \\cdot \\frac{precision \\cdot recall}{4\\cdot precision + recall}$$\n #### L'objectif avec un tel score est de discriminer les faux positifs par rapport aux faux négatifs, il est en effet plus important dans ce problème de détecter un COTS que de ne pas le détecter ou de détecter faux COTS.\n #### Le score F1 est la moyenne harmonique entre la précision et le rappel : $$F1 = 2 \\cdot \\frac{precision \\cdot recall}{precision + recall}$$\n ","metadata":{}},{"cell_type":"code","source":"''' De petits exemples pour comprendre le f2-score et\npourquoi il est meilleur dans le cas où on cherche\navant tout à préviligier les faux négatifs vis à vis des faux positifs\navec comparaison avec le F-0.5 et F-1 score'''\nfrom sklearn.metrics import fbeta_score\nfrom sklearn.metrics import f1_score\nfrom sklearn.metrics import precision_score\nfrom sklearn.metrics import recall_score\n\n\ndef compare_f_score(y_true, y_pred):\n    p = precision_score(y_true, y_pred)\n    r = recall_score(y_true, y_pred)\n    f05 = round(fbeta_score(y_true, y_pred, beta=0.5), 4)\n    f1 = round(f1_score(y_true, y_pred), 4)\n    f2 = round(fbeta_score(y_true, y_pred, beta=2.0), 4)\n    return [p, r, f05, f1, f2]\n\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:38.206254Z","iopub.execute_input":"2022-02-25T17:59:38.206770Z","iopub.status.idle":"2022-02-25T17:59:38.435657Z","shell.execute_reply.started":"2022-02-25T17:59:38.206722Z","shell.execute_reply":"2022-02-25T17:59:38.434559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\n# Confusion Matrix\ndef cf_matrix(y_true, y_pred):\n    cf_matrix = confusion_matrix(y_true, y_pred)\n    fig = plt.figure(figsize=(15,6))\n    plt.subplot(121)\n    ax = sns.heatmap(cf_matrix, annot=True)\n    ax.set_xlabel(\"Predicted labels\", color=\"g\")\n    ax.set_ylabel(\"True labels\", color=\"navy\")\n    plt.title(\"Matrice de confusion\", fontsize=18)\n    \n    plt.subplot(122)\n    y=compare_f_score(y_true,y_pred)\n    sns.barplot(x, y)\n    \n    \n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:38.437782Z","iopub.execute_input":"2022-02-25T17:59:38.438072Z","iopub.status.idle":"2022-02-25T17:59:38.450525Z","shell.execute_reply.started":"2022-02-25T17:59:38.438039Z","shell.execute_reply":"2022-02-25T17:59:38.448755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x=['p','r','f05','f1','f2']","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:38.453141Z","iopub.execute_input":"2022-02-25T17:59:38.453923Z","iopub.status.idle":"2022-02-25T17:59:38.468498Z","shell.execute_reply.started":"2022-02-25T17:59:38.453864Z","shell.execute_reply":"2022-02-25T17:59:38.467578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# exemple 1\ny_true = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]\ny_pred = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\ncf_matrix(y_true, y_pred)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:38.469897Z","iopub.execute_input":"2022-02-25T17:59:38.470787Z","iopub.status.idle":"2022-02-25T17:59:39.054038Z","shell.execute_reply.started":"2022-02-25T17:59:38.470739Z","shell.execute_reply":"2022-02-25T17:59:39.052399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# exemple 2\ny_true = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]\ny_pred = [1, 0, 0, 0, 0, 0, 0, 1, 1, 1]\ncf_matrix(y_true, y_pred)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:39.058226Z","iopub.execute_input":"2022-02-25T17:59:39.059906Z","iopub.status.idle":"2022-02-25T17:59:39.667438Z","shell.execute_reply.started":"2022-02-25T17:59:39.059828Z","shell.execute_reply":"2022-02-25T17:59:39.666063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# exemple 3\ny_true = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]\ny_pred = [1, 1, 1, 1, 0, 0, 0, 1, 1, 1]\ncf_matrix(y_true, y_pred)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:39.669321Z","iopub.execute_input":"2022-02-25T17:59:39.670041Z","iopub.status.idle":"2022-02-25T17:59:40.267120Z","shell.execute_reply.started":"2022-02-25T17:59:39.669989Z","shell.execute_reply":"2022-02-25T17:59:40.266122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# exemple 4\ny_true = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]\ny_pred = [1, 1, 1, 1, 0, 1, 1, 1, 1, 1]\ncf_matrix(y_true, y_pred)\n\npep8(_ih)","metadata":{"execution":{"iopub.status.busy":"2022-02-25T17:59:40.268946Z","iopub.execute_input":"2022-02-25T17:59:40.269373Z","iopub.status.idle":"2022-02-25T17:59:40.836628Z","shell.execute_reply.started":"2022-02-25T17:59:40.269339Z","shell.execute_reply":"2022-02-25T17:59:40.835688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}