{"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":"mod_path = '../input/linknet-or-unet-results/'\nimport yaml\nimport pprint\n\nTHRESHOLD = 0.3 # preds > THRESHOLD\nWINDOW = 1024\nMIN_OVERLAP = 300\n\nCHECKSUM = True\nselected_models = [0, 1, 2, 3, 4]\n# selected_models = []\ntorch_model_paths = [\n    '../input/hubmap-model-cv/model_dh_cv5_0.pth',\n    '../input/hubmap-model-cv/model_dh_cv5_2.pth',\n]\nTTAS = [0, 1, 2, 3]\nVOTERS = 0.5\ndef flip(img, axis=0):\n    if axis == 1:\n        return img[::-1, :, ]\n    elif axis == 2:\n        return img[:, ::-1, ]\n    elif axis == 3:\n        return img[::-1, ::-1, ]\n    else:\n        return img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Packages","metadata":{}},{"cell_type":"code","source":"! pip install ../input/kerasapplications/keras-team-keras-applications-3b180cb -f ./ --no-index -q\n! pip install ../input/efficientnet/efficientnet-1.1.0/ -f ./ --no-index -q\n! pip install --no-index ../input/segmentation-models-pytorch/efficientnet_pytorch-0.6.3.tar.gz\n! pip install --no-index ../input/segmentation-models-pytorch/pretrainedmodels-0.7.4.tar.gz\n! pip install --no-index ../input/segmentation-models-pytorch/timm-0.3.2-py3-none-any.whl\n! pip install --no-index ../input/segmentation-models-pytorch/segmentation_models_pytorch-0.1.3-py3-none-any.whl\n! pip install --no-index ../input/segmentation-models-pytorch/typing_extensions-3.7.4.3-py3-none-any.whl","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport glob\nimport gc\n\nimport rasterio\nfrom rasterio.windows import Window\n\nimport pathlib\nfrom tqdm.notebook import tqdm\nimport cv2\n\nimport tensorflow as tf\nimport efficientnet as efn\nimport efficientnet.tfkeras","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os, gc, json, cv2, tifffile, warnings, torch \n\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport matplotlib.cm as cm\nimport matplotlib.colors as colors\n\nfrom pathlib import Path\nfrom torch.utils.data import Dataset as BaseDataset\n\nwarnings.simplefilter('ignore')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Functions","metadata":{}},{"cell_type":"code","source":"def rle_encode_less_memory(img):\n    pixels = img.T.flatten()\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef make_grid(shape, window=256, min_overlap=32):\n    \"\"\"\n        Return Array of size (N,4), where N - number of tiles,\n        2nd axis represente slices: x1,x2,y1,y2 \n    \"\"\"\n    x, y = shape\n    nx = x // (window - min_overlap) + 1\n    x1 = np.linspace(0, x, num=nx, endpoint=False, dtype=np.int64)\n    x1[-1] = x - window\n    x2 = (x1 + window).clip(0, x)\n    ny = y // (window - min_overlap) + 1\n    y1 = np.linspace(0, y, num=ny, endpoint=False, dtype=np.int64)\n    y1[-1] = y - window\n    y2 = (y1 + window).clip(0, y)\n    slices = np.zeros((nx,ny, 4), dtype=np.int64)\n    \n    for i in range(nx):\n        for j in range(ny):\n            slices[i,j] = x1[i], x2[i], y1[j], y2[j]    \n    return slices.reshape(nx*ny,4)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Models","metadata":{}},{"cell_type":"code","source":"identity = rasterio.Affine(1, 0, 0, 0, 1, 0)\nfold_models = []\nfor selected_models_idx in selected_models:\n    fold_model_path = f'../input/linknet-or-unet-results/model-fold-{selected_models_idx}.h5'\n    print('keras:', fold_model_path)\n\n    model = tf.keras.models.load_model(fold_model_path,compile = False)\n    \n    fold_models.append({\n        'type': 'keras',\n        'model': model,\n        'size': 256,\n    })\n\ntorch_models = [torch.load(path) for path in torch_model_paths]\nfor model in torch_models:\n    fold_models.append({\n        'type': 'torch',\n        'model': model,\n        'size': 512,\n    })\n\nprint(len(fold_models))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tfrecords functions","metadata":{}},{"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\nimage_feature = {\n    'image': tf.io.FixedLenFeature([], tf.string),\n    'x1': tf.io.FixedLenFeature([], tf.int64),\n    'y1': tf.io.FixedLenFeature([], tf.int64)\n}\ndef _parse_image(example_proto, tta_mode=0):\n    example = tf.io.parse_single_example(example_proto, image_feature)\n    image = tf.reshape( tf.io.decode_raw(example['image'],out_type=np.dtype('uint8')), (P['DIM'],P['DIM'], 3))\n    \n    # 左右\n    if tta_mode == 2:\n        image = tf.image.flip_left_right(image)\n    # 上下\n    if tta_mode == 1:\n        image = tf.image.flip_up_down(image)\n    # 反转\n    if tta_mode == 3:\n        image = tf.image.rot90(image, k=2)\n        \n    return image, example['x1'], example['y1']\n\ndef load_dataset(filenames, ordered=True, tta_mode=0):\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False\n    dataset = tf.data.TFRecordDataset(filenames)\n    dataset = dataset.with_options(ignore_order)\n    dataset = dataset.map(lambda ex: _parse_image(ex, tta_mode=tta_mode))\n    return dataset\n\ndef get_dataset(FILENAME, tta_mode=0):\n    dataset = load_dataset(FILENAME, tta_mode=tta_mode)\n    dataset  = dataset.batch(64)\n    dataset = dataset.prefetch(AUTO)\n    return dataset","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Results","metadata":{}},{"cell_type":"code","source":"p = pathlib.Path('../input/hubmap-kidney-segmentation')\nsubm = {}\n\nfor i, filename in tqdm(enumerate(p.glob('test/*.tiff')), \n                        total = len(list(p.glob('test/*.tiff')))):\n    \n    print(f'{i+1} Predicting {filename.stem}')\n    \n    dataset = rasterio.open(filename.as_posix(), transform = identity)\n    preds = np.zeros(dataset.shape, dtype=np.uint8)    \n\n    print('SUBMISSION_MODE: FULL')\n    slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n\n    if dataset.count != 3:\n        print('Image file with subdatasets as channels')\n        layers = [rasterio.open(subd) for subd in dataset.subdatasets]\n            \n    for (x1,x2,y1,y2) in slices:\n        if dataset.count == 3:\n            image = dataset.read([1,2,3], window=Window.from_slices((x1,x2),(y1,y2)))\n            image = np.moveaxis(image, 0, -1)\n        else:\n            image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n            for fl in range(3):\n                image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))\n\n        images = {\n            '256': cv2.cvtColor(cv2.resize(image, (256, 256), interpolation=cv2.INTER_AREA), cv2.COLOR_RGB2BGR),\n            '512': cv2.cvtColor(cv2.resize(image, (512, 512), interpolation=cv2.INTER_AREA), cv2.COLOR_RGB2BGR),\n        }\n\n        pred = np.zeros((WINDOW, WINDOW), dtype=np.float32)\n        for fold_model  in fold_models:\n            model = fold_model['model']\n            if fold_model['type'] == 'keras':\n                fold_image = images[str(fold_model['size'])]\n                im_sh = fold_image.shape\n                fold_pred = np.squeeze(model.predict(fold_image.reshape((1, im_sh[0], im_sh[1], im_sh[2]))))\n            elif fold_model['type'] == 'torch':\n                fold_image = images[str(fold_model['size'])]\n                fold_image = fold_image.transpose(2, 0, 1).astype(np.float32) / 255.0\n                \n                fold_pred = model.predict(torch.from_numpy(fold_image).to('cuda').unsqueeze(0))\n                fold_pred = fold_pred.squeeze().cpu().numpy()[1, :, :]\n\n            fold_pred = cv2.resize(fold_pred, (WINDOW, WINDOW))\n            pred += fold_pred\n\n        pred = pred / len(fold_models)\n        preds[x1:x2,y1:y2] += (pred > THRESHOLD).astype(np.uint8)\n\n    preds = (preds > VOTERS).astype(np.uint8)\n    \n    contours, hierarchy = cv2.findContours(preds, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n\n    areas = []\n    c = np.zeros(preds.shape, np.uint8)\n    for contour in contours:\n        area = cv2.contourArea(contour)\n\n        if area < 7000:\n            c = cv2.drawContours(c, [contour], -1, 1, cv2.FILLED)\n\n    preds = np.logical_and(preds, np.logical_not(c)).astype(np.uint8)\n    del contours, c\n    gc.collect()\n    \n    subm[i] = {'id':filename.stem, 'predicted': rle_encode_less_memory(preds)}\n    \n    if CHECKSUM:\n        print('Checksum: '+ str(np.sum(preds)))\n    \n    del preds\n    gc.collect();","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Making submission","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame.from_dict(subm, orient='index')\nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}