{"cells":[{"metadata":{},"cell_type":"markdown","source":"# final_project\n"},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/timm-efficientdet-pytorch\")\nsys.path.insert(0, \"../input/omegaconf\")\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nsys.path.insert(0, \"../input/yetanotherefficientdetpytorch\")\n\nimport ensemble_boxes\nimport torch\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom torch.utils.data import Dataset,DataLoader\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nimport cv2\nimport gc\nfrom matplotlib import pyplot as plt\nfrom matplotlib import patches as patches\nfrom backbone import EfficientDetBackbone\nfrom torchvision import transforms\nfrom efficientdet.utils import BBoxTransform, ClipBoxes\nfrom typing import Union\nfrom torchvision.ops.boxes import batched_nms","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Functions that will be used later"},{"metadata":{"trusted":true},"cell_type":"code","source":"def invert_affine(metas: Union[float, list, tuple], preds):\n    for i in range(len(preds)):\n        if len(preds[i]['rois']) == 0:\n            continue\n        else:\n            if metas is float:\n                preds[i]['rois'][:, [0, 2]] = preds[i]['rois'][:, [0, 2]] / metas\n                preds[i]['rois'][:, [1, 3]] = preds[i]['rois'][:, [1, 3]] / metas\n            else:\n                new_w, new_h, old_w, old_h, padding_w, padding_h = metas[i]\n                preds[i]['rois'][:, [0, 2]] = preds[i]['rois'][:, [0, 2]] / (new_w / old_w)\n                preds[i]['rois'][:, [1, 3]] = preds[i]['rois'][:, [1, 3]] / (new_h / old_h)\n    return preds\n\n\ndef aspectaware_resize_padding(image, width, height, interpolation=None, means=None):\n    old_h, old_w, c = image.shape\n    if old_w > old_h:\n        new_w = width\n        new_h = int(width / old_w * old_h)\n    else:\n        new_w = int(height / old_h * old_w)\n        new_h = height\n\n    canvas = np.zeros((height, height, c), np.float32)\n    if means is not None:\n        canvas[...] = means\n\n    if new_w != old_w or new_h != old_h:\n        if interpolation is None:\n            image = cv2.resize(image, (new_w, new_h))\n        else:\n            image = cv2.resize(image, (new_w, new_h), interpolation=interpolation)\n\n    padding_h = height - new_h\n    padding_w = width - new_w\n\n    if c > 1:\n        canvas[:new_h, :new_w] = image\n    else:\n        if len(image.shape) == 2:\n            canvas[:new_h, :new_w, 0] = image\n        else:\n            canvas[:new_h, :new_w] = image\n\n    return canvas, new_w, new_h, old_w, old_h, padding_w, padding_h,\n\n\ndef preprocess(*image_path, max_size=512, mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    ori_imgs = [cv2.imread(img_path) for img_path in image_path]\n    normalized_imgs = [(img[..., ::-1] / 255 - mean) / std for img in ori_imgs]\n    imgs_meta = [aspectaware_resize_padding(img, max_size, max_size,\n                                            means=None) for img in normalized_imgs]\n    framed_imgs = [img_meta[0] for img_meta in imgs_meta]\n    framed_metas = [img_meta[1:] for img_meta in imgs_meta]\n\n    return ori_imgs, framed_imgs, framed_metas\n\n\ndef postprocess(x, anchors, regression, classification, regressBoxes, clipBoxes, threshold, iou_threshold):\n    transformed_anchors = regressBoxes(anchors, regression)\n    transformed_anchors = clipBoxes(transformed_anchors, x)\n    scores = torch.max(classification, dim=2, keepdim=True)[0]\n    scores_over_thresh = (scores > threshold)[:, :, 0]\n    out = []\n    for i in range(x.shape[0]):\n        if scores_over_thresh[i].sum() == 0:\n            out.append({\n                'rois': np.array(()),\n                'class_ids': np.array(()),\n                'scores': np.array(()),\n            })\n            continue\n\n        classification_per = classification[i, scores_over_thresh[i, :], ...].permute(1, 0)\n        transformed_anchors_per = transformed_anchors[i, scores_over_thresh[i, :], ...]\n        scores_per = scores[i, scores_over_thresh[i, :], ...]\n        scores_, classes_ = classification_per.max(dim=0)\n        anchors_nms_idx = batched_nms(transformed_anchors_per, scores_per[:, 0], classes_, iou_threshold=iou_threshold)\n\n        if anchors_nms_idx.shape[0] != 0:\n            classes_ = classes_[anchors_nms_idx]\n            scores_ = scores_[anchors_nms_idx]\n            boxes_ = transformed_anchors_per[anchors_nms_idx, :]\n\n            out.append({\n                'rois': boxes_.cpu().numpy(),\n                'class_ids': classes_.cpu().numpy(),\n                'scores': scores_.cpu().numpy(),\n            })\n        else:\n            out.append({\n                'rois': np.array(()),\n                'class_ids': np.array(()),\n                'scores': np.array(()),\n            })\n\n    return out","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_valid_transforms():\n    return A.Compose([\n            ToTensorV2(p=1.0),\n        ], p=1.0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_ROOT_PATH = '../input/global-wheat-detection/test'\n\nclass DatasetRetriever(Dataset):\n\n    def __init__(self, image_ids, transforms=None):\n        super().__init__()\n        self.image_ids = image_ids\n        self.transforms = transforms\n\n    def __getitem__(self, index: int):\n        image_id = self.image_ids[index]\n        image = cv2.imread(f'{DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image /= 255.0\n        if self.transforms:\n            sample = {'image': image}\n            sample = self.transforms(**sample)\n            image = sample['image']\n        return image, image_id\n\n    def __len__(self) -> int:\n        return self.image_ids.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = DatasetRetriever(\n    image_ids=np.array([path.split('/')[-1][:-4] for path in glob(f'{DATA_ROOT_PATH}/*.jpg')]),\n    transforms=get_valid_transforms()\n)\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\ndata_loader = DataLoader(\n    dataset,\n    batch_size=4,\n    shuffle=False,\n    num_workers=2,\n    drop_last=False,\n    collate_fn=collate_fn\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = '../input/selftrained/efficientdet-d7_79_29040.pth'\n\nnet = EfficientDetBackbone(num_classes = 1, compound_coef=7,\n                           ratio=eval('[(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)]'),\n                           scales=eval('[2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)]'))\nnet.load_state_dict(torch.load(weights_path), strict=False)\nnet.eval()\nnet.cuda()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Try one image"},{"metadata":{"trusted":true},"cell_type":"code","source":"image, image_id = dataset[5]\n\nnumpy_image = image.permute(1,2,0).cpu().numpy().copy()\n\nregressBoxes = BBoxTransform()\nclipBoxes = ClipBoxes()\nthreshold = 0.2\nnms_threshold = 0.5\n\nwith torch.no_grad():\n    mean = [0.485, 0.456, 0.406]\n    std = [0.229, 0.224, 0.225]\n    image_path = '../input/global-wheat-detection/test/' + image_id + '.jpg'\n    ori_imgs, framed_imgs, framed_metas = preprocess(image_path, max_size=512, mean=mean, std=std)\n    x = torch.from_numpy(framed_imgs[0])\n    x = x.unsqueeze(0).permute(0, 3, 1, 2)\n    x = x.cuda()\n\n    features, regression, classification, anchors = net(x)\n\n    preds = postprocess(x,\n                        anchors, regression, classification,\n                        regressBoxes, clipBoxes,\n                        threshold, nms_threshold)\n\n    preds = invert_affine(framed_metas, preds)[0]\n\n    scores = preds['scores']\n    class_ids = preds['class_ids']\n    rois = preds['rois']\n\n    rois[:, 2] -= rois[:, 0]\n    rois[:, 3] -= rois[:, 1]\n\n    \nfig ,ax = plt.subplots(1, figsize=(10, 10))\nax.imshow(numpy_image)\nfor bbox in rois:\n    rect = patches.Rectangle((bbox[0], bbox[1]), bbox[2], bbox[3],linewidth=1,edgecolor='r',facecolor='none')\n    ax.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference"},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = []\nmean = [0.485, 0.456, 0.406]\nstd = [0.229, 0.224, 0.225]\n\nfor i in range(len(dataset)):\n    with torch.no_grad():\n        image, image_id = dataset[i]\n        image_path = '../input/global-wheat-detection/test/' + image_id + '.jpg'\n        ori_imgs, framed_imgs, framed_metas = preprocess(image_path, max_size=1024, mean=mean, std=std)\n        x = torch.from_numpy(framed_imgs[0])\n        x = x.unsqueeze(0).permute(0, 3, 1, 2)\n        x = x.cuda()\n\n        features, regression, classification, anchors = net(x)\n\n        preds = postprocess(x,\n                            anchors, regression, classification,\n                            regressBoxes, clipBoxes,\n                            0.2, nms_threshold)\n\n        preds = invert_affine(framed_metas, preds)[0]\n\n        scores = preds['scores']\n        class_ids = preds['class_ids']\n        rois = preds['rois']\n        \n        if rois.ndim == 2:\n            rois[:, 2] -= rois[:, 0]\n            rois[:, 3] -= rois[:, 1]\n            rois = rois.astype(np.int64)\n\n            result = {\n                'image_id': image_id,\n                'PredictionString': format_prediction_string(rois, scores)\n            }\n        \n        else:\n            result = {\n                'image_id': image_id,\n                'PredictionString': ''\n            }\n        results.append(result)\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Thank you for reading my kernel!"}],"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":4,"nbformat_minor":4}