{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nfrom tqdm.notebook import tqdm\ntqdm.pandas()\nimport pandas as pd\nimport os\nimport pickle\nimport cv2\nimport ast\nimport glob\n\nfrom shutil import copyfile\nimport sys\nfrom sklearn.model_selection import StratifiedKFold\nsys.path.append('../input/tensorflow-great-barrier-reef')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-12T09:44:35.132628Z","iopub.execute_input":"2022-01-12T09:44:35.133121Z","iopub.status.idle":"2022-01-12T09:44:35.146086Z","shell.execute_reply.started":"2022-01-12T09:44:35.133083Z","shell.execute_reply":"2022-01-12T09:44:35.145166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Set up paths","metadata":{}},{"cell_type":"code","source":"ROOT_DIR  = '/kaggle/input/tensorflow-great-barrier-reef/'\nHOME_DIR = '/kaggle/working/'\nDATASET_PATH = 'COTS-YOLOv5-StratifiedKFold'\nLABEL_DIR = '/kaggle/labels' # to save yolo converted labels\nFOLD = 4 # number of folds to train","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:00:49.240372Z","iopub.execute_input":"2022-01-12T10:00:49.240822Z","iopub.status.idle":"2022-01-12T10:00:49.246034Z","shell.execute_reply.started":"2022-01-12T10:00:49.240791Z","shell.execute_reply":"2022-01-12T10:00:49.245251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir {HOME_DIR}{DATASET_PATH}\n!mkdir {HOME_DIR}{DATASET_PATH}/images\n!mkdir {HOME_DIR}{DATASET_PATH}/images/train\n!mkdir {HOME_DIR}{DATASET_PATH}/images/val\n!mkdir {HOME_DIR}{DATASET_PATH}/labels\n!mkdir {HOME_DIR}{DATASET_PATH}/labels/train\n!mkdir {HOME_DIR}{DATASET_PATH}/labels/val\n!mkdir {LABEL_DIR}","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:00:51.661369Z","iopub.execute_input":"2022-01-12T10:00:51.662003Z","iopub.status.idle":"2022-01-12T10:00:57.746501Z","shell.execute_reply.started":"2022-01-12T10:00:51.661929Z","shell.execute_reply":"2022-01-12T10:00:57.745287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper Functions","metadata":{}},{"cell_type":"code","source":"def get_path(row):\n    row['image_path'] = f'{ROOT_DIR}/train_images/video_{row.video_id}/{row.video_frame}.jpg'\n    row['label_path'] = f'{LABEL_DIR}/video_{row.video_id}_{row.video_frame}.txt'\n    return row\n\ndef get_bbox(annots):\n    bboxes = [list(annot.values()) for annot in annots]\n    return bboxes\n\ndef get_imgsize(row):\n    row['width'], row['height'] = imagesize.get(row['image_path'])\n    return row","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:01:16.356224Z","iopub.execute_input":"2022-01-12T10:01:16.357018Z","iopub.status.idle":"2022-01-12T10:01:16.368293Z","shell.execute_reply.started":"2022-01-12T10:01:16.356969Z","shell.execute_reply":"2022-01-12T10:01:16.367481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def coco2yolo(image_height, image_width, bboxes):\n    \"\"\"\n    coco => [xmin, ymin, w, h]\n    yolo => [xmid, ymid, w, h] (normalized)\n    \"\"\"\n    \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # normolizinig\n    bboxes[..., [0, 2]]= bboxes[..., [0, 2]]/ image_width\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    return bboxes","metadata":{"execution":{"iopub.status.busy":"2022-01-12T09:44:40.45659Z","iopub.execute_input":"2022-01-12T09:44:40.456934Z","iopub.status.idle":"2022-01-12T09:44:40.474146Z","shell.execute_reply.started":"2022-01-12T09:44:40.456905Z","shell.execute_reply":"2022-01-12T09:44:40.473385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modify train dataframe","metadata":{}},{"cell_type":"code","source":"# Train Data\ndf = pd.read_csv(f'{ROOT_DIR}/train.csv')\ndf = df.progress_apply(get_path, axis=1) # add image path to dataframe\ndf['annotations'] = df['annotations'].progress_apply(lambda x: ast.literal_eval(x)) # str to list\ndf['num_bbox'] = df['annotations'].progress_apply(lambda x: len(x))\ndf = df.query(\"num_bbox>0\") # take only rows which contains bounding boxes\ndf['bboxes'] = df.annotations.progress_apply(get_bbox) # add number of bboxes column\n# image resolution\ndf['width']  = 1280\ndf['height'] = 720\ndisplay(df.head(5))","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:01:22.172686Z","iopub.execute_input":"2022-01-12T10:01:22.173025Z","iopub.status.idle":"2022-01-12T10:01:54.226866Z","shell.execute_reply.started":"2022-01-12T10:01:22.172991Z","shell.execute_reply":"2022-01-12T10:01:54.226019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# StratifiedKFold","metadata":{}},{"cell_type":"code","source":"kf = StratifiedKFold(n_splits = 5)\ndf = df.reset_index(drop=True)\ndf['fold'] = -1\n\nfor fold, (train_idx, val_idx) in enumerate(kf.split(df, y=df.video_id.tolist(), groups=df.sequence)):\n    df.loc[val_idx, 'fold'] = fold\n    \ndisplay(df.fold.value_counts())   \ndf.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:01:54.228859Z","iopub.execute_input":"2022-01-12T10:01:54.229137Z","iopub.status.idle":"2022-01-12T10:01:54.271176Z","shell.execute_reply.started":"2022-01-12T10:01:54.229105Z","shell.execute_reply":"2022-01-12T10:01:54.270485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save images","metadata":{}},{"cell_type":"code","source":"for i in tqdm(range(len(df))):\n    \n    row = df.loc[i]\n    \n    if row.fold != FOLD: # train\n        copyfile(f'{row.image_path}', f'{HOME_DIR}{DATASET_PATH}/images/train/{row.image_id}.jpg')\n    \n    elif row.fold == FOLD: # val\n        copyfile(f'{row.image_path}', f'{HOME_DIR}{DATASET_PATH}/images/val/{row.image_id}.jpg')","metadata":{"execution":{"iopub.status.busy":"2022-01-12T09:46:10.261558Z","iopub.execute_input":"2022-01-12T09:46:10.261863Z","iopub.status.idle":"2022-01-12T09:47:15.280077Z","shell.execute_reply.started":"2022-01-12T09:46:10.261832Z","shell.execute_reply":"2022-01-12T09:47:15.279187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert YOLO annotation format","metadata":{}},{"cell_type":"code","source":"cnt = 0\nall_bboxes = []\nfor row_idx in tqdm(range(df.shape[0])):\n    row = df.iloc[row_idx]\n    image_height = row.height\n    image_width  = row.width\n    bboxes_coco  = np.array(row.bboxes).astype(np.float32).copy()\n    num_bbox     = len(bboxes_coco)\n    names        = ['cots']*num_bbox\n    labels       = [0]*num_bbox\n    ## Create Annotation(YOLO)\n    with open(row.label_path, 'w') as f:\n        if num_bbox<1:\n            annot = ''\n            f.write(annot)\n            cnt+=1\n            continue\n        bboxes_yolo  = coco2yolo(image_height, image_width, bboxes_coco)\n        bboxes_yolo  = np.clip(bboxes_yolo, 0, 1)\n        all_bboxes.extend(bboxes_yolo)\n        for bbox_idx in range(len(bboxes_yolo)):\n            annot = [str(labels[bbox_idx])]+ list(bboxes_yolo[bbox_idx].astype(str))+(['\\n'] if num_bbox!=(bbox_idx+1) else [''])\n            annot = ' '.join(annot)\n            annot = annot.strip(' ')\n            f.write(annot)\nprint('Missing:',cnt)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:01:57.045405Z","iopub.execute_input":"2022-01-12T10:01:57.046403Z","iopub.status.idle":"2022-01-12T10:02:00.227002Z","shell.execute_reply.started":"2022-01-12T10:01:57.046363Z","shell.execute_reply":"2022-01-12T10:02:00.226008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save annotations","metadata":{}},{"cell_type":"code","source":"for i in tqdm(range(len(df))):\n    \n    row = df.loc[i]\n    \n    if row.fold != FOLD: # train\n        copyfile(f'{row.label_path}', f'{HOME_DIR}{DATASET_PATH}/labels/train/{row.image_id}.txt')\n    \n    elif row.fold == FOLD: # val\n        copyfile(f'{row.label_path}', f'{HOME_DIR}{DATASET_PATH}/labels/val/{row.image_id}.txt')","metadata":{"execution":{"iopub.status.busy":"2022-01-12T10:02:02.647892Z","iopub.execute_input":"2022-01-12T10:02:02.648274Z","iopub.status.idle":"2022-01-12T10:02:04.654861Z","shell.execute_reply.started":"2022-01-12T10:02:02.648235Z","shell.execute_reply":"2022-01-12T10:02:04.653802Z"},"trusted":true},"execution_count":null,"outputs":[]}]}