{"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 cv2\nimport matplotlib.pyplot as plt\nimport glob\nimport shutil\nimport sys\nsys.path.append('../input/tensorflow-great-barrier-reef')\nimport torch\nfrom PIL import Image\nfrom IPython.display import display","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:59:05.189746Z","iopub.execute_input":"2022-03-23T12:59:05.190031Z","iopub.status.idle":"2022-03-23T12:59:05.196264Z","shell.execute_reply.started":"2022-03-23T12:59:05.190001Z","shell.execute_reply":"2022-03-23T12:59:05.195212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install bbox-utility --no-index --find-links=file:///kaggle/input/bboxutility2/bbox-utility","metadata":{"execution":{"iopub.status.busy":"2022-03-23T13:29:38.899251Z","iopub.execute_input":"2022-03-23T13:29:38.899996Z","iopub.status.idle":"2022-03-23T13:29:46.067142Z","shell.execute_reply.started":"2022-03-23T13:29:38.899957Z","shell.execute_reply":"2022-03-23T13:29:46.0663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/input/norfair2/\n!pip install commonmark-0.9.1-py2.py3-none-any.whl -f ./ --no-index\n!pip install rich-9.13.0-py3-none-any.whl -f ./ --no-index\n\n!mkdir /kaggle/working/tmp\n!cp -r /kaggle/input/norfair2/filterpy-1.4.5/filterpy-1.4.5/ /kaggle/working/tmp/\n%cd /kaggle/working/tmp/filterpy-1.4.5/\n!pip install . -f ./ --no-index\n!rm -rf /kaggle/working/tmp\n\n# norfair\n%cd /kaggle/input/norfair2/\n!pip install norfair-0.4.0-py3-none-any.whl -f ./ --no-index","metadata":{"execution":{"iopub.status.busy":"2022-03-28T12:24:59.020835Z","iopub.execute_input":"2022-03-28T12:24:59.021272Z","iopub.status.idle":"2022-03-28T12:25:39.783166Z","shell.execute_reply.started":"2022-03-28T12:24:59.021226Z","shell.execute_reply":"2022-03-28T12:25:39.782027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working/","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_DIR  = '/kaggle/input/tensorflow-great-barrier-reef/'\n# CKPT_DIR  = '/kaggle/input/greatbarrierreef-yolov5-train-ds'\nCKPT_PATH = '/kaggle/input/yoloweight/best.pt' # by @steamedsheep\nIMG_SIZE  = 9000\nCONF      = 0.25\nIOU       = 0.40\nAUGMENT   = True","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:37:48.546364Z","iopub.execute_input":"2022-03-23T12:37:48.546635Z","iopub.status.idle":"2022-03-23T12:37:48.553772Z","shell.execute_reply.started":"2022-03-23T12:37:48.546606Z","shell.execute_reply":"2022-03-23T12:37:48.553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train Data\ndf = pd.read_csv(f'{ROOT_DIR}/train.csv')\ndf['image_path'] = f'{ROOT_DIR}/train_images/video_'+df.video_id.astype(str)+'/'+df.video_frame.astype(str)+'.jpg'\ndf['annotations'] = df['annotations'].progress_apply(eval)\ndisplay(df.head(2))","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:37:50.238985Z","iopub.execute_input":"2022-03-23T12:37:50.239505Z","iopub.status.idle":"2022-03-23T12:37:50.67754Z","shell.execute_reply.started":"2022-03-23T12:37:50.239469Z","shell.execute_reply":"2022-03-23T12:37:50.676654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['num_bbox'] = df['annotations'].progress_apply(lambda x: len(x))\ndata = (df.num_bbox>0).value_counts()/len(df)*100\nprint(f\"No BBox: {data[0]:0.2f}% | With BBox: {data[1]:0.2f}%\")","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:37:55.44501Z","iopub.execute_input":"2022-03-23T12:37:55.445268Z","iopub.status.idle":"2022-03-23T12:37:55.543898Z","shell.execute_reply.started":"2022-03-23T12:37:55.44524Z","shell.execute_reply":"2022-03-23T12:37:55.543241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check https://github.com/awsaf49/bbox for source code of following utility functions\nfrom bbox.utils import coco2yolo, coco2voc, voc2yolo, voc2coco\nfrom bbox.utils import draw_bboxes, load_image\nfrom bbox.utils import clip_bbox, str2annot, annot2str\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\n\nnp.random.seed(32)\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-03-23T12:37:57.079047Z","iopub.execute_input":"2022-03-23T12:37:57.079571Z","iopub.status.idle":"2022-03-23T12:37:57.844824Z","shell.execute_reply.started":"2022-03-23T12:37:57.079534Z","shell.execute_reply":"2022-03-23T12:37:57.844069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /root/.config/Ultralytics\n!cp /kaggle/input/yolov5-font/Arial.ttf /root/.config/Ultralytics/","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:38:17.059925Z","iopub.execute_input":"2022-03-23T12:38:17.060187Z","iopub.status.idle":"2022-03-23T12:38:18.388947Z","shell.execute_reply.started":"2022-03-23T12:38:17.060159Z","shell.execute_reply":"2022-03-23T12:38:18.38809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_model(ckpt_path, conf=0.25, iou=0.50):\n    model = torch.hub.load('/kaggle/working/yolov5',\n                           'custom',\n                           path=ckpt_path,\n                           source='local',\n                           force_reload=True)  # local repo\n    model.conf = conf  # NMS confidence threshold\n    model.iou  = iou  # NMS IoU threshold\n    model.classes = None   # (optional list) filter by class, i.e. = [0, 15, 16] for persons, cats and dogs\n    model.multi_label = False  # NMS multiple labels per box\n    model.max_det = 1000  # maximum number of detections per image\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:47:29.716196Z","iopub.execute_input":"2022-03-23T12:47:29.716974Z","iopub.status.idle":"2022-03-23T12:47:29.724926Z","shell.execute_reply.started":"2022-03-23T12:47:29.716933Z","shell.execute_reply":"2022-03-23T12:47:29.724227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(model, img, size=768, augment=False):\n    height, width = img.shape[:2]\n    results = model(img, size=size, augment=augment)  # custom inference size\n    preds   = results.pandas().xyxy[0]\n    bboxes  = preds[['xmin','ymin','xmax','ymax']].values\n    if len(bboxes):\n        bboxes  = voc2coco(bboxes,height,width).astype(int)\n        confs   = preds.confidence.values\n        return bboxes, confs\n    else:\n        return [],[]\n    \ndef format_prediction(bboxes, confs):\n    annot = ''\n    if len(bboxes)>0:\n        for idx in range(len(bboxes)):\n            xmin, ymin, w, h = bboxes[idx]\n            conf             = confs[idx]\n            annot += f'{conf} {xmin} {ymin} {w} {h}'\n            annot +=' '\n        annot = annot.strip(' ')\n    return annot\n\ndef show_img(img, bboxes, bbox_format='yolo'):\n    names  = ['starfish']*len(bboxes)\n    labels = [0]*len(bboxes)\n    img    = draw_bboxes(img = img,\n                           bboxes = bboxes, \n                           classes = names,\n                           class_ids = labels,\n                           class_name = True, \n                           colors = colors, \n                           bbox_format = bbox_format,\n                           line_thickness = 2)\n    return Image.fromarray(img).resize((800, 400))","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:38:42.160296Z","iopub.execute_input":"2022-03-23T12:38:42.160839Z","iopub.status.idle":"2022-03-23T12:38:42.173051Z","shell.execute_reply.started":"2022-03-23T12:38:42.160806Z","shell.execute_reply":"2022-03-23T12:38:42.171563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##############################################################\n#                      Tracking helpers                      #\n##############################################################\n\nimport numpy as np\nfrom norfair import Detection, Tracker\n\n# Helper to convert bbox in format [x_min, y_min, x_max, y_max, score] to norfair.Detection class\ndef to_norfair(detects, frame_id):\n    result = []\n    for x_min, y_min, x_max, y_max, score in detects:\n        xc, yc = (x_min + x_max) / 2, (y_min + y_max) / 2\n        w, h = x_max - x_min, y_max - y_min\n        result.append(Detection(points=np.array([xc, yc]), scores=np.array([score]), data=np.array([w, h, frame_id])))\n        \n    return result\n\n# Euclidean distance function to match detections on this frame with tracked_objects from previous frames\ndef euclidean_distance(detection, tracked_object):\n    return np.linalg.norm(detection.points - tracked_object.estimate)","metadata":{"execution":{"iopub.status.busy":"2022-03-28T12:25:45.341011Z","iopub.execute_input":"2022-03-28T12:25:45.341326Z","iopub.status.idle":"2022-03-28T12:25:46.716174Z","shell.execute_reply.started":"2022-03-28T12:25:45.341292Z","shell.execute_reply":"2022-03-28T12:25:46.715366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def tracking_function(tracker, frame_id, bboxes, scores):\n    \n    detects = []\n    predictions = []\n    \n    if len(scores)>0:\n        for i in range(len(bboxes)):\n            box = bboxes[i]\n            score = scores[i]\n            x_min = int(box[0])\n            y_min = int(box[1])\n            bbox_width = int(box[2])\n            bbox_height = int(box[3])\n            detects.append([x_min, y_min, x_min+bbox_width, y_min+bbox_height, score])\n            predictions.append('{:.2f} {} {} {} {}'.format(score, x_min, y_min, bbox_width, bbox_height))\n#             print(predictions[:-1])\n    # Update tracks using detects from current frame\n    tracked_objects = tracker.update(detections=to_norfair(detects, frame_id))\n    for tobj in tracked_objects:\n        bbox_width, bbox_height, last_detected_frame_id = tobj.last_detection.data\n        if last_detected_frame_id == frame_id:  # Skip objects that were detected on current frame\n            continue\n        # Add objects that have no detections on current frame to predictions\n        xc, yc = tobj.estimate[0]\n        x_min, y_min = int(round(xc - bbox_width / 2)), int(round(yc - bbox_height / 2))\n        score = tobj.last_detection.scores[0]\n\n        predictions.append('{:.2f} {} {} {} {}'.format(score, x_min, y_min, bbox_width, bbox_height))\n        \n    return predictions","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working\n# !rm -r /kaggle/working/yolov5libds\n# !git clone https://github.com/ultralytics/yolov5 # clone\n!cp -r /kaggle/input/yolov5libds/yolov5 /kaggle/working/yolov5\n%cd yolov5\n# %pip install -qr requirements.txt  # install\n\nfrom yolov5 import utils\ndisplay = utils.notebook_init()  # check","metadata":{"execution":{"iopub.status.busy":"2022-03-23T13:46:22.156863Z","iopub.execute_input":"2022-03-23T13:46:22.157136Z","iopub.status.idle":"2022-03-23T13:46:23.77695Z","shell.execute_reply.started":"2022-03-23T13:46:22.157106Z","shell.execute_reply":"2022-03-23T13:46:23.776069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import greatbarrierreef\nenv = greatbarrierreef.make_env()# initialize the environment\niter_test = env.iter_test()      # an iterator which loops over the test set and sample submission","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:48:56.659494Z","iopub.execute_input":"2022-03-23T12:48:56.660106Z","iopub.status.idle":"2022-03-23T12:48:56.686175Z","shell.execute_reply.started":"2022-03-23T12:48:56.660065Z","shell.execute_reply":"2022-03-23T12:48:56.685503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model(CKPT_PATH, conf=CONF, iou=IOU)\n# for idx, (img, pred_df) in enumerate(tqdm(iter_test)):\n#     bboxes, confs  = predict(model, img, size=IMG_SIZE, augment=AUGMENT)\n#     annot          = format_prediction(bboxes, confs)\n#     pred_df['annotations'] = annot\n#     env.predict(pred_df)\ntracker = Tracker(\n    distance_function=euclidean_distance, \n    distance_threshold=30,\n    hit_inertia_min=3,\n    hit_inertia_max=6,\n    initialization_delay=1,\n)\n\nframe_id =0\nfor idx, (img, pred_df) in enumerate(tqdm(iter_test)):\n#     if FDA_aug:\n#         img = FDA_trans(image=img)['image']\n    bboxes, confs  = predict(model, img, size=IMG_SIZE, augment=AUGMENT)\n\n    predictions = tracking_function(tracker, frame_id, bboxes, confs)\n    \n    prediction_str = ' '.join(predictions)\n    pred_df['annotations'] = prediction_str\n    env.predict(pred_df)\n#     if frame_id < 3:\n#         if len(predict_box)>0:\n#             box = [list(map(int,box.split(' ')[1:])) for box in predictions]\n#         else:\n#             box = []\n#         display(show_img(img, box, bbox_format='coco'))\n#     print('Prediction:', pred_df)\n    frame_id += 1","metadata":{"execution":{"iopub.status.busy":"2022-03-23T12:49:06.019466Z","iopub.execute_input":"2022-03-23T12:49:06.019932Z","iopub.status.idle":"2022-03-23T12:49:10.585064Z","shell.execute_reply.started":"2022-03-23T12:49:06.019897Z","shell.execute_reply":"2022-03-23T12:49:10.584401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r /kaggle/working/yolov5/submission.csv /kaggle/working/submission.csv","metadata":{"execution":{"iopub.status.busy":"2022-03-23T14:00:30.162018Z","iopub.execute_input":"2022-03-23T14:00:30.162283Z","iopub.status.idle":"2022-03-23T14:00:30.857065Z","shell.execute_reply.started":"2022-03-23T14:00:30.162253Z","shell.execute_reply":"2022-03-23T14:00:30.856073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.read_csv('submission.csv')\nsub_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-23T13:59:02.11182Z","iopub.execute_input":"2022-03-23T13:59:02.112591Z","iopub.status.idle":"2022-03-23T13:59:02.155072Z","shell.execute_reply.started":"2022-03-23T13:59:02.112549Z","shell.execute_reply":"2022-03-23T13:59:02.154206Z"},"trusted":true},"execution_count":null,"outputs":[]}]}