{"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":"# !pip install -r /kaggle/input/yolov7-cots-yolov7e6e/yolov7/requirements.txt","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:29.340492Z","iopub.execute_input":"2022-08-01T10:24:29.340928Z","iopub.status.idle":"2022-08-01T10:24:43.233126Z","shell.execute_reply.started":"2022-08-01T10:24:29.340844Z","shell.execute_reply":"2022-08-01T10:24:43.232228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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('/kaggle/input/tensorflow-great-barrier-reef')\nimport torch\nfrom PIL import Image","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:43.235344Z","iopub.execute_input":"2022-08-01T10:24:43.235683Z","iopub.status.idle":"2022-08-01T10:24:45.248918Z","shell.execute_reply.started":"2022-08-01T10:24:43.235652Z","shell.execute_reply":"2022-08-01T10:24:45.247768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_DIR  = '/kaggle/input/tensorflow-great-barrier-reef/'\nCKPT_PATH = '/kaggle/input/yolov7-cots-yolov7e6e/yolov7/runs/train/yolov7-e6e-dim1280-fold1/weights/best.pt'\nIMG_SIZE  = 2560\nCONF      = 0.25\nIOU       = 0.40\nAUGMENT   = True","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:45.250248Z","iopub.execute_input":"2022-08-01T10:24:45.251071Z","iopub.status.idle":"2022-08-01T10:24:45.256167Z","shell.execute_reply.started":"2022-08-01T10:24:45.251036Z","shell.execute_reply":"2022-08-01T10:24:45.254989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !python /kaggle/input/yolov7-cots-yolov7e6e/yolov7/detect.py --weights CKPT_PATH --conf 0.25 --img-size 1280 --source /kaggle/input/tensorflow-great-barrier-reef/train_images/video_0/1002.jpg","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:30:39.303213Z","iopub.execute_input":"2022-08-01T10:30:39.303668Z","iopub.status.idle":"2022-08-01T10:30:39.309116Z","shell.execute_reply.started":"2022-08-01T10:30:39.303631Z","shell.execute_reply":"2022-08-01T10:30:39.307996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from numba import jit\nimport cv2\nimport numpy as np\nimport random\n\n__all__ = ['coco2yolo', 'yolo2coco', 'voc2coco', 'coco2voc', 'yolo2voc', 'voc2yolo',\n           'bbox_iou', 'draw_bboxes', 'load_image']\n\n@jit(nopython=True)\ndef voc2yolo(bboxes, height=720, width=1280):\n    \"\"\"\n    voc  => [x1, y1, x2, y1]\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    bboxes[..., 0::2] /= width\n    bboxes[..., 1::2] /= height\n    \n    bboxes[..., 2] -= bboxes[..., 0]\n    bboxes[..., 3] -= bboxes[..., 1]\n    \n    bboxes[..., 0] += bboxes[..., 2]/2\n    bboxes[..., 1] += bboxes[..., 3]/2\n    \n    return bboxes\n\n@jit(nopython=True)\ndef yolo2voc(bboxes, height=720, width=1280):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    voc  => [x1, y1, x2, y1]\n    \n    \"\"\" \n#     bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    bboxes[..., 0::2] *= width\n    bboxes[..., 1::2] *= height\n    \n    bboxes[..., 0:2] -= bboxes[..., 2:4]/2\n    bboxes[..., 2:4] += bboxes[..., 0:2]\n    \n    return bboxes\n\n@jit(nopython=True)\ndef coco2yolo(bboxes, height=720, width=1280):\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] /= width\n    bboxes[..., 1::2] /= height\n    \n    # converstion (xmin, ymin) => (xmid, ymid)\n    bboxes[..., 0:2] += bboxes[..., 2:4]/2\n    \n    return bboxes\n\n@jit(nopython=True)\ndef yolo2coco(bboxes, height=720, width=1280):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    coco => [xmin, ymin, w, h]\n    \n    \"\"\" \n#     bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # denormalizing\n    bboxes[..., 0::2] *= width\n    bboxes[..., 1::2] *= height\n    \n    # converstion (xmid, ymid) => (xmin, ymin) \n    bboxes[..., 0:2] -= bboxes[..., 2:4]/2\n    \n    return bboxes\n\n@jit(nopython=True)\ndef voc2coco(bboxes, height=720, width=1280):\n    \"\"\"\n    voc  => [xmin, ymin, xmax, ymax]\n    coco => [xmin, ymin, w, h]\n    \n    \"\"\" \n#     bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # converstion (xmax, ymax) => (w, h) \n    bboxes[..., 2:4] -= bboxes[..., 0:2]\n    \n    return bboxes\n\n@jit(nopython=True)\ndef coco2voc(bboxes, height=720, width=1280):\n    \"\"\"\n    coco => [xmin, ymin, w, h]\n    voc  => [xmin, ymin, xmax, ymax]\n    \n    \"\"\" \n#     bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # converstion (w, h) => (w, h) \n    bboxes[..., 2:4] += bboxes[..., 0:2]\n    \n    return bboxes\n\n@jit(nopython=True)\ndef bbox_iou(b1, b2):\n    \"\"\"Calculate the Intersection of Unions (IoUs) between bounding boxes.\n\n    Args:\n        b1 (np.ndarray): An ndarray containing N(x4) bounding boxes of shape (N, 4) in [xmin, ymin, xmax, ymax] format.\n        b2 (np.ndarray): An ndarray containing M(x4) bounding boxes of shape (N, 4) in [xmin, ymin, xmax, ymax] format.\n\n    Returns:\n        np.ndarray: An ndarray containing the IoUs of shape (N, 1)\n    \"\"\"\n#     0 = np.convert_to_tensor(0.0, b1.dtype)\n    # b1 = b1.astype(np.float32)\n    # b2 = b2.astype(np.float32)\n    b1_xmin, b1_ymin, b1_xmax, b1_ymax = np.split(b1, 4, axis=-1)\n    b2_xmin, b2_ymin, b2_xmax, b2_ymax = np.split(b2, 4, axis=-1)\n    b1_height = np.maximum(0, b1_ymax - b1_ymin)\n    b1_width  = np.maximum(0, b1_xmax - b1_xmin)\n    b2_height = np.maximum(0, b2_ymax - b2_ymin)\n    b2_width  = np.maximum(0, b2_xmax - b2_xmin)\n    b1_area = b1_height * b1_width\n    b2_area = b2_height * b2_width\n\n    intersect_xmin = np.maximum(b1_xmin, b2_xmin)\n    intersect_ymin = np.maximum(b1_ymin, b2_ymin)\n    intersect_xmax = np.minimum(b1_xmax, b2_xmax)\n    intersect_ymax = np.minimum(b1_ymax, b2_ymax)\n    intersect_height = np.maximum(0, intersect_ymax - intersect_ymin)\n    intersect_width  = np.maximum(0, intersect_xmax - intersect_xmin)\n    intersect_area   = intersect_height * intersect_width\n\n    union_area = b1_area + b2_area - intersect_area\n    iou = np.nan_to_num(intersect_area/union_area).squeeze()\n    \n    return iou\n\n@jit(nopython=True)\ndef clip_bbox(bboxes_voc, height=720, width=1280):\n    \"\"\"Clip bounding boxes to image boundaries.\n\n    Args:\n        bboxes_voc (np.ndarray): bboxes in [xmin, ymin, xmax, ymax] format.\n        height (int, optional): height of bbox. Defaults to 720.\n        width (int, optional): width of bbox. Defaults to 1280.\n\n    Returns:\n        np.ndarray : clipped bboxes in [xmin, ymin, xmax, ymax] format.\n    \"\"\"\n    bboxes_voc[..., 0::2] = np.clip(bboxes_voc[..., 0::2], 0, width)\n    bboxes_voc[..., 1::2] = np.clip(bboxes_voc[..., 1::2], 0, height)\n    return bboxes_voc\n\ndef str2annot(data):\n    \"\"\"Generate annotation from string.\n    \n    Args:\n        data (str): string of annotation.\n    \n    Returns:\n        np.ndarray: annotation in array format.\n    \"\"\"\n    data  = data.replace('\\n', ' ')\n    data  = np.array(data.split(' '))\n    annot = data.astype(float).reshape(-1, 5)\n    return annot\n\ndef annot2str(data):\n    \"\"\"Generate string from annotation.\n    \n    Args:\n        data (np.ndarray): annotation in array format.\n    \n    Returns:\n        str: annotation in string format.\n    \"\"\"\n    data   = data.astype(str)\n    string = '\\n'.join([' '.join(annot) for annot in data])\n    return string\n\ndef load_image(image_path):\n    return cv2.imread(image_path)[..., ::-1]\n\n\ndef plot_one_box(x, img, color=None, label=None, line_thickness=None):\n    # Plots one bounding box on image img\n    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness\n    color = color or [random.randint(0, 255) for _ in range(3)]\n    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))\n    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)\n    if label:\n        tf = max(tl - 1, 1)  # font thickness\n        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]\n        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3\n        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled\n        cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)\n\ndef draw_bboxes(img, bboxes, classes, class_ids, colors = None, show_classes = None, bbox_format = 'yolo', class_name = False, line_thickness = 2):  \n     \n    image = img.copy()\n    show_classes = classes if show_classes is None else show_classes\n    colors = (0, 255 ,0) if colors is None else colors\n    \n    if bbox_format == 'yolo':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes:\n            \n                x1 = round(float(bbox[0])*image.shape[1])\n                y1 = round(float(bbox[1])*image.shape[0])\n                w  = round(float(bbox[2])*image.shape[1]/2) #w/2 \n                h  = round(float(bbox[3])*image.shape[0]/2)\n\n                voc_bbox = (x1-w, y1-h, x1+w, y1+h)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(get_label(cls)),\n                             line_thickness = line_thickness)\n            \n    elif bbox_format == 'coco':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes:            \n                x1 = int(round(bbox[0]))\n                y1 = int(round(bbox[1]))\n                w  = int(round(bbox[2]))\n                h  = int(round(bbox[3]))\n\n                voc_bbox = (x1, y1, x1+w, y1+h)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(cls_id),\n                             line_thickness = line_thickness)\n\n    elif bbox_format == 'voc':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes: \n                x1 = int(round(bbox[0]))\n                y1 = int(round(bbox[1]))\n                x2 = int(round(bbox[2]))\n                y2 = int(round(bbox[3]))\n                voc_bbox = (x1, y1, x2, y2)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(cls_id),\n                             line_thickness = line_thickness)\n    else:\n        raise ValueError('wrong bbox format')\n\n    return image","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:46.143216Z","iopub.execute_input":"2022-08-01T10:24:46.143825Z","iopub.status.idle":"2022-08-01T10:24:47.151374Z","shell.execute_reply.started":"2022-08-01T10:24:46.143788Z","shell.execute_reply":"2022-08-01T10:24:47.150408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from bbox.utils import coco2yolo, coco2voc, voc2yolo, voc2coco\n# from bbox.utils import draw_bboxes, load_image\n# from 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-08-01T10:24:47.152960Z","iopub.execute_input":"2022-08-01T10:24:47.153683Z","iopub.status.idle":"2022-08-01T10:24:47.160674Z","shell.execute_reply.started":"2022-08-01T10:24:47.153644Z","shell.execute_reply":"2022-08-01T10:24:47.159583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_model(ckpt_path, conf=0.25, iou=0.40):\n    model = torch.hub.load('/kaggle/input/yolov7-cots-yolov7e6e/yolov7','custom',\n                           path_or_model=ckpt_path,source='local',force_reload=True)\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-08-01T10:24:47.162282Z","iopub.execute_input":"2022-08-01T10:24:47.163081Z","iopub.status.idle":"2022-08-01T10:24:47.177901Z","shell.execute_reply.started":"2022-08-01T10:24:47.163047Z","shell.execute_reply":"2022-08-01T10:24:47.176779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(model, img, size=3200, 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  = ['cots']*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((1280, 1280))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:47.179461Z","iopub.execute_input":"2022-08-01T10:24:47.180176Z","iopub.status.idle":"2022-08-01T10:24:47.194938Z","shell.execute_reply.started":"2022-08-01T10:24:47.180130Z","shell.execute_reply":"2022-08-01T10:24:47.193740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_DIR  = '/kaggle/input/tensorflow-great-barrier-reef/'\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)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:47.196784Z","iopub.execute_input":"2022-08-01T10:24:47.197231Z","iopub.status.idle":"2022-08-01T10:24:47.838217Z","shell.execute_reply.started":"2022-08-01T10:24:47.197186Z","shell.execute_reply":"2022-08-01T10:24:47.837102Z"},"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_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model(CKPT_PATH, conf=CONF, iou=IOU)\nimage_paths = df[df.num_bbox>1].sample(100).image_path.tolist()\nfor idx, path in enumerate(image_paths):\n    img = cv2.imread(path)[...,::-1]\n    bboxes, confis = predict(model, img, size=IMG_SIZE, augment=AUGMENT)\n    display(show_img(img, bboxes, bbox_format='coco'))\n    if idx>5:\n        break","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:47.842014Z","iopub.execute_input":"2022-08-01T10:24:47.842734Z","iopub.status.idle":"2022-08-01T10:24:49.339006Z","shell.execute_reply.started":"2022-08-01T10:24:47.842696Z","shell.execute_reply":"2022-08-01T10:24:49.337164Z"},"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-08-01T10:24:49.340589Z","iopub.status.idle":"2022-08-01T10:24:49.341734Z","shell.execute_reply.started":"2022-08-01T10:24:49.341382Z","shell.execute_reply":"2022-08-01T10:24:49.341431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = load_model(CKPT_PATH, conf=CONF, iou=IOU)\nfor 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)\n    if idx<3:\n        display(show_img(img, bboxes, bbox_format='coco'))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T10:24:49.343352Z","iopub.status.idle":"2022-08-01T10:24:49.344299Z","shell.execute_reply.started":"2022-08-01T10:24:49.343985Z","shell.execute_reply":"2022-08-01T10:24:49.344015Z"},"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-08-01T10:24:49.346264Z","iopub.status.idle":"2022-08-01T10:24:49.347250Z","shell.execute_reply.started":"2022-08-01T10:24:49.346954Z","shell.execute_reply":"2022-08-01T10:24:49.346982Z"},"trusted":true},"execution_count":null,"outputs":[]}]}