{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# installing segmentation models Pytorch\n!pip install ../input/segmentation-models-wheels/timm-0.3.2-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/efficientnet_pytorch-0.6.3-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/pretrainedmodels-0.7.4-py3-none-any.whl\n!pip install ../input/segmentation-models-wheels/segmentation_models_pytorch-0.1.3-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport rasterio\nimport cv2\nimport os\nfrom rasterio.windows import Window\nimport tifffile\nimport torch.nn as nn\nimport numpy as np\nimport pandas as pd\nimport os\nfrom tqdm import tqdm\nfrom PIL import Image\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom skimage import io,transform\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torch import nn\nimport cv2, os, time\nfrom albumentations.pytorch import ToTensor\nimport matplotlib.pyplot as plt\nimport torch, numba\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport gc\nfrom torch.utils.tensorboard import SummaryWriter\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir = '/kaggle/input/hubmap-kidney-segmentation/test'\nimage_files = [file for file in os.listdir(test_dir) if file.split('.')[1] == 'tiff']\nimage_files","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# for img in image_files:\n#     image_ = tifffile.imread(os.path.join(test_dir,img))\n#     print(image_.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_grid(shape, window=512, min_overlap=32):\n    x, y = shape   #(36800, 43780)\n    nx = x // (window - min_overlap) + 1   #36800//(512-32) + 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    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)\n\n\n\n\ndef make_grids(shape,window=512,overlap=0):\n    '''\n    takes input image shape and return slice coordinates. Input can be unpadded image\n    Last leftout frame is handled in a way that an overlaping window is taken\n    eg: if window size = 5 and last x1,x2 = 7,12 and length of x = 15, Then we will take last window as x1,x2=10,15\n    so last 2 windows will be (7,12) and (10,15). Last window will be always overlaping in these cases.\n    '''\n    y,x = shape[0],shape[1]   #h,w\n    nx,ny = x // window, y // window\n    y_,x_ = y - (y%window),x - (x%window)  #if no leftout portion (x%window) will be zero\n    base_x = np.linspace(0,x_,nx+1,dtype=np.int64)\n    base_y = np.linspace(0,y_,ny+1,dtype=np.int64)\n    x1,x2 = base_x[0:-1], base_x[1:]    \n    y1,y2 = base_y[0:-1], base_y[1:]\n    if overlap != 0:\n        sub_x = np.arange(0,nx*overlap,overlap)\n        x1,x2 = x1 - sub_x,x2 - sub_x \n        sub_y = np.arange(0,ny*overlap,overlap)\n        y1,y2 = y1 - sub_y, y2 - sub_y    \n        \n    # Always the last window at the end will be overlapping.\n    # finally we may be left with some frame which is smaller that window size.\n    # So we will append one window at last\n    if y%window != 0: #if reminder !=0 append last window because leftout frame is there\n        y1,y2 = np.append(y1,[y - window]),np.append(y2,[y])\n    if x%window !=0 :\n        x1,x2 = np.append(x1,[x - window]),np.append(x2,[x])\n    \n    \n    slices = np.zeros(shape=(len(x1),len(y1),4),dtype=np.int64)\n    for i in range(len(x1)):\n        for j in range(len(y1)):\n            slices[i, j] = x1[i], x2[i], y1[j], y2[j]\n    slices = slices.reshape(len(x1) * len(y1), 4)\n    return slices\n\n\ndef 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\n\ndef load_ckp(checkpoint_fpath, model):\n    \"\"\"\n    checkpoint_path: path to save checkpoint\n    model: model that we want to load checkpoint parameters into       \n    optimizer: optimizer we defined in previous training\n    \"\"\"\n    # load check point\n    checkpoint = torch.load(checkpoint_fpath,map_location=torch.device('cpu'))\n    # initialize state_dict from checkpoint to model\n    model.load_state_dict(checkpoint['state_dict'])\n    # return model, optimizer, epoch value, min validation loss \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import segmentation_models_pytorch as smp\n\ncheckpoint_path = '/kaggle/input/unetefficientnetb4/FPNbestmodel.pt_34'\n\nmodel = smp.FPN(\n    encoder_name=\"efficientnet-b4\",        # choose encoder, e.g. mobilenet_v2 or efficientnet-b7\n    encoder_weights=None,     # use `imagenet` pretreined weights for encoder initialization\n    in_channels=3,                  # model input channels (1 for grayscale images, 3 for RGB, etc.)\n    classes=1,                      # model output channels (number of classes in your dataset)\n)\nlearning_rate = 1e-3\nmodel.to(device) \nmodel.eval()\nmodel = load_ckp(checkpoint_path, model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from albumentations import *\n\ndef get_transforms(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)):\n    list_transforms = []\n    list_transforms.extend(\n        [\n            Resize(256,256),\n            Normalize(mean=mean, std=std, p=1),\n            ToTensor(),\n        ]\n                            )\n    list_trfms = Compose(list_transforms)\n    return list_trfms\n\n@numba.njit()\ndef rle_numba(pixels):\n    size = len(pixels)\n    points = []\n    if pixels[0] == 1: points.append(0)\n    flag = True\n    for i in range(1, size):\n        if pixels[i] != pixels[i-1]:\n            if flag:\n                points.append(i+1)\n                flag = False\n            else:\n                points.append(i+1 - points[-1])\n                flag = True\n    if pixels[-1] == 1: points.append(size-points[-1]+1)    \n    return points\n\ndef rle_numba_encode(image):\n    pixels = image.flatten(order = 'F')\n    points = rle_numba(pixels)\n    return ' '.join(str(x) for x in points)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"WINDOW = 256*4 #size of crop from large image 1024\ntile_size = 256\nMIN_OVERLAP = 100\n\nstart_time = time.time()\nidentity = rasterio.Affine(1, 0, 0, 0, 1, 0)\nsubm = {}\ntrfm = get_transforms()\nmodel.eval()\n\nfor i, filename in enumerate(image_files):\n    dataset = rasterio.open(os.path.join(test_dir, filename), transform = identity)\n    print(f'Processing image { i + 1 } of shape : {dataset.shape}')\n    slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n    preds = np.zeros(dataset.shape, dtype=np.uint8)\n    for (x1,x2,y1,y2) in tqdm(slices, desc=f'{filename}'):\n        image = dataset.read([1,2,3],\n                    window=Window.from_slices((x1,x2),(y1,y2)))\n       \n        image = np.moveaxis(image, 0, -1)\n        image = trfm(image=image)\n        image = image['image'].unsqueeze(0)\n\n        \n        with torch.no_grad():\n            score = model(image)\n\n            score2 = model(torch.flip(image, [0, 3]))\n            score2 = torch.flip(score2, [3, 0])[0][0]\n\n            score3 = model(torch.flip(image, [1, 2]))\n            score3 = torch.flip(score3, [2, 1])[0][0]\n\n            score_mean = (score + score2 + score3) / 3.0\n            \n            pred = score_mean.sigmoid().detach().cpu().numpy()[0][0]\n\n            score_sigmoid = cv2.resize(pred, (WINDOW, WINDOW))\n            preds[x1:x2,y1:y2] = (score_sigmoid > 0.5).astype(np.uint8)\n            \n    subm[i] = {'id':filename.split('.')[0], 'predicted': rle_numba_encode(preds)}\n    \n    del preds\n    gc.collect();\n    \n    print('done')\n\nelapsed_time = time.time() - start_time\nprint(f'time elapsed: {elapsed_time // 60:.0f} min {elapsed_time % 60:.0f} sec')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.DataFrame.from_dict(subm, orient='index')\nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}