{"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\nimport pandas as pd\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\nimport csv\nfrom copy import deepcopy\nfrom skimage.measure import label\nimport argparse\nimport sys\nfrom glob import glob\nimport cv2\nimport csv\nimport torch\nimport torch.backends.cudnn as cudnn\nimport yaml\nfrom albumentations.augmentations import transforms\nfrom albumentations.core.composition import Compose\nfrom sklearn.model_selection import train_test_split\nfrom tqdm import tqdm\nimport numpy as np\nfrom sklearn.model_selection import KFold\nfrom collections import OrderedDict\nimport pandas as pd\n\nimport torch\nfrom torch import nn","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:12:33.916479Z","iopub.execute_input":"2021-06-14T12:12:33.916814Z","iopub.status.idle":"2021-06-14T12:12:33.932367Z","shell.execute_reply.started":"2021-06-14T12:12:33.916785Z","shell.execute_reply":"2021-06-14T12:12:33.931586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"__all__ = ['UNet', 'NestedUNet']\n\nclass VGGBlock(nn.Module):\n    def __init__(self, in_channels, middle_channels, out_channels):\n        super().__init__()\n        self.relu = nn.ReLU(inplace=True)\n        self.conv1 = nn.Conv2d(in_channels, middle_channels, 3, padding=1)\n        self.bn1 = nn.BatchNorm2d(middle_channels)\n        self.conv2 = nn.Conv2d(middle_channels, out_channels, 3, padding=1)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n\n    def forward(self, x):\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        return out\n\n\nclass UNet(nn.Module):\n    def __init__(self, num_classes, input_channels=3, **kwargs):\n        super().__init__()\n\n        nb_filter = [32, 64, 128, 256, 512]\n\n        self.pool = nn.MaxPool2d(2, 2)\n        self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n\n        self.conv0_0 = VGGBlock(input_channels, nb_filter[0], nb_filter[0])\n        self.conv1_0 = VGGBlock(nb_filter[0], nb_filter[1], nb_filter[1])\n        self.conv2_0 = VGGBlock(nb_filter[1], nb_filter[2], nb_filter[2])\n        self.conv3_0 = VGGBlock(nb_filter[2], nb_filter[3], nb_filter[3])\n        self.conv4_0 = VGGBlock(nb_filter[3], nb_filter[4], nb_filter[4])\n\n        self.conv3_1 = VGGBlock(nb_filter[3]+nb_filter[4], nb_filter[3], nb_filter[3])\n        self.conv2_2 = VGGBlock(nb_filter[2]+nb_filter[3], nb_filter[2], nb_filter[2])\n        self.conv1_3 = VGGBlock(nb_filter[1]+nb_filter[2], nb_filter[1], nb_filter[1])\n        self.conv0_4 = VGGBlock(nb_filter[0]+nb_filter[1], nb_filter[0], nb_filter[0])\n\n        self.final = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n\n\n    def forward(self, input):\n        x0_0 = self.conv0_0(input)\n        x1_0 = self.conv1_0(self.pool(x0_0))\n        x2_0 = self.conv2_0(self.pool(x1_0))\n        x3_0 = self.conv3_0(self.pool(x2_0))\n        x4_0 = self.conv4_0(self.pool(x3_0))\n\n        x3_1 = self.conv3_1(torch.cat([x3_0, self.up(x4_0)], 1))\n        x2_2 = self.conv2_2(torch.cat([x2_0, self.up(x3_1)], 1))\n        x1_3 = self.conv1_3(torch.cat([x1_0, self.up(x2_2)], 1))\n        x0_4 = self.conv0_4(torch.cat([x0_0, self.up(x1_3)], 1))\n\n        output = self.final(x0_4)\n        return output\n\n\nclass NestedUNet(nn.Module):\n    def __init__(self, num_classes, input_channels=3, deep_supervision=False, **kwargs):\n        super().__init__()\n\n        nb_filter = [32, 64, 128, 256, 512]\n\n        self.deep_supervision = deep_supervision\n\n        self.pool = nn.MaxPool2d(2, 2)\n        self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n\n        self.conv0_0 = VGGBlock(input_channels, nb_filter[0], nb_filter[0])\n        self.conv1_0 = VGGBlock(nb_filter[0], nb_filter[1], nb_filter[1])\n        self.conv2_0 = VGGBlock(nb_filter[1], nb_filter[2], nb_filter[2])\n        self.conv3_0 = VGGBlock(nb_filter[2], nb_filter[3], nb_filter[3])\n        self.conv4_0 = VGGBlock(nb_filter[3], nb_filter[4], nb_filter[4])\n\n        self.conv0_1 = VGGBlock(nb_filter[0]+nb_filter[1], nb_filter[0], nb_filter[0])\n        self.conv1_1 = VGGBlock(nb_filter[1]+nb_filter[2], nb_filter[1], nb_filter[1])\n        self.conv2_1 = VGGBlock(nb_filter[2]+nb_filter[3], nb_filter[2], nb_filter[2])\n        self.conv3_1 = VGGBlock(nb_filter[3]+nb_filter[4], nb_filter[3], nb_filter[3])\n\n        self.conv0_2 = VGGBlock(nb_filter[0]*2+nb_filter[1], nb_filter[0], nb_filter[0])\n        self.conv1_2 = VGGBlock(nb_filter[1]*2+nb_filter[2], nb_filter[1], nb_filter[1])\n        self.conv2_2 = VGGBlock(nb_filter[2]*2+nb_filter[3], nb_filter[2], nb_filter[2])\n\n        self.conv0_3 = VGGBlock(nb_filter[0]*3+nb_filter[1], nb_filter[0], nb_filter[0])\n        self.conv1_3 = VGGBlock(nb_filter[1]*3+nb_filter[2], nb_filter[1], nb_filter[1])\n\n        self.conv0_4 = VGGBlock(nb_filter[0]*4+nb_filter[1], nb_filter[0], nb_filter[0])\n\n        if self.deep_supervision:\n            self.final1 = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n            self.final2 = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n            self.final3 = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n            self.final4 = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n        else:\n            self.final = nn.Conv2d(nb_filter[0], num_classes, kernel_size=1)\n\n\n    def forward(self, input):\n        x0_0 = self.conv0_0(input)\n        x1_0 = self.conv1_0(self.pool(x0_0))\n        x0_1 = self.conv0_1(torch.cat([x0_0, self.up(x1_0)], 1))\n\n        x2_0 = self.conv2_0(self.pool(x1_0))\n        x1_1 = self.conv1_1(torch.cat([x1_0, self.up(x2_0)], 1))\n        x0_2 = self.conv0_2(torch.cat([x0_0, x0_1, self.up(x1_1)], 1))\n\n        x3_0 = self.conv3_0(self.pool(x2_0))\n        x2_1 = self.conv2_1(torch.cat([x2_0, self.up(x3_0)], 1))\n        x1_2 = self.conv1_2(torch.cat([x1_0, x1_1, self.up(x2_1)], 1))\n        x0_3 = self.conv0_3(torch.cat([x0_0, x0_1, x0_2, self.up(x1_2)], 1))\n\n        x4_0 = self.conv4_0(self.pool(x3_0))\n        x3_1 = self.conv3_1(torch.cat([x3_0, self.up(x4_0)], 1))\n        x2_2 = self.conv2_2(torch.cat([x2_0, x2_1, self.up(x3_1)], 1))\n        x1_3 = self.conv1_3(torch.cat([x1_0, x1_1, x1_2, self.up(x2_2)], 1))\n        x0_4 = self.conv0_4(torch.cat([x0_0, x0_1, x0_2, x0_3, self.up(x1_3)], 1))\n\n        if self.deep_supervision:\n            output1 = self.final1(x0_1)\n            output2 = self.final2(x0_2)\n            output3 = self.final3(x0_3)\n            output4 = self.final4(x0_4)\n            return [output1, output2, output3, output4]\n\n        else:\n            output = self.final(x0_4)\n            return output","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:12:38.433283Z","iopub.execute_input":"2021-06-14T12:12:38.433584Z","iopub.status.idle":"2021-06-14T12:12:38.469895Z","shell.execute_reply.started":"2021-06-14T12:12:38.433552Z","shell.execute_reply":"2021-06-14T12:12:38.469172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:07:37.421975Z","iopub.execute_input":"2021-06-14T12:07:37.422328Z","iopub.status.idle":"2021-06-14T12:08:07.096507Z","shell.execute_reply.started":"2021-06-14T12:07:37.422298Z","shell.execute_reply":"2021-06-14T12:08:07.095545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\nDataset = \"stage2_test_final\"\nos.makedirs('stage2_test', exist_ok=True)\nwith zipfile.ZipFile(\"../input/data-science-bowl-2018/\"+Dataset+\".zip\", \"r\") as z:\n    z.extractall(\"stage2_test\")\n\nimg_size = 256\npaths = glob('stage2_test/*')\nos.makedirs('test2_256/images', exist_ok=True)\nos.makedirs('test2_256/masks/0', exist_ok=True)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:12:43.873889Z","iopub.execute_input":"2021-06-14T12:12:43.874191Z","iopub.status.idle":"2021-06-14T12:12:46.773905Z","shell.execute_reply.started":"2021-06-14T12:12:43.874165Z","shell.execute_reply":"2021-06-14T12:12:46.773142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in tqdm(range(len(paths))):\n    path = paths[i]\n    img = cv2.imread(os.path.join(path, 'images',\n                     os.path.basename(path) + '.png'))\n    mask = np.zeros((img.shape[0], img.shape[1]))\n    if len(img.shape) == 2:\n        img = np.tile(img[..., None], (1, 1, 3))\n    if img.shape[2] == 4:\n        img = img[..., :3]\n    img = cv2.resize(img, (img_size, img_size))\n    mask = cv2.resize(mask, (img_size, img_size))\n    cv2.imwrite(os.path.join('test2_256/images',\n                os.path.basename(path) + '.png'), img)\n    cv2.imwrite(os.path.join('test2_256/masks/0',\n                os.path.basename(path) + '.png'), (mask * 255).astype('uint8'))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:12:51.742055Z","iopub.execute_input":"2021-06-14T12:12:51.742380Z","iopub.status.idle":"2021-06-14T12:13:15.357980Z","shell.execute_reply.started":"2021-06-14T12:12:51.742353Z","shell.execute_reply":"2021-06-14T12:13:15.356802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Dataset(torch.utils.data.Dataset):\n    def __init__(self, img_ids, img_dir, mask_dir, img_ext, mask_ext, num_classes, transform=None):\n        self.img_ids = img_ids\n        self.img_dir = img_dir\n        self.mask_dir = mask_dir\n        self.img_ext = img_ext\n        self.mask_ext = mask_ext\n        self.num_classes = num_classes\n        self.transform = transform\n    def __len__(self):\n        return len(self.img_ids)\n    def __getitem__(self, idx):\n        img_id = self.img_ids[idx]\n        \n        img = cv2.imread(os.path.join(self.img_dir, img_id + self.img_ext))\n        mask = []\n        for i in range(self.num_classes):\n            mask.append(cv2.imread(os.path.join(self.mask_dir, str(i),\n                        img_id + self.mask_ext), cv2.IMREAD_GRAYSCALE)[..., None])\n        mask = np.dstack(mask)\n        if self.transform is not None:\n            augmented = self.transform(image=img, mask=mask)\n            img = augmented['image']\n            mask = augmented['mask']\n        \n        img = img.astype('float32') / 255\n        img = img.transpose(2, 0, 1)\n        mask = mask.astype('float32') / 255\n        mask = mask.transpose(2, 0, 1)\n        \n        return img, mask, {'img_id': img_id}","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:20:25.558288Z","iopub.execute_input":"2021-06-14T12:20:25.558795Z","iopub.status.idle":"2021-06-14T12:20:25.568331Z","shell.execute_reply.started":"2021-06-14T12:20:25.558765Z","shell.execute_reply":"2021-06-14T12:20:25.567622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_path = '../input/model-sgd/Best_model/kits19_all_512_NestedUNet_woDS'\n\ndef convert_to_pixel_list(img):\n    flat_img = img.ravel()\n    pixel_list = []\n    start_nr = 0\n    run_length = 0\n    for i in range(len(flat_img)):\n        if flat_img[i] >= 128:\n            if run_length == 0:\n                start_nr = i\n            run_length += 1\n        else:\n            if run_length > 0:\n                pixel_list.append(start_nr)\n                pixel_list.append(run_length)\n                run_length = 0\n    if run_length > 0:\n        pixel_list.append(start_nr)\n        pixel_list.append(run_length)\n    \n    result_as_string = ''\n    for value in pixel_list:\n        result_as_string += ' ' + str(value)\n    result_as_string = result_as_string[1:] # remove first space\n\n    return result_as_string\n\ndef generate_solution_images():\n    with open(f'{model_path}/config.yml' , 'r') as f:\n        config = yaml.load(f, Loader=yaml.FullLoader)\n\n    print('-'*20)\n    for key in config.keys():\n        print('%s: %s' % (key, str(config[key])))\n    print('-'*20)\n\n    cudnn.benchmark = True\n\n    # create model\n    print(\"=> creating model %s\" % config['arch'])\n    model = NestedUNet(config['num_classes'], config['input_channels'], config['deep_supervision'])\n\n    model = model.cpu()\n\n    # Data loading code\n    val_img_ids = glob('test2_256/images/*' + config['img_ext'])\n    val_img_ids = [os.path.splitext(os.path.basename(p))[0] for p in val_img_ids]\n\n    model.load_state_dict(torch.load(f'{model_path}/model.pth', map_location=torch.device('cpu')))\n    model.eval()\n\n    val_transform = Compose([\n        transforms.Resize(config['input_h'], config['input_w']),\n        #geometric.resize.Resize(config['input_h'], config['input_w']),\n        transforms.Normalize(),\n    ])\n\n    val_dataset = Dataset(\n        img_ids=val_img_ids,\n        img_dir='test2_256/images/',\n        mask_dir='test2_256/masks/',\n        img_ext=config['img_ext'],\n        mask_ext=config['mask_ext'],\n        num_classes=config['num_classes'],\n        transform=val_transform)\n    val_loader = torch.utils.data.DataLoader(\n        val_dataset,\n        batch_size=config['batch_size'],\n        shuffle=False,\n        num_workers=config['num_workers'],\n        drop_last=False)\n\n    for c in range(config['num_classes']):\n        os.makedirs(os.path.join(f'outputs', str(c)), exist_ok=True)\n    \n    with torch.no_grad():\n        for input, target, meta in tqdm(val_loader, total=len(val_loader)):\n            input = input.cpu()\n            target = target.cpu()\n\n            # compute output\n            if config['deep_supervision']:\n                output = model(input)[-1]\n            else:\n                output = model(input)\n\n            output = torch.sigmoid(output).cpu().numpy()\n            for i in range(len(output)):\n                for c in range(config['num_classes']):\n                    out_img = (output[i, c] * 255).astype('uint8')\n                    id = meta['img_id'][i]\n                    cv2.imwrite(os.path.join(f'outputs', str(c), meta['img_id'][i] + '.jpg'), out_img)\n    #torch.cuda.empty_cache()\n\ngenerate_solution_images()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T12:20:37.112391Z","iopub.execute_input":"2021-06-14T12:20:37.112911Z","iopub.status.idle":"2021-06-14T13:11:15.347048Z","shell.execute_reply.started":"2021-06-14T12:20:37.112882Z","shell.execute_reply":"2021-06-14T13:11:15.345698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encoding(x):\n    dots = np.where(x.T.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    result_as_string = ''\n    for value in run_lengths:\n        result_as_string += ' ' + str(value)\n    result_as_string = result_as_string[1:] # remove first space\n\n    return result_as_string\n\ndef all_pixel_lists(images):\n    results = []\n    for img in images:\n        results.append(rle_encoding(img))\n    return results\n\ndef segmented_images(mask):\n    results = []\n    lab_img = label(mask)\n    for i in range(1, lab_img.max() + 1):\n        img = lab_img == i\n        if np.count_nonzero(img) > 5:\n            results.append(img)\n    return results\n\ndef main():\n    id_to_shape = {}\n    original_img_dir = glob(os.path.join('stage2_test', \"*\"))\n    for img_dir in original_img_dir:\n        img_id = os.path.basename(os.path.normpath(img_dir)) \n        image_path = os.path.join(img_dir, 'images', img_id+'.png')\n        img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n        id_to_shape[img_id] = (img.shape[1], img.shape[0])\n\n    with open(f'test.csv', 'w', encoding='UTF8', newline='') as f:\n        writer = csv.writer(f)\n        writer.writerow(['ImageId', 'EncodedPixels'])\n        img_paths = glob(os.path.join(f'outputs/0/', \"*\"))\n        k = 0\n        avg_scores = []\n        for img_path in img_paths:\n            print(f'\\r{k+1}/{len(img_paths)}', end='')\n            k += 1\n            img_id = os.path.basename(os.path.normpath(img_path))[:-4]\n            img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)\n            img = cv2.resize(img, id_to_shape[img_id])\n            _, img = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)\n            seg_imgs = segmented_images(img)\n            pixel_lists = all_pixel_lists(seg_imgs)\n            for pixel_list in pixel_lists:\n                writer.writerow([img_id, pixel_list])\n            if len(pixel_list) == 0:\n                writer.writerow([img_id, ''])\n\nmain()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-14T13:35:12.659900Z","iopub.execute_input":"2021-06-14T13:35:12.660394Z","iopub.status.idle":"2021-06-14T13:39:46.361078Z","shell.execute_reply.started":"2021-06-14T13:35:12.660361Z","shell.execute_reply":"2021-06-14T13:39:46.360042Z"},"trusted":true},"execution_count":null,"outputs":[]}]}