{"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":"# **Introduction**\nThis notebook is my notebook for [TensorFlow - Help Protect the Great Barrier Reef](https://www.kaggle.com/competitions/tensorflow-great-barrier-reef) which is aim for developing computer vision program for real-time Crown-of-Thorns Starfish(cots) detection.\n\nThis is my first time attempt object detection task and can only achieve basic procedure. I whoul like to give my gratitude to this notebook- [🐡GreatBarrierReef: YOLO Full Guide [train+infer]](https://www.kaggle.com/code/andradaolteanu/greatbarrierreef-yolo-full-guide-train-infer)- without this guide I could never done this notebook.\nt\nThis notebook is about data preparation and training the models.","metadata":{}},{"cell_type":"code","source":"import os\nimport wandb\nimport sys\nimport time\nimport random\nimport shutil\nimport yaml\nfrom tqdm import tqdm\ntqdm.pandas()\nimport warnings\nimport cv2\nimport pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nfrom IPython.display import display_html\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:31.729292Z","iopub.execute_input":"2022-04-18T14:31:31.729817Z","iopub.status.idle":"2022-04-18T14:31:31.740214Z","shell.execute_reply.started":"2022-04-18T14:31:31.729776Z","shell.execute_reply":"2022-04-18T14:31:31.739522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# output = cv2.seamlessClone(src, dst, mask, center, flags)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:31.743252Z","iopub.execute_input":"2022-04-18T14:31:31.744383Z","iopub.status.idle":"2022-04-18T14:31:31.751797Z","shell.execute_reply.started":"2022-04-18T14:31:31.744344Z","shell.execute_reply":"2022-04-18T14:31:31.751027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Environment Check\nwarnings.filterwarnings('ignore')\nos.environ['WANDB_SILENT'] = 'true'\n\nCONFIG = {'competition' : 'greatReef', '_wandb_kernel': 'aot'}\n\n# Secrets\nfrom kaggle_secrets import UserSecretsClient\nuser_secret = UserSecretsClient()\nsecret_value_0 = user_secret.get_secret('wandb')\n\n! wandb login $secret_value_0\n\nclass color:\n    S = '\\033[1m' + '\\033[94m'\n    E = '\\033[0m'\n    \nmy_colors = [\"#16558F\", \"#1583D2\", \"#61B0B7\", \"#ADDEFF\", \"#A99AEA\", \"#7158B7\"]  \nprint(color.S+'Notebook Color Scheme:'+color.E)\nsns.palplot(sns.color_palette(my_colors))\n\nprint(color.S+'Current Directory'+color.E, os.getcwd)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:31.758006Z","iopub.execute_input":"2022-04-18T14:31:31.758218Z","iopub.status.idle":"2022-04-18T14:31:34.394853Z","shell.execute_reply.started":"2022-04-18T14:31:31.758175Z","shell.execute_reply":"2022-04-18T14:31:34.394106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Working Directory\nprint(color.S+\"-Directory Structure-\"+color.E)\nprint(color.S+\"Before:\"+color.E, os.listdir(\"../\"))\n\n# Create 2 new folders\n!mkdir -p '../images'\n!mkdir -p '../labels'\n\nprint(color.S+\"After:\"+color.E, os.listdir(\"../\"))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:34.396804Z","iopub.execute_input":"2022-04-18T14:31:34.397077Z","iopub.status.idle":"2022-04-18T14:31:35.760623Z","shell.execute_reply.started":"2022-04-18T14:31:34.397038Z","shell.execute_reply":"2022-04-18T14:31:35.759841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FOLD = 4 #training fold\nDIM = 1280\nMODEL = 'yolov5m'\nBATCH = 8\nEPOCH = 25\n\nPROJECT = 'REEF2'\nNAME = f'{MODEL}-dim{DIM}-fold{FOLD}'\n\nREMOVE_NOBBOX = True\nROOT_DIR = '/kaggle/input/tensorflow-great-barrier-reef'\nIMAGE_DIR = '/kaggle/images'\nLABEL_DIR = '/kaggle/labels'","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:35.762513Z","iopub.execute_input":"2022-04-18T14:31:35.762791Z","iopub.status.idle":"2022-04-18T14:31:35.768901Z","shell.execute_reply.started":"2022-04-18T14:31:35.762752Z","shell.execute_reply":"2022-04-18T14:31:35.767807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# W&B Experiment\nrun = wandb.init(project=PROJECT, name='DataUnderstanding', config=CONFIG, anonymous=\"allow\")\n\ntrain = pd.read_csv(f'{ROOT_DIR}/train.csv')\ntest = pd.read_csv(f'{ROOT_DIR}/test.csv')","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:35.771702Z","iopub.execute_input":"2022-04-18T14:31:35.772481Z","iopub.status.idle":"2022-04-18T14:31:46.055296Z","shell.execute_reply.started":"2022-04-18T14:31:35.77244Z","shell.execute_reply":"2022-04-18T14:31:46.054413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_values_on_bars(axs, h_v=\"v\", space=0.4):\n    '''Plots the value at the end of the a seaborn barplot.\n    axs: the ax of the plot\n    h_v: weather or not the barplot is vertical/ horizontal'''\n    \n    def _show_on_single_plot(ax):\n        if h_v == \"v\":\n            for p in ax.patches:\n                _x = p.get_x() + p.get_width() / 2\n                _y = p.get_y() + p.get_height()\n                value = int(p.get_height())\n                ax.text(_x, _y, format(value, ','), ha=\"center\") \n        elif h_v == \"h\":\n            for p in ax.patches:\n                _x = p.get_x() + p.get_width() + float(space)\n                _y = p.get_y() + p.get_height()\n                value = int(p.get_width())\n                ax.text(_x, _y, format(value, ','), ha=\"left\")\n\n    if isinstance(axs, np.ndarray):\n        for idx, ax in np.ndenumerate(axs):\n            _show_on_single_plot(ax)\n    else:\n        _show_on_single_plot(axs)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.056917Z","iopub.execute_input":"2022-04-18T14:31:46.057175Z","iopub.status.idle":"2022-04-18T14:31:46.065697Z","shell.execute_reply.started":"2022-04-18T14:31:46.057138Z","shell.execute_reply":"2022-04-18T14:31:46.064763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1, ax2)) = plt.subplots(nrows=1, ncols=2, figsize=(23, 10))\n\n#plot 1\ndf1 = train['video_id'].value_counts().reset_index()\n\nsns.barplot(data=df1, x='index', y='video_id', ax = ax1,palette=my_colors)\nshow_values_on_bars(ax1, h_v='v',space=0.1)\nax1.set_xlabel(\"Video ID\")\nax1.set_ylabel(\"\")\nax1.title.set_text(\"Frequency of Frames per Video\")\nax1.set_yticks([])\n\n# Plot 2\n\ndf2 = train['sequence'].value_counts().reset_index()\n\nsns.barplot(data=df2, x='index', y='sequence', ax=ax2, orient ='h', palette='BuPu_r')\nshow_values_on_bars(ax2, h_v=\"h\", space=0.1)\nax2.set_xlabel(\"\")\nax2.set_ylabel(\"Sequence ID\")\nax2.title.set_text(\"Frequency of Frames per Sequence\")\nax2.set_xticks([])\n\nsns.despine(top=True, bottom=True, left=True, right=True, ax=ax1)\nsns.despine(top=True, right=True, left=True, bottom=True, ax=ax2)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.066941Z","iopub.execute_input":"2022-04-18T14:31:46.067611Z","iopub.status.idle":"2022-04-18T14:31:46.516718Z","shell.execute_reply.started":"2022-04-18T14:31:46.067574Z","shell.execute_reply":"2022-04-18T14:31:46.516031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_values_on_bars(axs, h_v=\"v\", space=0.4):\n    '''Plots the value at the end of the a seaborn barplot.\n    axs: the ax of the plot\n    h_v: weather or not the barplot is vertical/ horizontal'''\n    \n    def _show_on_single_plot(ax):\n        if h_v == \"v\":\n            for p in ax.patches:\n                _x = p.get_x() + p.get_width() / 2\n                _y = p.get_y() + p.get_height()\n                value = int(p.get_height())\n                ax.text(_x, _y, format(value, ','), ha=\"center\") \n        elif h_v == \"h\":\n            for p in ax.patches:\n                _x = p.get_x() + p.get_width() + float(space)\n                _y = p.get_y() + p.get_height()\n                value = int(p.get_width())\n                ax.text(_x, _y, format(value, ','), ha=\"left\")\n\n    if isinstance(axs, np.ndarray):\n        for idx, ax in np.ndenumerate(axs):\n            _show_on_single_plot(ax)\n    else:\n        _show_on_single_plot(axs)\n    \n    \n# === 🐝 W&B ===\ndef save_dataset_artifact(run_name, artifact_name, path):\n    '''Saves dataset to W&B Artifactory.\n    run_name: name of the experiment\n    artifact_name: under what name should the dataset be stored\n    path: path to the dataset'''\n    \n    run = wandb.init(project='g2net', \n                     name=run_name, \n                     config=CONFIG, anonymous=\"allow\")\n    artifact = wandb.Artifact(name=artifact_name, \n                              type='dataset')\n    artifact.add_file(path)\n\n    wandb.log_artifact(artifact)\n    wandb.finish()\n    print(\"Artifact has been saved successfully.\")\n    \n    \ndef create_wandb_plot(x_data=None, y_data=None, x_name=None, y_name=None, title=None, log=None, plot=\"line\"):\n    '''Create and save lineplot/barplot in W&B Environment.\n    x_data & y_data: Pandas Series containing x & y data\n    x_name & y_name: strings containing axis names\n    title: title of the graph\n    log: string containing name of log'''\n    \n    data = [[label, val] for (label, val) in zip(x_data, y_data)]\n    table = wandb.Table(data=data, columns = [x_name, y_name])\n    \n    if plot == \"line\":\n        wandb.log({log : wandb.plot.line(table, x_name, y_name, title=title)})\n    elif plot == \"bar\":\n        wandb.log({log : wandb.plot.bar(table, x_name, y_name, title=title)})\n    elif plot == \"scatter\":\n        wandb.log({log : wandb.plot.scatter(table, x_name, y_name, title=title)})\n        \n        \ndef create_wandb_hist(x_data=None, x_name=None, title=None, log=None):\n    '''Create and save histogram in W&B Environment.\n    x_data: Pandas Series containing x values\n    x_name: strings containing axis name\n    title: title of the graph\n    log: string containing name of log'''\n    \n    data = [[x] for x in x_data]\n    table = wandb.Table(data=data, columns=[x_name])\n    wandb.log({log : wandb.plot.histogram(table, x_name, title=title)})","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.518045Z","iopub.execute_input":"2022-04-18T14:31:46.518646Z","iopub.status.idle":"2022-04-18T14:31:46.535875Z","shell.execute_reply.started":"2022-04-18T14:31:46.518605Z","shell.execute_reply":"2022-04-18T14:31:46.534889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of Annotations\ntrain['no_annotations'] = train['annotations'].apply(lambda x: len(eval(x)))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.537421Z","iopub.execute_input":"2022-04-18T14:31:46.537777Z","iopub.status.idle":"2022-04-18T14:31:46.753237Z","shell.execute_reply.started":"2022-04-18T14:31:46.537635Z","shell.execute_reply":"2022-04-18T14:31:46.752425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.754537Z","iopub.execute_input":"2022-04-18T14:31:46.754799Z","iopub.status.idle":"2022-04-18T14:31:46.765298Z","shell.execute_reply.started":"2022-04-18T14:31:46.754763Z","shell.execute_reply":"2022-04-18T14:31:46.764501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 🐝 Log plots into W&B Dashboard\ncreate_wandb_plot(x_data=df1.index, \n                  y_data=df1.video_id, \n                  x_name=\"Video ID\", y_name=\" \", \n                  title=\"-Frequency of Frames per Video-\", \n                  log=\"frames\", plot=\"bar\")\n\ncreate_wandb_plot(x_data=df2.index, \n                  y_data=df2.sequence, \n                  x_name=\"Sequence ID\", y_name=\" \", \n                  title=\"-Frequency of Frames per Sequence-\", \n                  log=\"frames2\", plot=\"bar\")","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:46.769172Z","iopub.execute_input":"2022-04-18T14:31:46.769742Z","iopub.status.idle":"2022-04-18T14:31:47.63796Z","shell.execute_reply.started":"2022-04-18T14:31:46.769692Z","shell.execute_reply":"2022-04-18T14:31:47.637241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# % annotations\nn = len(train)\nno_annot = round(train[train[\"no_annotations\"]==0].shape[0]/n*100)\nwith_annot = round(train[train[\"no_annotations\"]>0].shape[0]/n*100)\n\nprint(color.S + f\"There are ~{no_annot}% frames with no annotation and\" + color.E,\n      \"\\n\",\n      color.S + f\"only ~{with_annot}% frames with at least 1 annotation.\" + color.E)\n\n# Plot\nplt.figure(figsize=(23, 6))\nsns.histplot(train[\"no_annotations\"], bins=19, kde=True, element=\"step\", \n             color=my_colors[5])\n\nplt.xlabel(\"Number of Annotations\")\nplt.ylabel(\"Frequency\")\nplt.title(\"Distribution for Number of Annotations per Frame\")\n\nsns.despine(top=True, right=True, left=False, bottom=True)\n\nn = len(train)\nno_annot = round(train[train.no_annotations==0].shape[0]/n*100)\nwith_annot = round(train[train.no_annotations!=0].shape[0]/n*100)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:47.642313Z","iopub.execute_input":"2022-04-18T14:31:47.644264Z","iopub.status.idle":"2022-04-18T14:31:48.276644Z","shell.execute_reply.started":"2022-04-18T14:31:47.644222Z","shell.execute_reply":"2022-04-18T14:31:48.27597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = train[train[\"no_annotations\"]>0].reset_index(drop=True)\n\ntrain.sample(3, random_state=24)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:48.278036Z","iopub.execute_input":"2022-04-18T14:31:48.278306Z","iopub.status.idle":"2022-04-18T14:31:48.292747Z","shell.execute_reply.started":"2022-04-18T14:31:48.278271Z","shell.execute_reply":"2022-04-18T14:31:48.291708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(train.annotations[0][0])","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:48.293859Z","iopub.execute_input":"2022-04-18T14:31:48.294192Z","iopub.status.idle":"2022-04-18T14:31:48.305469Z","shell.execute_reply.started":"2022-04-18T14:31:48.294154Z","shell.execute_reply":"2022-04-18T14:31:48.304741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sequence of Annotations\nsequences = list(train['sequence'].unique())\n\nplt.figure(figsize =(23,20))\nplt.subplots_adjust(left=None, right=None, top=None, bottom=None, wspace=0.2, hspace=0.5)\nplt.suptitle('Frequency of annotations on sequence length', fontsize=20)\n\n# Enumerate through all sequences\nfor k, sequence in enumerate(sequences):\n    train[train['sequence'] == sequence]\n    df_seq = train[train['sequence'] == sequence]\n    \n    plt.subplot(5, 4, k+1)\n    plt.title(f\"Sequence: {sequence}\", fontsize = 12)\n    plt.xlabel(\"Seq Frame\", fontsize=10)\n    plt.ylabel(\"No. Annot\", fontsize=10)\n    plt.xticks(fontsize=10); plt.yticks(fontsize=10)\n    sns.lineplot(x=df_seq[\"sequence_frame\"], y=df_seq[\"no_annotations\"],\n                 color=my_colors[2], lw=3)\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:48.306858Z","iopub.execute_input":"2022-04-18T14:31:48.307241Z","iopub.status.idle":"2022-04-18T14:31:51.283753Z","shell.execute_reply.started":"2022-04-18T14:31:48.30719Z","shell.execute_reply":"2022-04-18T14:31:51.283035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:51.285192Z","iopub.execute_input":"2022-04-18T14:31:51.285663Z","iopub.status.idle":"2022-04-18T14:31:51.2983Z","shell.execute_reply.started":"2022-04-18T14:31:51.285626Z","shell.execute_reply":"2022-04-18T14:31:51.297333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wandb.finish()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:51.299792Z","iopub.execute_input":"2022-04-18T14:31:51.300072Z","iopub.status.idle":"2022-04-18T14:31:55.702052Z","shell.execute_reply.started":"2022-04-18T14:31:51.300036Z","shell.execute_reply":"2022-04-18T14:31:55.701261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# WandB Experiment\nrun = wandb.init(project=PROJECT, name='ExampleImages', config=CONFIG, anonymous='allow')\n\n# Create a path column\nbase_folder = f'{ROOT_DIR}/train_images'\n\ntrain['path'] = base_folder + '/video_' + train['video_id'].astype(str) +'/' + train['video_frame'].astype(str) + '.jpg'","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:31:55.705524Z","iopub.execute_input":"2022-04-18T14:31:55.70573Z","iopub.status.idle":"2022-04-18T14:32:02.00916Z","shell.execute_reply.started":"2022-04-18T14:31:55.705705Z","shell.execute_reply":"2022-04-18T14:32:02.008419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['path'][0]","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.011278Z","iopub.execute_input":"2022-04-18T14:32:02.011693Z","iopub.status.idle":"2022-04-18T14:32:02.02056Z","shell.execute_reply.started":"2022-04-18T14:32:02.011652Z","shell.execute_reply":"2022-04-18T14:32:02.019879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def format_annotations(x):\n    annotations = eval(x)\n    new_annotations = []\n    \n    if annotations:\n        for annot in annotations:\n            new_annotations.append([annot['x'],\n                                    annot['y'],\n                                    annot['x'] + annot['width'],\n                                    annot['y'] + annot['height'],\n                                   ])\n    \n    if new_annotations:\n        return str(new_annotations)\n    else:\n        return '[]'","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.023558Z","iopub.execute_input":"2022-04-18T14:32:02.024161Z","iopub.status.idle":"2022-04-18T14:32:02.030714Z","shell.execute_reply.started":"2022-04-18T14:32:02.024125Z","shell.execute_reply":"2022-04-18T14:32:02.030002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['f_annotations'] = train['annotations'].apply(lambda x: format_annotations(x))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.032005Z","iopub.execute_input":"2022-04-18T14:32:02.032643Z","iopub.status.idle":"2022-04-18T14:32:02.222747Z","shell.execute_reply.started":"2022-04-18T14:32:02.032605Z","shell.execute_reply":"2022-04-18T14:32:02.22209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.223897Z","iopub.execute_input":"2022-04-18T14:32:02.224158Z","iopub.status.idle":"2022-04-18T14:32:02.246395Z","shell.execute_reply.started":"2022-04-18T14:32:02.224125Z","shell.execute_reply":"2022-04-18T14:32:02.245736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_image_bbox(img, annot, axs=None):\n    if axs==None:\n        fig, axs = plt.subplots(figsize=(223,8))\n    \n    axs.imshow(img)\n    \n    if annot:\n        for a in annot:\n            rect = patches.Rectangle((a[0], a[1],), a[2]-a[0], a[3]-a[1],\n                                    linewidth=3, edgecolor='#FF6103', facecolor='none')\n            \n            axs.add_patch(rect)\n    axs.axis('off')","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.24761Z","iopub.execute_input":"2022-04-18T14:32:02.247828Z","iopub.status.idle":"2022-04-18T14:32:02.254567Z","shell.execute_reply.started":"2022-04-18T14:32:02.247797Z","shell.execute_reply":"2022-04-18T14:32:02.253558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random Horizontal Flip\nclass RandomHorizontalFlip(object):\n    \n    def __init__(self, p = 0.5):\n        self.p=p\n        \n    def __call__(self, img, bboxes):\n        bboxes = np.array(bboxes)\n        \n        img_center = np.array(img.shape[:2])[::-1]/2\n        img_center = np.hstack((img_center, img_center))\n        \n        if random.random() < self.p:\n            # Reverse image in the 1st dimension\n            img =img[:,::-1,:]\n            bboxes[:,[0,2]] +2*(img_center[[0,2]] - bboxes[:,[0,2]])\n            # Convert the bounding boxes\n            box_w = abs(bboxes[:,0] - bboxes[:,2])\n            bboxes[:,0] -= box_w\n            bboxes[:,2] += box_w\n        return img, bboxes.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.256131Z","iopub.execute_input":"2022-04-18T14:32:02.256685Z","iopub.status.idle":"2022-04-18T14:32:02.267143Z","shell.execute_reply.started":"2022-04-18T14:32:02.256647Z","shell.execute_reply":"2022-04-18T14:32:02.266503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Take an example\npath = list(train[train[\"no_annotations\"]==18][\"path\"])[0]\n\nimg_original = cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB)\nannot_original = eval(list(train[train[\"no_annotations\"]==18][\"f_annotations\"])[0])\n\n# Horizontal Flip\nhorizontal_flip = RandomHorizontalFlip(p=1)  \nimg_flipped, annot_flipped = horizontal_flip(img_original, annot_original)\n\n\n\n# Show the Before and After\nfig, axs = plt.subplots(1, 2, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f\"(Random) Horizontal Flip\", fontsize = 20)\n\naxs[0].set_title(\"Original Image\", fontsize = 20)\nshow_image_bbox(img_original, annot_original, axs=axs[0])\n\naxs[1].set_title(\"With Horizontal Flip\", fontsize = 20)\nshow_image_bbox(img_flipped, annot_flipped, axs[1])\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:02.268581Z","iopub.execute_input":"2022-04-18T14:32:02.269045Z","iopub.status.idle":"2022-04-18T14:32:03.372734Z","shell.execute_reply.started":"2022-04-18T14:32:02.269007Z","shell.execute_reply":"2022-04-18T14:32:03.372107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annot_original[1]","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.373918Z","iopub.execute_input":"2022-04-18T14:32:03.374261Z","iopub.status.idle":"2022-04-18T14:32:03.381052Z","shell.execute_reply.started":"2022-04-18T14:32:03.374228Z","shell.execute_reply":"2022-04-18T14:32:03.380218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pip install pillow","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.382682Z","iopub.execute_input":"2022-04-18T14:32:03.382991Z","iopub.status.idle":"2022-04-18T14:32:03.390853Z","shell.execute_reply.started":"2022-04-18T14:32:03.382895Z","shell.execute_reply":"2022-04-18T14:32:03.390037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import sys\n# print(sys.path)\n# sys.path.append('/lib/python3.7/site-packages')\n# from PIL import Image","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.392231Z","iopub.execute_input":"2022-04-18T14:32:03.393057Z","iopub.status.idle":"2022-04-18T14:32:03.399048Z","shell.execute_reply.started":"2022-04-18T14:32:03.393022Z","shell.execute_reply":"2022-04-18T14:32:03.398248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annot_original[1][1]","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.406568Z","iopub.execute_input":"2022-04-18T14:32:03.406798Z","iopub.status.idle":"2022-04-18T14:32:03.412643Z","shell.execute_reply.started":"2022-04-18T14:32:03.406769Z","shell.execute_reply":"2022-04-18T14:32:03.411979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from skimage import io\n# image = io.imread(img_original)\n# cropped = image[x1:x2,y1:y2]","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.414163Z","iopub.execute_input":"2022-04-18T14:32:03.414675Z","iopub.status.idle":"2022-04-18T14:32:03.419777Z","shell.execute_reply.started":"2022-04-18T14:32:03.414635Z","shell.execute_reply":"2022-04-18T14:32:03.419134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from skimage import data, color\nfrom skimage.transform import rescale, resize, downscale_local_mean","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.420925Z","iopub.execute_input":"2022-04-18T14:32:03.421379Z","iopub.status.idle":"2022-04-18T14:32:03.429569Z","shell.execute_reply.started":"2022-04-18T14:32:03.421344Z","shell.execute_reply":"2022-04-18T14:32:03.428772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.430948Z","iopub.execute_input":"2022-04-18T14:32:03.431475Z","iopub.status.idle":"2022-04-18T14:32:03.437664Z","shell.execute_reply.started":"2022-04-18T14:32:03.431437Z","shell.execute_reply":"2022-04-18T14:32:03.436915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In this session i tried to apply [this](https://www.kaggle.com/competitions/tensorflow-great-barrier-reef/discussion/308007) solution. However, the process is too complicated. I tried to blend cots from other source into the train images but the size and aspect is not blend to the image naturally. I think that I should use the cots from dataset image to fix this problem.","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# src = cv2.imread(\"../input/cot2naja/114-1142936_crown-thorns-png-crown-of-thorns-starfish-png.png\")\n# # src = cv2.imread(\"../input/cots-jpg/Crown_of_Thorns_Starfish.jpg\")\n# # src = resize(src, (src.shape[0] // 2, src.shape[1] // 2),\n# #                        anti_aliasing=True)\n# dst = img_original\n# \t# Create a rough mask around the airplane.\n# src_mask = np.zeros(src.shape, src.dtype)\n# poly = np.array([ [225,220],  [425,220], [425,390],[225,390], ], np.int32)\n# # poly = np.array([ [40,90],  [425,90], [425,390],[40,390], ], np.int32)\n\n# cv2.fillPoly(src_mask, [poly], (255, 255, 255))\n \n# src =cv2.cvtColor(src, cv2.COLOR_BGR2RGB)    \n# # This is where the CENTER of the airplane will be placed\n# center = (random.randint(0,1280), random.randint(0,720))\n \n# # Clone seamlessly.\n# output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)\n\n# from matplotlib.pyplot import figure\n# figure(figsize=(10,7), dpi=120)\n# plt.imshow(output)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.438985Z","iopub.execute_input":"2022-04-18T14:32:03.439502Z","iopub.status.idle":"2022-04-18T14:32:03.447599Z","shell.execute_reply.started":"2022-04-18T14:32:03.439467Z","shell.execute_reply":"2022-04-18T14:32:03.446517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# # src = downscale_local_mean(image, (4, 3))\n# from matplotlib.pyplot import figure\n# figure(figsize=(12,9), dpi=120)\n# plt.imshow(src)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.449363Z","iopub.execute_input":"2022-04-18T14:32:03.449662Z","iopub.status.idle":"2022-04-18T14:32:03.461404Z","shell.execute_reply.started":"2022-04-18T14:32:03.449629Z","shell.execute_reply":"2022-04-18T14:32:03.459905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(output)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.462919Z","iopub.execute_input":"2022-04-18T14:32:03.463162Z","iopub.status.idle":"2022-04-18T14:32:03.512793Z","shell.execute_reply.started":"2022-04-18T14:32:03.463134Z","shell.execute_reply":"2022-04-18T14:32:03.511252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random Scaling","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.513589Z","iopub.status.idle":"2022-04-18T14:32:03.514124Z","shell.execute_reply.started":"2022-04-18T14:32:03.513888Z","shell.execute_reply":"2022-04-18T14:32:03.513913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ==== Clips the bboxes ====\ndef bbox_area(bbox):\n    return (bbox[:,2] - bbox[:,0])*(bbox[:,3] - bbox[:,1])\n\ndef clip_box(bbox, clip_box, alpha):\n    \"\"\"\n    Clip the bounding boxes to the borders of an image\n    bbox: numpy.ndarray\n        Numpy array containing bounding boxes of shape `N X 4` where N is the \n        number of bounding boxes and the bounding boxes are represented in the\n        format `x1 y1 x2 y2`\n    \n    clip_box: numpy.ndarray\n        An array of shape (4,) specifying the diagonal co-ordinates of the image\n        The coordinates are represented in the format `x1 y1 x2 y2`\n        \n    alpha: float\n        If the fraction of a bounding box left in the image after being clipped is \n        less than `alpha` the bounding box is dropped. \n    \n    Returns\n    -------\n    numpy.ndarray\n        Numpy array containing **clipped** bounding boxes of shape `N X 4` where N is the \n        number of bounding boxes left are being clipped and the bounding boxes are represented in the\n        format `x1 y1 x2 y2` \n    \"\"\"\n    ar_ = (bbox_area(bbox))\n    x_min = np.maximum(bbox[:,0], clip_box[0]).reshape(-1,1)\n    y_min = np.maximum(bbox[:,1], clip_box[1]).reshape(-1,1)\n    x_max = np.minimum(bbox[:,2], clip_box[2]).reshape(-1,1)\n    y_max = np.minimum(bbox[:,3], clip_box[3]).reshape(-1,1)\n    \n    bbox = np.hstack((x_min, y_min, x_max, y_max, bbox[:,4:]))\n    \n    delta_area = ((ar_ - bbox_area(bbox))/ar_)\n    \n    mask = (delta_area < (1 - alpha)).astype(int)\n    \n    bbox = bbox[mask == 1,:]\n\n\n    return bbox","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.515634Z","iopub.status.idle":"2022-04-18T14:32:03.516853Z","shell.execute_reply.started":"2022-04-18T14:32:03.516624Z","shell.execute_reply":"2022-04-18T14:32:03.516649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RandomScale(object):\n\n    def __init__(self, scale = 0.2, diff = False):\n        \n        # scale must always be a positive number\n        self.scale = scale\n        self.scale = (max(-1, -self.scale), self.scale)\n        \n        # Maintain the aspect ratio\n        # (scaling factor remains the same for width & height)\n        self.diff = diff\n        \n        \n    def __call__(self, img, bboxes):\n        \n        # Convert bboxes\n        bboxes = np.array(bboxes)\n\n        #Chose a random digit to scale by \n        img_shape = img.shape\n\n        if self.diff:\n            scale_x = random.uniform(*self.scale)\n            scale_y = random.uniform(*self.scale)\n        else:\n            scale_x = random.uniform(*self.scale)\n            scale_y = scale_x\n\n        resize_scale_x = 1 + scale_x\n        resize_scale_y = 1 + scale_y\n\n        # Resize the image by scale factor\n        img = cv2.resize(img, None, fx = resize_scale_x, fy = resize_scale_y)\n\n        bboxes[:,:4] = bboxes[:,:4] * [resize_scale_x, resize_scale_y, resize_scale_x, resize_scale_y]\n\n        # The black image (the remaining area after we have clipped the image)\n        canvas = np.zeros(img_shape, dtype = np.uint8)\n\n        # Determine the size of the scaled image\n        y_lim = int(min(resize_scale_y,1)*img_shape[0])\n        x_lim = int(min(resize_scale_x,1)*img_shape[1])\n\n        canvas[:y_lim,:x_lim,:] =  img[:y_lim,:x_lim,:]\n\n        img = canvas\n        # Adjust the bboxes - remove all annotations that dissapeared after the scaling\n        bboxes = clip_box(bboxes, [0,0,1 + img_shape[1], img_shape[0]], 0.25)\n\n        return img, bboxes.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.517914Z","iopub.status.idle":"2022-04-18T14:32:03.518695Z","shell.execute_reply.started":"2022-04-18T14:32:03.518459Z","shell.execute_reply":"2022-04-18T14:32:03.518488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(24)\n\n# Scaling\nscale = RandomScale(scale=1.3, diff = False) \nimg_scaled, annot_scaled = scale(img_original, annot_original)\n\n\n\n# Show the Before and After\nfig, axs = plt.subplots(1, 2, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f\"(Random) Image Scaling\", fontsize = 20)\n\naxs[0].set_title(\"Original Image\", fontsize = 20)\nshow_image_bbox(img_original, annot_original, axs=axs[0])\n\naxs[1].set_title(\"Scaled (zoomed in) Image\", fontsize = 20)\nshow_image_bbox(img_scaled, annot_scaled, axs[1])\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.52292Z","iopub.status.idle":"2022-04-18T14:32:03.524092Z","shell.execute_reply.started":"2022-04-18T14:32:03.523855Z","shell.execute_reply":"2022-04-18T14:32:03.52388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random Translate\nclass RandomTranslate(object):\n\n    def __init__(self, translate = 0.2, diff = False):\n        \n        self.translate = translate\n        self.translate = (-self.translate, self.translate)\n            \n        # Maintain the aspect ratio\n        # (scaling factor remains the same for width & height)\n        self.diff = diff\n        \n    def __call__(self, img, bboxes):  \n        \n        # Convert bboxes\n        bboxes = np.array(bboxes)\n        \n        # Chose a random digit to scale by \n        img_shape = img.shape\n\n        # Percentage of the dimension of the image to translate\n        translate_factor_x = random.uniform(*self.translate)\n        translate_factor_y = random.uniform(*self.translate)\n\n        if not self.diff:\n            translate_factor_y = translate_factor_x\n\n        canvas = np.zeros(img_shape).astype(np.uint8)\n\n        corner_x = int(translate_factor_x*img.shape[1])\n        corner_y = int(translate_factor_y*img.shape[0])\n\n        #Change the origin to the top-left corner of the translated box\n        orig_box_cords =  [max(0,corner_y), max(corner_x,0), min(img_shape[0], corner_y + img.shape[0]), min(img_shape[1],corner_x + img.shape[1])]\n\n        mask = img[max(-corner_y, 0):min(img.shape[0], -corner_y + img_shape[0]), max(-corner_x, 0):min(img.shape[1], -corner_x + img_shape[1]),:]\n        canvas[orig_box_cords[0]:orig_box_cords[2], orig_box_cords[1]:orig_box_cords[3],:] = mask\n        img = canvas\n\n        bboxes[:,:4] += [corner_x, corner_y, corner_x, corner_y]\n\n        bboxes = clip_box(bboxes, [0,0,img_shape[1], img_shape[0]], 0.25)\n\n        return img, bboxes.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.525084Z","iopub.status.idle":"2022-04-18T14:32:03.525652Z","shell.execute_reply.started":"2022-04-18T14:32:03.525424Z","shell.execute_reply":"2022-04-18T14:32:03.525449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(25)\n\n# Translate\ntranslate = RandomTranslate(translate=0.4, diff = False) \nimg_translated, annot_translated = translate(img_original, annot_original)\n\n\n\n# Show the Before and After\nfig, axs = plt.subplots(1, 2, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f\"(Random) Image Translation\", fontsize = 20)\n\naxs[0].set_title(\"Original Image\", fontsize = 20)\nshow_image_bbox(img_original, annot_original, axs=axs[0])\n\naxs[1].set_title(\"Translated (shifted) Image\", fontsize = 20)\nshow_image_bbox(img_translated, annot_translated, axs[1])\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.527245Z","iopub.status.idle":"2022-04-18T14:32:03.528304Z","shell.execute_reply.started":"2022-04-18T14:32:03.528043Z","shell.execute_reply":"2022-04-18T14:32:03.528067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random Rotation\n# === Image Rotation ===\n\ndef rotate_im(image, angle):\n    '''image: numpy array of the image'''\n    '''angle: a float that specifies the angle the image should be rotated.'''\n\n    # Image dimensions\n    (h, w) = image.shape[:2]\n    # Image Centre\n    (cX, cY) = (w // 2, h // 2)\n\n    # Rotation Matrix from cv2\n    M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)\n    # Sine & Cosine - rotation components of the matrix\n    cos = np.abs(M[0, 0])\n    sin = np.abs(M[0, 1])\n\n    # NEW Bounding Dimensions of the image\n    nW = int((h * sin) + (w * cos))\n    nH = int((h * cos) + (w * sin))\n\n    # Adjust the rotation matrix to take into account translation\n    M[0, 2] += (nW / 2) - cX\n    M[1, 2] += (nH / 2) - cY\n\n    # Perform the Rotation\n    image = cv2.warpAffine(image, M, (nW, nH))\n\n    return image","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.529272Z","iopub.status.idle":"2022-04-18T14:32:03.533944Z","shell.execute_reply.started":"2022-04-18T14:32:03.533696Z","shell.execute_reply":"2022-04-18T14:32:03.533721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# === Get Corners of Bounding Boxes ===\n\ndef get_corners(bboxes):\n    '''bboxes: array of the original bounding boxes.'''\n    \n    width = (bboxes[:,2] - bboxes[:,0]).reshape(-1,1)\n    height = (bboxes[:,3] - bboxes[:,1]).reshape(-1,1)\n    \n    x1 = bboxes[:,0].reshape(-1,1)\n    y1 = bboxes[:,1].reshape(-1,1)\n    \n    x2 = x1 + width\n    y2 = y1 \n    \n    x3 = x1\n    y3 = y1 + height\n    \n    x4 = bboxes[:,2].reshape(-1,1)\n    y4 = bboxes[:,3].reshape(-1,1)\n    \n    # Each bounding box is described by 8 coordinates x1,y1,x2,y2,x3,y3,x4,y4\n    corners = np.hstack((x1,y1,x2,y2,x3,y3,x4,y4))\n    \n    return corners\n\n\n# === Box Rotation ===\n\ndef rotate_box(corners, angle, cx, cy, h, w):\n    '''\n    corners: output from get_corners()\n    angle:  a float that specifies the angle the image should be rotated\n    cx, cy: coordinates for the xenter of the image\n    h, w: height and width of the image\n    '''\n    \n    # corners = x1,y1,x2,y2,x3,y3,x4,y4\n    corners = corners.reshape(-1,2)\n    corners = np.hstack((corners, np.ones((corners.shape[0],1), dtype = type(corners[0][0]))))\n    \n    # Rotation Matrix from cv2\n    M = cv2.getRotationMatrix2D((cx, cy), angle, 1.0)\n    # Sine & Cosine - rotation components of the matrix\n    cos = np.abs(M[0, 0])\n    sin = np.abs(M[0, 1])\n    \n    # NEW Bounding Dimensions of the image\n    nW = int((h * sin) + (w * cos))\n    nH = int((h * cos) + (w * sin))\n    \n    # Adjust the rotation matrix to take into account translation\n    M[0, 2] += (nW / 2) - cx\n    M[1, 2] += (nH / 2) - cy\n    \n    # Prepare the vector to be transformed\n    calculated = np.dot(M,corners.T).T\n    calculated = calculated.reshape(-1,8)\n    \n    return calculated\n\n\n# === Get the Enclosing Box ===\n\ndef get_enclosing_box(corners):\n    '''corners: output from get_corners()'''\n    \n    x_ = corners[:,[0,2,4,6]]\n    y_ = corners[:,[1,3,5,7]]\n    \n    xmin = np.min(x_,1).reshape(-1,1)\n    ymin = np.min(y_,1).reshape(-1,1)\n    xmax = np.max(x_,1).reshape(-1,1)\n    ymax = np.max(y_,1).reshape(-1,1)\n    \n    # Notation where each bounding box is determined by 4 coordinates or two corners\n    final = np.hstack((xmin, ymin, xmax, ymax,corners[:,8:]))\n    \n    return final","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.534913Z","iopub.status.idle":"2022-04-18T14:32:03.53588Z","shell.execute_reply.started":"2022-04-18T14:32:03.535653Z","shell.execute_reply":"2022-04-18T14:32:03.535677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RandomRotate(object):\n\n    def __init__(self, angle = 10):\n        \n        self.angle = angle\n        self.angle = (-self.angle, self.angle)\n        \n        \n    def __call__(self, img, bboxes):\n\n        # Convert bboxes\n        bboxes = np.array(bboxes)\n        \n        # Compute the random angle\n        angle = random.uniform(*self.angle)\n\n        # width, height and center of the image\n        w,h = img.shape[1], img.shape[0]\n        cx, cy = w//2, h//2\n\n        # Rotate the image\n        img = rotate_im(img, angle)\n\n        # --- Rotate the bounding boxes ---\n        # Get the 4 point corner coordinates\n        corners = get_corners(bboxes)\n        corners = np.hstack((corners, bboxes[:,4:]))\n        # Rotate the bounding box\n        corners[:,:8] = rotate_box(corners[:,:8], angle, cx, cy, h, w)\n        # Get the enclosing (new bboxes)\n        new_bbox = get_enclosing_box(corners)\n\n        # Get scaling factors to clip the image and bboxes\n        scale_factor_x = img.shape[1] / w\n        scale_factor_y = img.shape[0] / h\n\n        # Rescale the image - to w,h and not nW,nH\n        img = cv2.resize(img, (w,h))\n\n        # Clip boxes (in case there are any outside of the rotated image)\n        bboxes[:,:4] = bboxes[:,:4] / [scale_factor_x, scale_factor_y, scale_factor_x, scale_factor_y] \n        bboxes = clip_box(bboxes, [0,0,w, h], 0.25)\n\n        return img, bboxes.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.536841Z","iopub.status.idle":"2022-04-18T14:32:03.537635Z","shell.execute_reply.started":"2022-04-18T14:32:03.5374Z","shell.execute_reply":"2022-04-18T14:32:03.537429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(25)\n\n# Translate\nrotate = RandomRotate(angle=25) \nimg_rotated, annot_rotated = rotate(img_original, annot_original)\n\n\n\n# Show the Before and After\nfig, axs = plt.subplots(1, 2, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f\"(Random) Image Rotation\", fontsize = 20)\n\naxs[0].set_title(\"Original Image\", fontsize = 20)\nshow_image_bbox(img_original, annot_original, axs=axs[0])\n\naxs[1].set_title(\"Rotated Image\", fontsize = 20)\nshow_image_bbox(img_rotated, annot_rotated, axs[1])\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.538793Z","iopub.status.idle":"2022-04-18T14:32:03.539594Z","shell.execute_reply.started":"2022-04-18T14:32:03.539362Z","shell.execute_reply":"2022-04-18T14:32:03.539386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Random Shear","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.544102Z","iopub.status.idle":"2022-04-18T14:32:03.544678Z","shell.execute_reply.started":"2022-04-18T14:32:03.544448Z","shell.execute_reply":"2022-04-18T14:32:03.544472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RandomShear(object):\n\n    def __init__(self, shear_factor = 0.2):\n        \n        self.shear_factor = shear_factor\n        self.shear_factor = (-self.shear_factor, self.shear_factor)\n        \n        shear_factor = random.uniform(*self.shear_factor)\n        \n        \n    def __call__(self, img, bboxes):\n        \n        # Convert bboxes\n        bboxes = np.array(bboxes)\n\n        # Get the shear factor and size of the image\n        shear_factor = random.uniform(*self.shear_factor)\n        w,h = img.shape[1], img.shape[0]\n\n        # Flip the image and boxes horizontally\n        if shear_factor < 0:\n            img, bboxes = HorizontalFlip()(img, bboxes)\n\n        # Apply the shear transformation\n        M = np.array([[1, abs(shear_factor), 0],[0,1,0]])\n        nW =  img.shape[1] + abs(shear_factor*img.shape[0])\n\n        bboxes[:,[0,2]] += ((bboxes[:,[1,3]]) * abs(shear_factor) ).astype(int) \n\n        # Transform using cv2 warpAffine (like in rotation)\n        img = cv2.warpAffine(img, M, (int(nW), img.shape[0]))\n\n        # Flip the image back again\n        if shear_factor < 0:\n            img, bboxes = HorizontalFlip()(img, bboxes)\n\n        # Resize\n        img = cv2.resize(img, (w,h))\n\n        scale_factor_x = nW / w\n        bboxes[:,:4] = bboxes[:,:4] / [scale_factor_x, 1, scale_factor_x, 1] \n        \n        return img, bboxes.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.54588Z","iopub.status.idle":"2022-04-18T14:32:03.547075Z","shell.execute_reply.started":"2022-04-18T14:32:03.546839Z","shell.execute_reply":"2022-04-18T14:32:03.546864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(25)\n\n# Translate\nshear = RandomShear(shear_factor=0.9) \nimg_sheared, annot_sheared = shear(img_original, annot_original)\n\n\n\n# Show the Before and After\nfig, axs = plt.subplots(1, 2, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f\"(Random) Image Shear\", fontsize = 20)\n\naxs[0].set_title(\"Original Image\", fontsize = 20)\nshow_image_bbox(img_original, annot_original, axs=axs[0])\n\naxs[1].set_title(\"Sheared Image\", fontsize = 20)\nshow_image_bbox(img_sheared, annot_sheared, axs[1])\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.548227Z","iopub.status.idle":"2022-04-18T14:32:03.54877Z","shell.execute_reply.started":"2022-04-18T14:32:03.548537Z","shell.execute_reply":"2022-04-18T14:32:03.548566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# === 🐝W&B Log (redone for formated annotations) ===\ndef wandb_bboxes(image, annotations):\n    '''Source: https://www.kaggle.com/ayuraj/visualize-bounding-boxes-interactively\n    image: the cv2.imread() output\n    annotations: the FORMATED annotations from the train dataset'''\n    \n    all_annotations = []\n    if annotations:\n        for annot in annotations:\n            data = {\"position\": {\n                            \"minX\": annot[0],\n                            \"minY\": annot[1],\n                            \"maxX\": annot[2],\n                            \"maxY\": annot[3]\n                        },\n                    \"class_id\" : 1,\n                    \"domain\" : \"pixel\"}\n            all_annotations.append(data)\n    \n    return wandb.Image(image, \n                       boxes={\"ground_truth\": {\"box_data\": all_annotations}}\n                      )\n\n# Log all augmented images to the Dashboard\nwandb.log({\"flipped\": wandb_bboxes(img_flipped, annot_flipped)})\nwandb.log({\"scaled\": wandb_bboxes(img_scaled, annot_scaled)})\nwandb.log({\"translated\": wandb_bboxes(img_translated, annot_translated)})\n# wandb.log({\"rotated\": wandb_bboxes(img_rotated, annot_rotated)})\nwandb.log({\"sheared\": wandb_bboxes(img_sheared, annot_sheared)})","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.550431Z","iopub.status.idle":"2022-04-18T14:32:03.556249Z","shell.execute_reply.started":"2022-04-18T14:32:03.555985Z","shell.execute_reply":"2022-04-18T14:32:03.556011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wandb.finish()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.557051Z","iopub.status.idle":"2022-04-18T14:32:03.557859Z","shell.execute_reply.started":"2022-04-18T14:32:03.557626Z","shell.execute_reply":"2022-04-18T14:32:03.557651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head(1)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.558658Z","iopub.status.idle":"2022-04-18T14:32:03.559285Z","shell.execute_reply.started":"2022-04-18T14:32:03.559019Z","shell.execute_reply":"2022-04-18T14:32:03.559043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Libraries\nimport os\nimport sys\nimport wandb\nimport torch\nimport time\nimport random\nimport shutil\nimport yaml\nfrom tqdm import tqdm\nimport warnings\nimport cv2\nimport pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport matplotlib as mpl\nimport matplotlib.patches as patches\nimport matplotlib.pyplot as plt\nfrom IPython.display import display_html\n\n\n# Environment check\nwarnings.filterwarnings(\"ignore\")\nos.environ[\"WANDB_SILENT\"] = \"true\"\nCONFIG = {'competition': 'greatReef', '_wandb_kernel': 'aot'}\n\n# 🐝 Secrets\nfrom kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient()\nsecret_value_0 = user_secrets.get_secret(\"wandb\")\n\n! wandb login $secret_value_0\n\n# Custom colors\nclass color:\n    S = '\\033[1m' + '\\033[94m'\n    E = '\\033[0m'\n    \nmy_colors = [\"#16558F\", \"#1583D2\", \"#61B0B7\", \"#ADDEFF\", \"#A99AEA\", \"#7158B7\"]\nprint(color.S+\"Current Directory\"+color.E, os.getcwd())\nprint(color.S+\"Notebook Color Scheme:\"+color.E)\nsns.palplot(sns.color_palette(my_colors))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.560796Z","iopub.status.idle":"2022-04-18T14:32:03.565298Z","shell.execute_reply.started":"2022-04-18T14:32:03.565011Z","shell.execute_reply":"2022-04-18T14:32:03.565039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# === 🐝 W&B ===\ndef save_dataset_artifact(run_name, artifact_name, path):\n    '''Saves dataset to W&B Artifactory.\n    run_name: name of the experiment\n    artifact_name: under what name should the dataset be stored\n    path: path to the dataset'''\n    \n    run = wandb.init(project='g2net', \n                     name=run_name, \n                     config=CONFIG, anonymous=\"allow\")\n    artifact = wandb.Artifact(name=artifact_name, \n                              type='dataset')\n    artifact.add_file(path)\n\n    wandb.log_artifact(artifact)\n    wandb.finish()\n    print(\"Artifact has been saved successfully.\")\n    \n    \ndef create_wandb_plot(x_data=None, y_data=None, x_name=None, y_name=None, title=None, log=None, plot=\"line\"):\n    '''Create and save lineplot/barplot in W&B Environment.\n    x_data & y_data: Pandas Series containing x & y data\n    x_name & y_name: strings containing axis names\n    title: title of the graph\n    log: string containing name of log'''\n    \n    data = [[label, val] for (label, val) in zip(x_data, y_data)]\n    table = wandb.Table(data=data, columns = [x_name, y_name])\n    \n    if plot == \"line\":\n        wandb.log({log : wandb.plot.line(table, x_name, y_name, title=title)})\n    elif plot == \"bar\":\n        wandb.log({log : wandb.plot.bar(table, x_name, y_name, title=title)})\n    elif plot == \"scatter\":\n        wandb.log({log : wandb.plot.scatter(table, x_name, y_name, title=title)})\n        \n        \ndef create_wandb_hist(x_data=None, x_name=None, title=None, log=None):\n    '''Create and save histogram in W&B Environment.\n    x_data: Pandas Series containing x values\n    x_name: strings containing axis name\n    title: title of the graph\n    log: string containing name of log'''\n    \n    data = [[x] for x in x_data]\n    table = wandb.Table(data=data, columns=[x_name])\n    wandb.log({log : wandb.plot.histogram(table, x_name, title=title)})","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.566414Z","iopub.status.idle":"2022-04-18T14:32:03.569836Z","shell.execute_reply.started":"2022-04-18T14:32:03.569599Z","shell.execute_reply":"2022-04-18T14:32:03.569626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create sepparate paths for images and their labels (annotations)\n# these will come in handy later for the YOLO model\ntrain[\"path_images\"] = \"/kaggle/images/video_\" + train[\"video_id\"].astype(str) + \"_\" + \\\n                                                train[\"video_frame\"].astype(str) + \".jpg\"\ntrain[\"path_labels\"] = \"/kaggle/labels/video_\" + train[\"video_id\"].astype(str) + \"_\" + \\\n                                                train[\"video_frame\"].astype(str) + \".txt\"\n\n# Save the width and height of the images\n# it is the same for the entire dataset\ntrain[\"width\"] = 1280\ntrain[\"height\"] = 720\n\n# Simplify the annotation format\ntrain[\"coco_bbox\"] = train[\"annotations\"].apply(lambda annot: [list(item.values()) for item in eval(annot)])\n\n# Data Sample\ntrain.sample(5, random_state=24)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.570789Z","iopub.status.idle":"2022-04-18T14:32:03.571875Z","shell.execute_reply.started":"2022-04-18T14:32:03.571646Z","shell.execute_reply":"2022-04-18T14:32:03.57167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Save dataset\n# train.to_csv(\"train.csv\", index=False)\n\n\n# # 🐝 Save dataset Artifact\n# save_dataset_artifact(run_name=\"save-train-data\",\n#                       artifact_name=\"train_meta\",\n#                       path=\"../input/2021-greatbarrierreef-prep-data/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.572826Z","iopub.status.idle":"2022-04-18T14:32:03.578578Z","shell.execute_reply.started":"2022-04-18T14:32:03.578339Z","shell.execute_reply":"2022-04-18T14:32:03.578364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train[train['no_annotations']==0])","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.57949Z","iopub.status.idle":"2022-04-18T14:32:03.579973Z","shell.execute_reply.started":"2022-04-18T14:32:03.579745Z","shell.execute_reply":"2022-04-18T14:32:03.579769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['annotations'] = train['annotations'].apply(eval)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.581059Z","iopub.status.idle":"2022-04-18T14:32:03.582375Z","shell.execute_reply.started":"2022-04-18T14:32:03.582118Z","shell.execute_reply":"2022-04-18T14:32:03.582142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -qU bbox-utility\nfrom bbox.utils import coco2yolo, coco2voc, voc2yolo, draw_bboxes, load_image, clip_bbox, str2annot, annot2str\n\ndef get_bbox(annots):\n    bboxs = [list(annot.values()) for annot in annots]\n    return bboxs\n\ndef get_imgsize(row):\n    row['width'], row['height'] = imagesize.get(row['image_path'])\n    return row\n\nnp.random.seed(42)\ncolors = [(np.random.randint(255), np.random.randint(255), np.random.randint(255))\\\n         for idx in range(1)]","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.583521Z","iopub.status.idle":"2022-04-18T14:32:03.584063Z","shell.execute_reply.started":"2022-04-18T14:32:03.583834Z","shell.execute_reply":"2022-04-18T14:32:03.583859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train['bboxes'] = train.annotations.apply(get_bbox)\n# train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.585366Z","iopub.status.idle":"2022-04-18T14:32:03.586116Z","shell.execute_reply.started":"2022-04-18T14:32:03.585877Z","shell.execute_reply":"2022-04-18T14:32:03.585904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(train['annotations'][0][0])","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.592021Z","iopub.status.idle":"2022-04-18T14:32:03.592597Z","shell.execute_reply.started":"2022-04-18T14:32:03.592362Z","shell.execute_reply":"2022-04-18T14:32:03.592387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Import the prepped train dataset\n# train = pd.read_csv(\"../input/2021-greatbarrierreef-prep-data/train.csv\")\n# # Remove all images that have no bounding box (removing ~80% of data)\n# train = train[train[\"no_annotations\"]>0].reset_index(drop=True)\n\n# train.sample(3, random_state=24)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.593897Z","iopub.status.idle":"2022-04-18T14:32:03.594669Z","shell.execute_reply.started":"2022-04-18T14:32:03.594431Z","shell.execute_reply":"2022-04-18T14:32:03.594457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Create sepparate paths for images and their labels (annotations)\n# # these will come in handy later for the YOLO model\n# train[\"path_images\"] = \"/kaggle/images/video_\" + train[\"video_id\"].astype(str) + \"_\" + \\\n#                                                 train[\"video_frame\"].astype(str) + \".jpg\"\n# train[\"path_labels\"] = \"/kaggle/labels/video_\" + train[\"video_id\"].astype(str) + \"_\" + \\\n#                                                 train[\"video_frame\"].astype(str) + \".txt\"\n\n# # Save the width and height of the images\n# # it is the same for the entire dataset\n# train[\"width\"] = 1280\n# train[\"height\"] = 720\n\n# # Simplify the annotation format\n# train[\"coco_bbox\"] = train[\"annotations\"].apply(lambda annot: [list(item.values()) for item in (annot)])\n\n# # Data Sample\n# train.sample(5, random_state=24)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.598555Z","iopub.status.idle":"2022-04-18T14:32:03.599054Z","shell.execute_reply.started":"2022-04-18T14:32:03.598873Z","shell.execute_reply":"2022-04-18T14:32:03.598896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Populate the ../images folder\n\nfor path in tqdm(train[\"path\"].tolist()):\n    split_path = path.split(\"/\")\n\n    # Retrieve the video id (0, 1, 2) and its frame number\n    video_id = split_path[-2]\n    video_frame = split_path[-1]\n\n    # Create new image path\n    path_image = f\"../images/{video_id}_{video_frame}\"\n    \n    # Copy file from source (competition data) to destination (our new folder)\n    shutil.copy(src=path, dst=path_image)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.601163Z","iopub.status.idle":"2022-04-18T14:32:03.601916Z","shell.execute_reply.started":"2022-04-18T14:32:03.60163Z","shell.execute_reply":"2022-04-18T14:32:03.601659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Glimpse of images folder now:\nprint(color.S+\"Sample of 3 images from the ../images/ folder:\"+color.E, os.listdir(\"../images\")[:3])\n\nplt.figure(figsize=(10, 10))\nimg_sample = cv2.imread(\"../images/video_1_6258.jpg\")\nimg_sample = cv2.cvtColor(img_sample, cv2.COLOR_BGR2RGB)\nplt.imshow(img_sample)\nplt.axis(\"off\");","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.603148Z","iopub.status.idle":"2022-04-18T14:32:03.603792Z","shell.execute_reply.started":"2022-04-18T14:32:03.603545Z","shell.execute_reply":"2022-04-18T14:32:03.60357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# COCO to YOLO\ndef coco2yolo(image_height, image_width, bboxes):\n    \"\"\"\n    Converts a coco annotation format [xmin, ymin, w, h] to \n    the corresponding yolo format [xmid, ymid, w, h]\n    \n    image_height: height of the original image\n    image_width: width of the original image\n    bboxes: coco boxes to be converted\n    return :: \n    \n    inspo: https://www.kaggle.com/awsaf49/great-barrier-reef-yolov5-train\n    \"\"\"\n    \n    bboxes = np.array(bboxes).astype(float)\n    \n    # Normalize xmin, w\n    bboxes[:, [0, 2]]= bboxes[:, [0, 2]]/ image_width\n    # Normalize ymin, h\n    bboxes[:, [1, 3]]= bboxes[:, [1, 3]]/ image_height\n    \n    # Converstion (xmin, ymin) => (xmid, ymid)\n    bboxes[:, [0, 1]] = bboxes[:, [0, 1]] + bboxes[:, [2, 3]]/2\n    \n    # Clip values (between 0 and 1)\n    bboxes = np.clip(bboxes, a_min=0, a_max=1)\n    \n    return bboxes","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.604997Z","iopub.status.idle":"2022-04-18T14:32:03.605621Z","shell.execute_reply.started":"2022-04-18T14:32:03.605389Z","shell.execute_reply":"2022-04-18T14:32:03.605414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# --- Example ---\nbbox_example = [[559, 213, 50, 32], [679, 223, 10, 100]]\n\nprint(color.S+\"From COCO: \"+color.E, bbox_example)\nprint(color.S+\"to YOLO:\"+color.E, \n      coco2yolo(image_height=720, \n                image_width=1280, \n                bboxes=bbox_example))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.606807Z","iopub.status.idle":"2022-04-18T14:32:03.607428Z","shell.execute_reply.started":"2022-04-18T14:32:03.607181Z","shell.execute_reply":"2022-04-18T14:32:03.607221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head(2)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.608582Z","iopub.status.idle":"2022-04-18T14:32:03.609226Z","shell.execute_reply.started":"2022-04-18T14:32:03.608976Z","shell.execute_reply":"2022-04-18T14:32:03.609001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# YOLO tags\nyolo_bboxes = []\n\nfor k in tqdm(range(len(train))):\n    \n    row_data = train.iloc[k, :]\n    height = row_data['height']\n    width = row_data['width']\n    coco_bbox = (row_data['coco_bbox'])\n    len_bbox = row_data['no_annotations']\n    \n    with open(row_data['path_labels'], 'w') as file:\n        if len_bbox == 0:\n            file.write('')\n            continue\n        \n        yolo_bbox = coco2yolo(height, width, coco_bbox)\n        yolo_bboxes.append(yolo_bbox)\n        \n        for i in range(len_bbox):\n            annot = ['0'] + \\\n                    yolo_bbox[i].astype(str).tolist() + \\\n                    ([''] if i+1 == len_bbox else ['\\n'])\n            annot = ' '.join(annot).strip()\n            file.write(annot)\n            \ntrain['yolo_bbox'] = yolo_bboxes","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.610418Z","iopub.status.idle":"2022-04-18T14:32:03.611038Z","shell.execute_reply.started":"2022-04-18T14:32:03.610804Z","shell.execute_reply":"2022-04-18T14:32:03.610829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Glimpse of labels folder now:\nprint(color.S+\"Sample of 3 labels from the ../labels/ folder:\"+color.E, os.listdir(\"../labels\")[:3], \"\\n\")\n\n# Let's read the files\nf1 = open('../labels/video_1_4238.txt', 'r')\nf2 = open('../labels/video_1_5315.txt', 'r')\nf3 = open('../labels/video_0_1006.txt', 'r')\n\n# How the .txt files look?\nprint(color.S+\"File1: \"+color.E, f1.read())\nprint(color.S+\"File2: \"+color.E, f2.read())\nprint(color.S+\"File3: \"+color.E, f3.read())","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.612248Z","iopub.status.idle":"2022-04-18T14:32:03.612882Z","shell.execute_reply.started":"2022-04-18T14:32:03.612637Z","shell.execute_reply":"2022-04-18T14:32:03.612661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = os.listdir('/kaggle/images')[6:12]\nvid_id = [im.split('_')[1] for im in images]\nseq_id = [im.split('_')[2].split('.')[0] for im in images]\n\nfig, axs = plt.subplots(2,3, figsize=(23, 10))\naxs = axs.flatten()\nfig.suptitle(f'Samplt of image and YOLO bounding boxes', fontsize = 20)\n\nfor k in range(6):\n    im = cv2.imread(f'/kaggle/images/{images[k]}')\n    im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)\n    dh, dw, _ = im.shape\n    txt = open(f'/kaggle/labels/video_{vid_id[k]}_{seq_id[k]}.txt', 'r').read().split(' ')[1:]\n    no_boxes = int(len(txt)/4)\n    \n     # Draw boxes\n    i = 0\n    while i < no_boxes:\n        i = i+4\n        box = txt[:i][-4:]\n        \n        # Src: https://github.com/pjreddie/darknet/blob/810d7f797bdb2f021dbe65d2524c2ff6b8ab5c8b/src/image.c#L283-L291\n        # from YOLO to COCO\n        x, y, w, h = box\n        x, y, w, h = float(x), float(y), float(w), float(h)\n\n        l = int((x - w / 2) * dw)\n        r = int((x + w / 2) * dw)\n        t = int((y - h / 2) * dh)\n        b = int((y + h / 2) * dh)\n\n        if l < 0: l = 0\n        if r > dw - 1: r = dw - 1\n        if t < 0: t = 0\n        if b > dh - 1: b = dh - 1\n\n        cv2.rectangle(im, (l, t), (r, b), (255,0,0), 3)\n        \n    # Show image with bboxes\n    axs[k].set_title(f\"Sample {k}\", fontsize = 14)\n    axs[k].imshow(im)\n    axs[k].set_axis_off()\n       \n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.614092Z","iopub.status.idle":"2022-04-18T14:32:03.61472Z","shell.execute_reply.started":"2022-04-18T14:32:03.614486Z","shell.execute_reply":"2022-04-18T14:32:03.614511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Spliting TRAIN/TEST data by videos\ntrain_data = train[train['video_id'].isin([0,2])]\ntest_data = train[train['video_id']==1]\n\n# Get path\ntrain_images = list(train_data['path_images'])\ntrain_labels = list(train_data['path_labels'])\n\n\ntest_images = list(test_data['path_images'])\ntest_labels = list(test_data['path_labels'])\n\nprint(color.S+\"Train Length:\"+color.E, len(train_data), \"\\n\" +\n      color.S+\"Test Length:\"+color.E, len(test_data))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.615938Z","iopub.status.idle":"2022-04-18T14:32:03.616576Z","shell.execute_reply.started":"2022-04-18T14:32:03.616344Z","shell.execute_reply":"2022-04-18T14:32:03.61637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create Working Path\nprint(color.S+\"./working BEFORE:\"+color.E, os.listdir(\"../working\"))\n\n# Create train and test path data\nwith open(\"../working/train_images.txt\", \"w\") as file:\n    for path in train_images:\n        file.write(path + \"\\n\")\n        \nwith open(\"../working/test_images.txt\", \"w\") as file:\n    for path in test_images:\n        file.write(path + \"\\n\")\n\n\n# Create configuration\nconfig = {'path': '/kaggle/working',\n          'train': '/kaggle/working/train_images.txt',\n          'val': '/kaggle/working/test_images.txt',\n          'nc': 1,\n          'names': ['cots']}\n\nwith open(\"../working/cots.yaml\", \"w\") as file:\n    yaml.dump(config, file, default_flow_style=False)\n\n        \nprint(color.S+\"../working AFTER:\"+color.E, os.listdir(\"../working\"))","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.617777Z","iopub.status.idle":"2022-04-18T14:32:03.618409Z","shell.execute_reply.started":"2022-04-18T14:32:03.618163Z","shell.execute_reply":"2022-04-18T14:32:03.618188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ---> YOLOv5 install <---\n%cd /kaggle/working     \n!cp -r /kaggle/input/yolov5-lib-ds /kaggle/working/yolov5     \n%cd yolov5     \n%pip install -qr requirements.txt   \n\nfrom yolov5 import utils\ndisplay = utils.notebook_init()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.619589Z","iopub.status.idle":"2022-04-18T14:32:03.620243Z","shell.execute_reply.started":"2022-04-18T14:32:03.619992Z","shell.execute_reply":"2022-04-18T14:32:03.620017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# --- PARAMETERS ---\n# These are just small samples, so the notebook runs faster\nSIZE = 1280\nBATCH_SIZE = 8\nEPOCHS = 2\nMODEL = \"yolov5m\"\nWORKERS = 1\nOPTMIZER  = 'Adam'\n\n\nPROJECT = PROJECT\n\nRUN_NAME = f\"{MODEL}_size{SIZE}_epochs{EPOCHS}_batch{BATCH_SIZE}_simple\"\n# ------------------","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.621432Z","iopub.status.idle":"2022-04-18T14:32:03.622063Z","shell.execute_reply.started":"2022-04-18T14:32:03.621826Z","shell.execute_reply":"2022-04-18T14:32:03.621851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# FOLD      = 1 # which fold to train\n# DIM       = 3000 \n# MODEL     = 'yolov5s6'\n# BATCH     = 4\n# EPOCHS    = 7\n# OPTMIZER  = 'Adam'\n\n# PROJECT   = PROJECT # w&b in yolov5\n# NAME      = f'{MODEL}-dim{DIM}-fold{FOLD}' # w&b for yolov5\n\n# REMOVE_NOBBOX = True # remove images with no bbox\n# ROOT_DIR  = '/kaggle/input/tensorflow-great-barrier-reef/'\n# IMAGE_DIR = '/kaggle/images' # directory to save images\n# LABEL_DIR = '/kaggle/labels' # directory to save labels","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.623276Z","iopub.status.idle":"2022-04-18T14:32:03.623901Z","shell.execute_reply.started":"2022-04-18T14:32:03.623658Z","shell.execute_reply":"2022-04-18T14:32:03.623682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !python train.py --img {DIM}\\\n# --batch {BATCH}\\\n# --epochs {EPOCHS}\\\n# --optimizer {OPTMIZER}\\\n# --data /kaggle/working/gbr.yaml\\\n# --hyp /kaggle/working/hyp.yaml\\\n# --weights {MODEL}.pt\\\n# --project {PROJECT} --name {NAME}\\\n# --exist-ok","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.625081Z","iopub.status.idle":"2022-04-18T14:32:03.625701Z","shell.execute_reply.started":"2022-04-18T14:32:03.625471Z","shell.execute_reply":"2022-04-18T14:32:03.625495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training\n!python train.py --img {SIZE}\\\n                --batch {BATCH_SIZE}\\\n                --epochs {EPOCHS}\\\n                --optimizer {OPTMIZER}\\\n                --data /kaggle/working/cots.yaml\\\n                --weights {MODEL}.pt\\\n                --workers {WORKERS}\\\n                --project {PROJECT}\\\n                --name {RUN_NAME}\\\n                --exist-ok","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.626888Z","iopub.status.idle":"2022-04-18T14:32:03.627521Z","shell.execute_reply.started":"2022-04-18T14:32:03.627287Z","shell.execute_reply":"2022-04-18T14:32:03.627312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Run details\nos.listdir(f\"{PROJECT}/{RUN_NAME}\")","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.628853Z","iopub.status.idle":"2022-04-18T14:32:03.62948Z","shell.execute_reply.started":"2022-04-18T14:32:03.629248Z","shell.execute_reply":"2022-04-18T14:32:03.629274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('hello')","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.630647Z","iopub.status.idle":"2022-04-18T14:32:03.631292Z","shell.execute_reply.started":"2022-04-18T14:32:03.631039Z","shell.execute_reply":"2022-04-18T14:32:03.631064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Change our position within the directory back\n# %cd /kaggle/working","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.632469Z","iopub.status.idle":"2022-04-18T14:32:03.63309Z","shell.execute_reply.started":"2022-04-18T14:32:03.632856Z","shell.execute_reply":"2022-04-18T14:32:03.63288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.634289Z","iopub.status.idle":"2022-04-18T14:32:03.634935Z","shell.execute_reply.started":"2022-04-18T14:32:03.634668Z","shell.execute_reply":"2022-04-18T14:32:03.634692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# --- Trained Model ---\nMODEL_PATH = \"../input/reef-baseline-fold12/l6_3600_uflip_vm5_f12_up/f1/best.pt\"\n\n# Load the model\nmodel = torch.hub.load(\"../input/yolov5-lib-ds\", \"custom\",\n                       path=MODEL_PATH,\n                       source='local', force_reload=True)\n\n# BoundingBox Confidence\nmodel.conf = 0.01\n# Intersection Over Union\nmodel.iou = 0.5","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.636104Z","iopub.status.idle":"2022-04-18T14:32:03.636726Z","shell.execute_reply.started":"2022-04-18T14:32:03.636492Z","shell.execute_reply":"2022-04-18T14:32:03.636516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create Ultralytics directory\n!mkdir -p /root/.config/Ultralytics\n# Copy folder to root\n!cp /kaggle/input/yolov5-font/Arial.ttf /root/.config/Ultralytics/","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.637917Z","iopub.status.idle":"2022-04-18T14:32:03.638544Z","shell.execute_reply.started":"2022-04-18T14:32:03.638315Z","shell.execute_reply":"2022-04-18T14:32:03.638339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import greatbarrierreef\n\n# Initialize the environment\nenv = greatbarrierreef.make_env()\n# Iterator that loops through the submission dataset\n# !!! you can run this cell only once\niter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.639694Z","iopub.status.idle":"2022-04-18T14:32:03.640332Z","shell.execute_reply.started":"2022-04-18T14:32:03.640079Z","shell.execute_reply":"2022-04-18T14:32:03.640104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !!! you can run this cell only once\n\n# Loop through the test file\nfor k, (image, sample_prediction_df) in enumerate(tqdm(iter_test)):\n    \n    annotation = \"\"\n    prediction = model(image, size=3600, augment=True)\n    print(\"Prediction Object:\", prediction.pandas())\n    print(\"Bounding Boxes:\", prediction.pandas().xyxy[0])\n    print(\"Shape:\", prediction.pandas().xyxy[0].shape[0])\n    \n    if prediction.pandas().xyxy[0].shape[0] == 0:\n        annotation = \"\"\n    else:\n        for k, row in prediction.pandas().xyxy[0].iterrows():\n            if row.confidence > 0.15:\n                conf = row.confidence\n                x = int(row.xmin)\n                y = int(row.ymin)\n                width = int(row.xmax-row.xmin)\n                height = int(row.ymax-row.ymin)\n                annotation += \"{} {} {} {} {}\".format(conf, x, y, width, height)\n    \n    sample_prediction_df['annotations'] = annotation.strip(' ')\n    \n    # Register your predictions\n    env.predict(sample_prediction_df)","metadata":{"execution":{"iopub.status.busy":"2022-04-18T14:32:03.641521Z","iopub.status.idle":"2022-04-18T14:32:03.64215Z","shell.execute_reply.started":"2022-04-18T14:32:03.641916Z","shell.execute_reply":"2022-04-18T14:32:03.641942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}