{"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 ../input/uwm-modules-ishikei/addict-2.4.0-py3-none-any.whl","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-27T03:39:06.795609Z","iopub.execute_input":"2022-07-27T03:39:06.795958Z","iopub.status.idle":"2022-07-27T03:39:39.122976Z","shell.execute_reply.started":"2022-07-27T03:39:06.795870Z","shell.execute_reply":"2022-07-27T03:39:39.121940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install ../input/mmdetection/einops-0.4.1-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:39:39.126891Z","iopub.execute_input":"2022-07-27T03:39:39.127130Z","iopub.status.idle":"2022-07-27T03:40:09.639909Z","shell.execute_reply.started":"2022-07-27T03:39:39.127099Z","shell.execute_reply":"2022-07-27T03:40:09.638159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install ../input/mmdetection/mmcv_full-1.3.17-cp37-cp37m-linux_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:40:09.642073Z","iopub.execute_input":"2022-07-27T03:40:09.642371Z","iopub.status.idle":"2022-07-27T03:40:42.587671Z","shell.execute_reply.started":"2022-07-27T03:40:09.642333Z","shell.execute_reply":"2022-07-27T03:40:42.586657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r ../input/yolov5/yolov5 .","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:40:42.590345Z","iopub.execute_input":"2022-07-27T03:40:42.590614Z","iopub.status.idle":"2022-07-27T03:40:43.929120Z","shell.execute_reply.started":"2022-07-27T03:40:42.590584Z","shell.execute_reply":"2022-07-27T03:40:43.927983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install --retries 0 -r yolov5/requirements.txt","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:40:43.931000Z","iopub.execute_input":"2022-07-27T03:40:43.931294Z","iopub.status.idle":"2022-07-27T03:41:25.859240Z","shell.execute_reply.started":"2022-07-27T03:40:43.931253Z","shell.execute_reply":"2022-07-27T03:41:25.858221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nsys.path.append(\"../input/segmentation-models-pytorch/segmentation_models.pytorch-0.2.1\")\nsys.path.append(\"../input/pretrainedmodels/pretrainedmodels-0.7.4\")\nsys.path.append(\"../input/efficientnet-pytorch/EfficientNet-PyTorch-master\")","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:41:25.861127Z","iopub.execute_input":"2022-07-27T03:41:25.863698Z","iopub.status.idle":"2022-07-27T03:41:25.870100Z","shell.execute_reply.started":"2022-07-27T03:41:25.863651Z","shell.execute_reply":"2022-07-27T03:41:25.869244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nsys.path.append('../input/uwm-modules-ishikei/uwm')","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:41:25.873236Z","iopub.execute_input":"2022-07-27T03:41:25.874135Z","iopub.status.idle":"2022-07-27T03:41:25.880302Z","shell.execute_reply.started":"2022-07-27T03:41:25.874102Z","shell.execute_reply":"2022-07-27T03:41:25.879445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport glob\nimport numpy as np\nimport pandas as pd\nimport shutil\nfrom pathlib import Path\nfrom tqdm.auto import tqdm\nimport cv2\nfrom sklearn.model_selection import GroupKFold\n\n\n# dataset paths.\ninput_dir = Path('../input/uw-madison-gi-tract-image-segmentation')\nwork_dir = Path('./')\n\ntest_len = len(glob.glob(os.path.join(input_dir, \"test\", \"**\", \"*.png\"), recursive = True))\n\nif test_len:\n    df_path = input_dir / 'sample_submission.csv'\n    img_dir = input_dir / 'test'    \nelse:\n    df_path = input_dir / 'train.csv'\n    img_dir = input_dir / 'train'\n\nsave_dir = work_dir / f'test_1channel'\n\nos.makedirs(save_dir / 'images', exist_ok=True)\n\n# make train_df.\ndf_train = pd.read_csv(df_path)\ndf_train = df_train.sort_values([\"id\", \"class\"]).reset_index(drop = True)\ndf_train[\"patient\"] = df_train.id.apply(lambda x: x.split(\"_\")[0])\ndf_train[\"days\"] = df_train.id.apply(lambda x: \"_\".join(x.split(\"_\")[:2]))\n\ndf_tmp = pd.DataFrame()\nall_image_files = sorted([str(x) for x in img_dir.glob(\"*/*/scans/*.png\")], key = lambda x: x.split(\"/\")[3] + \"_\" + x.split(\"/\")[5])\ndf_tmp['image_files'] = all_image_files\ndf_tmp['size_x'] = [int(os.path.basename(_)[:-4].split(\"_\")[-4]) for _ in all_image_files]\ndf_tmp['size_y'] = [int(os.path.basename(_)[:-4].split(\"_\")[-3]) for _ in all_image_files]\ndf_tmp['spacing_x'] = [float(os.path.basename(_)[:-4].split(\"_\")[-2]) for _ in all_image_files]\ndf_tmp['spacing_y'] = [float(os.path.basename(_)[:-4].split(\"_\")[-1]) for _ in all_image_files]\ndf_tmp['slice'] = [int(os.path.basename(_)[:-4].split(\"_\")[-5]) for _ in all_image_files]\ndf_tmp['slice_str'] = ['slice_'+os.path.basename(_)[:-4].split(\"_\")[-5] for _ in all_image_files]\ndf_tmp['case'] = [_.split('/')[-3] for _ in all_image_files]\ndf_tmp['id'] = df_tmp['case'] + '_' + df_tmp['slice_str']\n\ndf_train = df_train.merge(df_tmp, on='id', how='left')\nif test_len==0:\n    df_train = df_train.loc[:500]\nprint(df_train)\n\nall_file_names = []\nfor day, group in tqdm(df_train.groupby(\"days\")):\n    patient = group.patient.iloc[0]\n    file_names = []\n    for i, file_name in enumerate(group.image_files.unique()):\n        new_file_name = f\"{day}_slice_{i+1:0>4}.png\"\n        shutil.copyfile(file_name, save_dir / 'images' / new_file_name)\n\nall_image_files = list(save_dir.glob(\"images/*\"))\nwith open(save_dir / f'test.txt', \"w\") as f:\n    for idx in range(len(all_image_files)):\n        f.write(os.path.basename(all_image_files[idx])[:-4] + \"\\n\")\n","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:41:25.882677Z","iopub.execute_input":"2022-07-27T03:41:25.882899Z","iopub.status.idle":"2022-07-27T03:41:37.784874Z","shell.execute_reply.started":"2022-07-27T03:41:25.882871Z","shell.execute_reply":"2022-07-27T03:41:37.783947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('test_uint8', exist_ok=True)\nall_image_files = list(save_dir.glob(\"images/*\"))\n\nfor name in tqdm(all_image_files):\n    img = cv2.imread(f'{name}',  cv2.IMREAD_ANYDEPTH)\n    img = img / (np.max(img) + 1e-7)\n    img *= 255\n    img = img.astype(np.uint8)\n    cv2.imwrite(f'test_uint8/{os.path.basename(name)}', img)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:41:37.786219Z","iopub.execute_input":"2022-07-27T03:41:37.786719Z","iopub.status.idle":"2022-07-27T03:41:38.425768Z","shell.execute_reply.started":"2022-07-27T03:41:37.786675Z","shell.execute_reply":"2022-07-27T03:41:38.424907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python yolov5/detect.py --img 360 \\\n--source test_uint8 \\\n--weights ../input/uwm-yolov5-weight/best.pt \\\n--project crop_yolov5 --name test \\\n--conf 0.01 --iou 0.4 --max-det 1 \\\n--save-txt --save-conf \\\n--half \\\n--exist-ok \\\n--nosave","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:41:39.224134Z","iopub.execute_input":"2022-07-27T03:41:39.224454Z","iopub.status.idle":"2022-07-27T03:42:03.678145Z","shell.execute_reply.started":"2022-07-27T03:41:39.224390Z","shell.execute_reply":"2022-07-27T03:42:03.677188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r test_uint8","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:03.681701Z","iopub.execute_input":"2022-07-27T03:42:03.681992Z","iopub.status.idle":"2022-07-27T03:42:04.435691Z","shell.execute_reply.started":"2022-07-27T03:42:03.681961Z","shell.execute_reply":"2022-07-27T03:42:04.434579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ann_dir = './crop_yolov5/test/labels'\nann_list = os.listdir(ann_dir)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:04.437505Z","iopub.execute_input":"2022-07-27T03:42:04.438167Z","iopub.status.idle":"2022-07-27T03:42:04.445072Z","shell.execute_reply.started":"2022-07-27T03:42:04.438122Z","shell.execute_reply":"2022-07-27T03:42:04.444054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nimport pandas as pd\n\n\ndef yolo_to_xyxy(name):\n    path = os.path.join(ann_dir, name)\n    with open(path, 'r') as f:\n        boxes = [float(x) for x in f.readline().split()]\n    \n    img = cv2.imread(os.path.join('./test_1channel/images', name.replace('.txt', '.png')), cv2.IMREAD_ANYDEPTH)\n        \n    x,y,w,h = boxes[1:5] # x_center, y_center, w, h\n    score = boxes[-1]\n    x = int(x * img.shape[1])\n    y = int(y * img.shape[0])\n    w = int(w * img.shape[1])\n    h = int(h * img.shape[0])\n    \n    xmin = y-int(h/2)\n    xmax = y+int(h/2)\n    ymin = x-int(w/2)\n    ymax = x+int(w/2)\n    img_yolo = img[y-int(h/2):y+int(h/2), x-int(w/2):x+int(w/2)]\n    return xmin, xmax, ymin, ymax, score\n\n\nnames = []\nxmins = []\nxmaxs = []\nymins = []\nymaxs = []\nscores = []\nfor name in tqdm(ann_list):\n    xmin, xmax, ymin, ymax, score = yolo_to_xyxy(name)\n    \n    names.append(name.replace('.txt', ''))\n    xmins.append(np.clip(xmin,0,None))\n    xmaxs.append(np.clip(xmax,0,None))\n    ymins.append(np.clip(ymin,0,None))\n    ymaxs.append(np.clip(ymax,0,None))\n    scores.append(score)\n\ndf = pd.DataFrame()\ndf['name'] = names\ndf['xmin'] = xmins\ndf['xmax'] = xmaxs\ndf['ymin'] = ymins\ndf['ymax'] = ymaxs\ndf['score'] = scores\ndisplay(df)\ndf.to_csv('boxes.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:04.447090Z","iopub.execute_input":"2022-07-27T03:42:04.448013Z","iopub.status.idle":"2022-07-27T03:42:04.839379Z","shell.execute_reply.started":"2022-07-27T03:42:04.447970Z","shell.execute_reply":"2022-07-27T03:42:04.838524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    def __init__(self, config, checkpoint):\n        self.config = config\n        self.checkpoint = checkpoint\n        \n\nbase_args = [\n    Config(\n        '../input/uwm-weight/062_no_valid/062_crop_512_8stride_no_valid.py',\n        '../input/uwm-weight/062_no_valid/avg_11_20.pth'),\n    Config(\n        '../input/uwm-weight/091_no_valid/091_swin_b_512_no_valid.py',\n        '../input/uwm-weight/091_no_valid/avg_11_20.pth')\n]\n\npos_args = [\n    Config(\n        '../input/uwm-weight/080_no_valid/080_pos_only_swin_l_512_no_valid.py',\n        '../input/uwm-weight/080_no_valid/avg_11_20.pth'),\n    Config(\n        '../input/uwm-weight/081_no_valid/081_pos_only_convnext_xl_512_no_valid.py',\n        '../input/uwm-weight/081_no_valid/avg_11_20.pth'),\n    Config(\n        '../input/uwm-weight/082_no_valid/082_pos_only_l2_512_2_no_valid.py',\n        '../input/uwm-weight/082_no_valid/avg_11_20.pth'),\n    Config(\n        '../input/uwm-weight/090_no_valid/090_pos_only_l2_512_8stride_dice_no_valid.py',\n        '../input/uwm-weight/090_no_valid/avg_11_20.pth')\n]","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:04.841227Z","iopub.execute_input":"2022-07-27T03:42:04.841597Z","iopub.status.idle":"2022-07-27T03:42:04.849863Z","shell.execute_reply.started":"2022-07-27T03:42:04.841549Z","shell.execute_reply":"2022-07-27T03:42:04.848758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nimport glob\nfrom typing import Any\nimport argparse\nimport cv2\nfrom PIL import Image\n\nimport numpy as np\nimport pandas as pd\nimport torch\nfrom tqdm.auto import tqdm\n\nimport mmcv\nfrom mmcv.utils import config\nfrom mmcv.parallel import collate, scatter\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import (get_dist_info, init_dist, load_checkpoint,\n                         wrap_fp16_model)\n\nfrom mmseg.apis import multi_gpu_test, single_gpu_test\nfrom mmseg.datasets import build_dataloader, build_dataset\nfrom mmseg.models import build_segmentor\nfrom mmseg.datasets.pipelines import Compose\n\n\ntrain = pd.read_csv('../input/uw-madison-gi-tract-image-segmentation/train.csv')\ntrain_cases = set([x.split(\"_\")[0] for x in train['id'].unique()])\n\n\ndef rle_encode(img: np.array, thr: float) -> str:\n    img = (img>thr).astype('uint8')\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\n\ndef dice_coef(y_true, y_pred, thr=0.5, dim=(0,1), epsilon=0.001):\n    y_true = y_true.to(torch.float32)\n    y_pred = (y_pred>thr).to(torch.float32)\n    assert y_true.max() <= 1\n    assert y_pred.max() <= 1\n    \n    inter = (y_true*y_pred).sum(dim=dim)\n    den = y_true.sum(dim=dim) + y_pred.sum(dim=dim)\n    \n    dice = ((2*inter+epsilon)/(den+epsilon))\n    return dice\n\n\ndef crop_img_yolo(h, w, name, crop_df):\n    xmin, xmax, ymin, ymax = crop_df[\n        crop_df.name==name.replace('.png','')\n        ][['xmin', 'xmax', 'ymin', 'ymax']].values[0]\n    mask = np.zeros((h,w))\n    mask[xmin:xmax, ymin:ymax] = 1\n    crop_shape = np.ix_(mask.any(1),mask.any(0))\n    return crop_shape  \n\n\ndef crop_img(img, tol=300, shape_thr=64):\n    assert img.ndim == 2\n    mask = img>tol\n\n    crop_shape = np.ix_(mask.any(1),mask.any(0))\n\n    check_shape = img[crop_shape].shape[0]\n    if check_shape < shape_thr:\n        return None\n    else:\n        xmax = np.max(crop_shape[0])\n        xmin = np.min(crop_shape[0])\n        ymax = np.max(crop_shape[1])\n        ymin = np.min(crop_shape[1])\n        mask2 = np.zeros(img.shape)\n        mask2[xmin:xmax, ymin:ymax] = 1\n        crop_shape2 = np.ix_(mask2.any(1),mask2.any(0))\n        return crop_shape2\n        \n\nclass LoadMultiSliceImage:\n    \"\"\"A simple pipeline to load image.\"\"\"\n    def __init__(self, slice_range, crop=True, crop_type='cv2', clip=False):\n        self.slice_range = slice_range\n        self.crop = crop\n        self.crop_type = crop_type\n        self.clip = clip\n        \n        if crop_type == 'yolo':\n            self.crop_df = pd.read_csv('boxes.csv')\n        else:\n            self.crop_df = None\n    \n    def get_index(self, gallery_list, query):\n        for i, e in enumerate(gallery_list):\n            if query in e: return i\n        raise IndexError\n    \n    def crop_img(self, img, tol=300, shape_thr=64):\n        assert img.ndim == 2\n        mask = img>tol\n\n        crop_shape = np.ix_(mask.any(1),mask.any(0))\n\n        check_shape = img[crop_shape].shape[0]\n        if check_shape < shape_thr:\n            return None\n        else:\n            xmax = np.max(crop_shape[0])\n            xmin = np.min(crop_shape[0])\n            ymax = np.max(crop_shape[1])\n            ymin = np.min(crop_shape[1])\n            mask2 = np.zeros(img.shape)\n            mask2[xmin:xmax, ymin:ymax] = 1\n            crop_shape2 = np.ix_(mask2.any(1),mask2.any(0))\n            return crop_shape2\n        \n    def crop_img_yolo(self, img, name):\n        xmin, xmax, ymin, ymax = self.crop_df[\n            self.crop_df.name==name.replace('.png','')\n            ][['xmin', 'xmax', 'ymin', 'ymax']].values[0]\n        mask = np.zeros(img.shape)\n        mask[xmin:xmax, ymin:ymax] = 1\n        crop_shape = np.ix_(mask.any(1),mask.any(0))\n        return crop_shape\n    \n    def clip_outlier(self, img):\n        c_min, c_max = np.percentile(img, [0, 99])\n        return np.clip(img, c_min, c_max)\n\n    def __call__(self, results):\n        \"\"\"Call function to load images into results.\n\n        Args:\n            results (dict): A result dict contains the file name\n                of the image to be read.\n\n        Returns:\n            dict: ``results`` will be returned containing loaded image.\n            filename, ori_filename, img, img_shape, ori_shape\n        \"\"\"\n        filename = results['filename']\n        splits = os.path.basename(filename).split(\"_\")\n        slice_num_index = self.get_index(splits, '.png')\n        slice_num = int(splits[slice_num_index].replace('.png', ''))\n        \n        # make slices.\n        _diff = self.slice_range // 2\n        _step = 1\n        _range = list(range(slice_num-_diff*_step, slice_num+_diff*_step+1, _step))\n        _med_index = _range.index(slice_num)\n        \n        imgs = []\n        for i in _range:\n            filename_i = [_ for _ in splits]\n            if 'slice' in filename:\n                filename_i[slice_num_index] = f\"{i:0>4}\"\n            else:    \n                filename_i[slice_num_index] = f\"{i}\"\n            filename_i = os.path.join(os.path.dirname(filename), \"_\".join(filename_i))+'.png'\n            if os.path.exists(filename_i):\n                img = cv2.imread(filename_i, cv2.IMREAD_ANYDEPTH)\n            else:\n                img = cv2.imread(filename, cv2.IMREAD_ANYDEPTH)\n                img[:,:] = 0\n            if self.clip:\n                img = self.clip_outlier(img)\n            imgs.append(img)\n        img = np.stack(imgs).transpose(1,2,0)\n        \n        crop_shape = None\n        if self.crop:\n            crop_img = img[...,_med_index]\n            if self.crop_type == 'cv2':\n                crop_shape = self.crop_img(crop_img)\n            elif self.crop_type == 'yolo':\n                crop_shape = self.crop_img_yolo(crop_img, os.path.basename(filename))\n            if crop_shape is not None:\n                imgs = []\n                for i in range(img.shape[-1]):\n                    imgs.append(img[...,i][crop_shape])\n                img = np.stack(imgs).transpose(1,2,0)  \n        \n        img = img.astype(np.float32) / (img.max() + 1e-7)\n\n        results['filename'] = filename\n        results['ori_filename'] = filename\n        results['img'] = img\n        results['img_shape'] = img.shape\n        results['ori_shape'] = img.shape\n        results['crop_shape'] = crop_shape\n        return results\n\n\ndef inference_segmentors(models, filename):\n    \"\"\"Inference image(s) with the segmentor.\n\n    Args:\n        model (nn.Module): The loaded segmentor.\n        imgs (str/ndarray or list[str/ndarray]): Either image files or loaded\n            images.\n\n    Returns:\n        (list[Tensor]): The segmentation result.\n    \"\"\"\n    results = []\n    for model in models:\n        cfg = model.cfg\n        device = next(model.parameters()).device  # model device\n        # build the data pipeline\n        test_pipeline = [LoadMultiSliceImage(5, crop_type='yolo', clip=False)] + cfg.data.test.pipeline[1:]\n        test_pipeline = Compose(test_pipeline)\n        # prepare data\n        data = dict(filename=filename)\n        data = test_pipeline(data)\n        data = collate([data], samples_per_gpu=1)\n        if next(model.parameters()).is_cuda:\n            # scatter to specified GPU\n            data = scatter(data, [device])[0]\n        else:\n            data['img_metas'] = [i.data[0] for i in data['img_metas']]\n\n        # forward the model\n        with torch.no_grad():\n            result = model(return_loss=False, rescale=True, **data)\n        results.append(result[0])\n        \n    return np.mean(np.array(results), axis=0)\n\n\ndef inference_segmentors_pos(models, filename):\n    \"\"\"Inference image(s) with the segmentor.\n\n    Args:\n        model (nn.Module): The loaded segmentor.\n        imgs (str/ndarray or list[str/ndarray]): Either image files or loaded\n            images.\n\n    Returns:\n        (list[Tensor]): The segmentation result.\n    \"\"\"\n    cfg = models[0].cfg\n    device = next(models[0].parameters()).device  # model device\n    # build the data pipeline\n    test_pipeline = [LoadMultiSliceImage(5, crop_type='yolo', clip=False)] + cfg.data.test.pipeline[1:]\n    test_pipeline = Compose(test_pipeline)\n    # prepare data\n    data = dict(filename=filename)\n    data = test_pipeline(data)\n    data = collate([data], samples_per_gpu=1)\n    if next(models[0].parameters()).is_cuda:\n        # scatter to specified GPU\n        data = scatter(data, [device])[0]\n    else:\n        data['img_metas'] = [i.data[0] for i in data['img_metas']]\n    \n    results = []\n    for model in models:\n        # forward the model\n        with torch.no_grad():\n            result = model(return_loss=False, rescale=True, **data)\n        results.append(result[0])\n        \n    return np.mean(np.array(results), axis=0)\n\n\ndef get_model(args):\n    cfg = config.Config.fromfile(args.config)\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n    \n    # dataset config.\n    cfg.data.test.test_mode = True\n    cfg.data.test.data_root = './test_1channel/'\n    cfg.data.test.img_dir = 'images'\n    cfg.data.test.split = 'test.txt'\n        \n    # model config.\n    cfg.model.pretrained = None\n    cfg.model.backbone.pretrained = None\n    cfg.model.test_cfg.logits = True\n    \n    # build the model and load checkpoint\n    cfg.model.train_cfg = None\n    model = build_segmentor(cfg.model, test_cfg=cfg.get('test_cfg'))\n    checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu')\n        \n    torch.cuda.empty_cache()\n    model.cfg = cfg  # save the config in the model for convenience\n    model.to('cuda:0')\n    model.eval()\n    \n    return model, cfg\n\n\ndef is_positive_3ch(result, thrs):\n    return (np.max(result, axis=(0,1))>thrs).any()\n\n\ndef is_positive(result, thr):\n    res = (result>thr)\n    is_pos_sample = (res.astype(float) > 0).any()    \n    return is_pos_sample\n\n\ndef main(base_models, base_cfgs, pos_models, pos_cfgs, model3ds, model3_base, df3d):\n    \n    thrs = [0.5, 0.4, 0.5]\n    pos_thrs = [0.4, 0.4, 0.3]\n    \n    # make holdout names.\n    split_path = os.path.join(base_cfgs[0].data.test.data_root, base_cfgs[0].data.test.split)\n    with open(split_path, 'r') as f:\n        val_names = f.readlines()\n    val_names = [x.rstrip() for x in val_names]\n\n    # inference.\n    torch.cuda.empty_cache()\n    CLASSES = ['large_bowel', 'small_bowel', 'stomach']\n    \n    ids = []\n    classes = []\n    predicteds = []\n    \n    crop_df = pd.read_csv('boxes.csv')\n    show_count = 0\n    \n    for _, group in tqdm(df3d.groupby(['case_id_str', 'day_num_str'])):\n        group_df = group.sort_values('slice_id', ascending=True)\n        n_slices = group_df.shape[0]\n        case = group_df['case_id_str'].iloc[0]\n        day = group_df['day_num_str'].iloc[0]\n        sid = f'case{case}_day{day}'\n\n        imgs = []\n        ids_ = []\n        results_swin = []\n        for idx in range(n_slices):\n            df_ = group_df.iloc[idx]\n            img_name = df_['ID']\n\n            img = mmcv.imread(str(img_dir) + '/' + img_name + '.png',\n                              flag='unchanged')\n            imgs.append(img)\n            ids_.append(df_['id'])\n            \n            img_info = dict(filename=img_name + '.png')\n            results_ = dict(img_info=img_info)\n            results_['seg_fields'] = []\n            results_['img_prefix'] = img_dir\n\n            results_swin.append(results_)\n\n        img = np.stack(imgs).astype(np.float32)[:][np.newaxis]\n\n        results = dict(\n            id=sid,\n            ori_filename=None,\n            filename=None,\n            img=img,\n            ori_shape=img.shape,\n            img_shape=img.shape,\n            pad_shape=img.shape,\n            scale_factor=1.0,\n            keep_ratio=False,\n            flip=False,\n            flip_direction=None,\n        )\n\n        result_1 = inference3d(model3_base[0], results_swin, use_threshold=False)[0]\n        result_2 = inference3d(model3_base[1], results_swin, use_threshold=False)[0]\n        # test a single image\n        # (3, 144, 266, 266)\n        result = inference_3d_ens(model3ds, results, use_threshold=False)[0]\n        # C, D, H, W -> D, H, W, C\n        result = np.transpose(result, (1, 2, 3, 0))\n        \n        for n_sample, name in enumerate(ids_):\n            # inference one image.\n            filename = os.path.join(base_cfgs[0].data.test.data_root, base_cfgs[0].data.test.img_dir, f'{name}.png')\n            res = inference_segmentors(base_models, filename) # res: (x,y,3)\n\n            if is_positive_3ch(res, pos_thrs):\n                pos_res = inference_segmentors_pos(pos_models, filename) # res: (x,y,3)\n            else:\n                pos_res = np.zeros(res.shape)\n\n            # paste to original mask.\n            with Image.open(filename) as f:\n                h,w = f.height, f.width\n\n            new_pred = np.zeros((h, w, 3))\n            new_pred_pos = np.zeros((h, w, 3))\n            crop_shape = crop_img_yolo(h, w, name, crop_df)\n            if crop_shape is not None:\n                new_pred[crop_shape] = res\n                new_pred_pos[crop_shape] = pos_res\n            else:\n                new_pred = res\n                new_pred_pos = pos_res    \n            \n            pred_3d = np.concatenate(\n                [result_1[i][..., n_sample][..., None] * 0.5 + result_2[i][..., n_sample][..., None] * 0.5 for i in range(3)],\n                axis=-1).astype(np.float32)\n            new_pred = new_pred * 0.75 + pred_3d * 0.25\n\n            if test_len==0 and show_count < 10:\n                import copy\n                new_pred_pos_old = copy.deepcopy(new_pred_pos)\n            new_pred_pos = new_pred_pos * 0.8 + result[n_sample] * 0.2\n\n            # replace with pos_model.\n            for i in range(3):\n                if is_positive(new_pred[...,i], pos_thrs[i]):\n                    new_pred[...,i] = new_pred_pos[...,i]\n                    if test_len==0 and show_count < 10:\n                        import matplotlib.pyplot as plt\n                        plt_img = np.concatenate([(new_pred[...,i] > thrs[i]) * 255,\n                                                 (result[n_sample][...,i] > thrs[i]) * 255,\n                                                 (new_pred_pos_old[...,i] > thrs[i]) * 255], axis=1)\n                        plt.imshow(plt_img)\n                        plt.show()\n                        show_count += 1\n\n            # to rle format.\n            for i in range(3):\n                #rle = \"\"\n                rle = rle_encode(new_pred[...,i], thrs[i])\n                ids.append(name)\n                classes.append(CLASSES[i])\n                predicteds.append(rle)\n\n    pred_df = pd.DataFrame({'id': ids, 'class': classes, 'predicted': predicteds})\n    print(pred_df)\n    \n    # make submission.csv\n    data_dir = \"../input/uw-madison-gi-tract-image-segmentation/\"\n    sub = pd.read_csv(os.path.join(data_dir, \"sample_submission.csv\"), usecols=['id', 'class'])\n    \n    if test_len==0:\n        sub['predicted'] = ''\n    else:\n        if len(sub) != len(pred_df): # get score=0\n            sub['predicted'] = ''\n        else:\n            sub = sub.merge(pred_df, on=['id', 'class'], how='left')\n            assert sub['predicted'].isnull().sum()==0 # AssertionError\n            sub['predicted'].fillna(\"\", inplace=True)\n        \n    print(sub)\n    sub[['id', 'class', 'predicted']].to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:04.852242Z","iopub.execute_input":"2022-07-27T03:42:04.853063Z","iopub.status.idle":"2022-07-27T03:42:28.855186Z","shell.execute_reply.started":"2022-07-27T03:42:04.853014Z","shell.execute_reply":"2022-07-27T03:42:28.854178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_models = []\nbase_cfgs = []\nfor base_arg in base_args:\n    base_model, base_cfg = get_model(base_arg)\n    base_models.append(base_model)\n    base_cfgs.append(base_cfg)\n    del base_model\n    torch.cuda.empty_cache()\n\npos_models = []\npos_cfgs = []\nfor pos_arg in pos_args:\n    pos_model, pos_cfg = get_model(pos_arg)\n    pos_models.append(pos_model)\n    pos_cfgs.append(pos_cfg)\n    del pos_model\n    torch.cuda.empty_cache()\n\n# force after loading other models because some components are overwritten\nsys.path.append('../input/monai090/MONAI-0.9.0')\nsys.path.append('../input/uwmcode/kaggle_uwm/')  # noqa\nimport custom_modules  # noqa\nfrom custom_modules.apis import inference_segmentor as inference3d  # noqa\nfrom custom_modules.apis import init_segmentor as init_segmentor3d  # noqa\n\n\n\ndef inference_3d_ens(models, data, use_threshold=True):\n    \"\"\"Inference image(s) with the segmentor.\n\n    Args:\n        model (nn.Module): The loaded segmentor.\n        imgs (str/ndarray or list[str/ndarray]): Either image files or loaded\n            images.\n    Returns:\n        (list[Tensor]): The segmentation result.\n    \"\"\"\n    cfg = models[0].cfg\n    device = next(models[0].parameters()).device  # model device\n    # build the data pipeline\n    # test_pipeline = [LoadImage()] + cfg.data.test.pipeline[1:]\n    test_pipeline = cfg.data.val.pipeline\n    test_pipeline = Compose(test_pipeline)\n    # prepare data\n    data = test_pipeline(data)\n    data = collate([data], samples_per_gpu=1)\n    if next(models[0].parameters()).is_cuda:\n        # scatter to specified GPU\n        data = scatter(data, [device])[0]\n    else:\n        data['img_metas'] = [i.data[0] for i in data['img_metas']]\n\n    # forward the model\n    with torch.no_grad():\n        results = []\n        for model in models:\n            result = model(return_loss=False,\n                           rescale=True,\n                           use_threshold=use_threshold,\n                           **data)\n            results.append(result[0])\n\n    return [np.mean(np.array(results), axis=0)]\n\n\ndef preprocess(df, img_dir_base):\n    data_infos = []\n    for user_id, df_ in tqdm(df.groupby('id')):\n        user_id_split = user_id.split('_')\n        img_dir = img_dir_base + f'{user_id_split[0]}/' \\\n                                 f'{\"_\".join(user_id_split[:2])}/scans'\n        img_path = list(Path(img_dir).glob('*.png'))\n        img_path = [str(p) for p in img_path if user_id_split[-1] in str(p)]\n        assert len(img_path) == 1\n\n        data_info = [\n            df_['id'].values[0],\n            user_id_split[0],\n            img_path[0].replace('.png', '').replace(img_dir_base, ''),\n        ]\n\n        assert len(data_info) == 3\n        data_infos.append(data_info)\n    df = pd.DataFrame(data_infos,\n                      columns=[\n                          'id', 'case', 'ID'\n                      ])\n    return df\n\ncfg = '../input/uwmcode/kaggle_uwm/configs/fold0.py'\nweights = [\n    '../input/uwmtweights/fold0.pth',\n    '../input/uwmtweights/fold1.pth',\n    '../input/uwmtweights/fold2.pth',\n    '../input/uwmtweights/fold3.pth',\n    '../input/uwmtweights/fold4.pth',\n    '../input/uwmtweights/alldata.pth',\n    '../input/uwmtweights/unet3d_trainval_avg.pth',\n]\n\nmodel3ds = []\nfor weight in weights:\n    model3d = init_segmentor3d(cfg,\n                   weight,\n                   device='cuda:0')\n    model3ds.append(model3d)\n    del model3d\n    torch.cuda.empty_cache()\n\ncfg_weights = [\n    ['../input/uwmcode/kaggle_uwm/configs/dynunet3d.py', '../input/uwmtweights/dynunet3d.pth'],\n    ['../input/uwmcode/kaggle_uwm/configs/unet3d.py', '../input/uwmtweights/unet3d.pth'],\n]\nmodel3_base = []\nfor cfg, weight in cfg_weights:\n    model3d = init_segmentor3d(cfg,\n                   weight,\n                   device='cuda:0')\n    model3_base.append(model3d)\n    del model3d\n    torch.cuda.empty_cache()\n\ndf3d = preprocess(df_train, str(img_dir) + '/')\ndf3d['case_id_str'] = df3d['ID'].apply(lambda x: x.split('/')[0])\ndf3d['day_num_str'] = df3d['ID'].apply(lambda x: x.split('/')[1])\ndf3d['slice_id'] = df3d['ID'].apply(lambda x: x.split('/')[3].split('_')[1])\n\nmain(base_models, base_cfgs, pos_models, pos_cfgs, model3ds, model3_base, df3d)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:42:28.857105Z","iopub.execute_input":"2022-07-27T03:42:28.857404Z","iopub.status.idle":"2022-07-27T03:46:09.344848Z","shell.execute_reply.started":"2022-07-27T03:42:28.857363Z","shell.execute_reply":"2022-07-27T03:46:09.340261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r test_1channel\n!rm -r yolov5\n!rm -r crop_yolov5","metadata":{"execution":{"iopub.status.busy":"2022-07-27T03:47:42.312592Z","iopub.execute_input":"2022-07-27T03:47:42.314889Z","iopub.status.idle":"2022-07-27T03:47:45.467018Z","shell.execute_reply.started":"2022-07-27T03:47:42.314844Z","shell.execute_reply":"2022-07-27T03:47:45.465770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}