{"cells":[{"metadata":{},"cell_type":"markdown","source":"# <div align = 'center'> HuBMAP: Hacking the Kidney </div>\n# <div align = 'center'> Identify glomeruli in human kidney tissue images </div>"},{"metadata":{},"cell_type":"markdown","source":"# Table of contents <a id='0.1'></a>\n\n1. [Introduction](#1)\n2. [Import Packages](#2)\n3. [Utility Functions](#4)\n4. [Loading Data and overview](#3)\n   * [3.1 Train Data](#5)\n   * [3.2 HuBMAP-Metadata](#6)\n   * [3.3 Test Data](#7)\n   * [3.4 Train Imaegs](#8)\n   * [3.5 Test Images](#9)\n5. [Image + Segmentation Mask](#10)\n   * [4.1 Image Tiff File](#11)\n   * [4.2 Annotation json file](#12)\n6. [EDA](#13)\n   * [Individual Features](#14)\n   * [Pandas Metadata profiling](#15)\n\n7. [Creating Dataset for Training](#16)\n   * [Idea](#17)\n   * [Tiling](#18)\n   * [Visualisation](#19)\n8. [Data Preparation](#20)\n   * [Filtering low band density](#21)\n   * [Augmentation](#22)"},{"metadata":{},"cell_type":"markdown","source":"# 1. <a id='1'>Introduction</a>\n[Table of contents](#0.1)\n\nWe aim to develop a segmentation algorithm to identify the \"Glomerulus\" in the kidney.\n\nWe are given histological images of the kidney and annotation information representing the glomerular segmentation. Also we can use anatomical structure segmentation information and additional information (including anonymized patient data) about each image."},{"metadata":{},"cell_type":"markdown","source":"# 2. <a id='2'>Import Packages</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"%env SM_FRAMEWORK=tf.keras","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# basic\nimport os\nimport cv2\nimport collections\nimport sys, gc\nimport warnings\nimport time, math\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom pathlib import Path\nimport pandas_profiling as pp\nfrom tqdm.notebook import tqdm\n\n# visualize\nimport seaborn as sn\nimport matplotlib.pyplot as plt\n \n# image preprocessing \nimport json\nimport rasterio\nimport skimage.io\nimport tifffile as tiff\nimport zipfile\nfrom rasterio.windows import Window\nfrom PIL import Image, ImageDraw\nfrom IPython.display import clear_output, Image as displayImage, display\n\n# kaggle datasets\n# from kaggle_datasets import KaggleDatasets\n\n# # deep learning\nimport tensorflow as tf\n# import segmentation_models as sm\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.models import Model, load_model\nfrom tensorflow.keras.utils import get_custom_objects\nfrom tensorflow.keras.losses import binary_crossentropy\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, Callback, LearningRateScheduler\n\n# # cross validation\nfrom sklearn.model_selection import KFold\nfrom sklearn.model_selection import train_test_split\n\n# # logging\nimport wandb\nfrom wandb.keras import WandbCallback\nfrom kaggle_secrets import UserSecretsClient\n\n%matplotlib inline\nwarnings.filterwarnings('ignore')\nprint(f'Wandb Version: {wandb.__version__}')\nprint(f'Seaborn Version: {sn.__version__}')\nprint(f'Tensorflow Version: {tf.__version__}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. <a id='3'>Loading Data and Overview</a>\n[Table of contents](#0.1)"},{"metadata":{},"cell_type":"markdown","source":"There are 3 .csv files containing\n\n* train\n* test\n* anonymous patient data\n\nThere are addition two folders/directories containing\n\n* images in .tiff format\n* encoded annotations in .json format"},{"metadata":{},"cell_type":"markdown","source":"## 3.1 <a id='5'>Train Data</a>\n[Table of contents](#0.1)\n\nThere are 8 training set. This csv includes ids corresponding to data in train directory. Also it has mask data in \"encoding\" column. This data is encoded with RLE encoding."},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv(\"../input/hubmap-kidney-segmentation/train.csv\")\ntrain.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.2 <a id='6'>HuBMAP metadata</a>\n[Table of contents](#0.1)\n\nThis file includes additional information (including anonymized patient data) about each image"},{"metadata":{"trusted":true},"cell_type":"code","source":"ds_info = pd.read_csv(\"../input/hubmap-kidney-segmentation/HuBMAP-20-dataset_information.csv\")\nds_info.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ds_info.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.3 <a id='7'>Test Data</a>\n[Table of contents](#0.1)\n\nThere are 5 test set"},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.read_csv(\"../input/hubmap-kidney-segmentation/sample_submission.csv\")\ntest.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.4 <a id='8'>Train Images</a>\n[Table of contents](#0.1)\n\n* tiff files are kidney image data.\n* json files include unencoded annotations."},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir(\"../input/hubmap-kidney-segmentation/train\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_1 = tiff.imread('../input/hubmap-kidney-segmentation/train/' + train.iloc[2,0] + \".tiff\")\nimg_id_1 = train.iloc[2,0]\nprint(\"This image's id:\", img_id_1)\nimage_1.shape\n\nplt.figure(figsize=(10, 10))\nplt.imshow(image_1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 3.5 <a id='9'>Test Images</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir(\"../input/hubmap-kidney-segmentation/test\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_1 = tiff.imread('../input/hubmap-kidney-segmentation/test/' + test.iloc[1,0] + \".tiff\")\nimg_id_1 = test.iloc[1,0]\nprint(\"This image's id:\", img_id_1)\nimage_1.shape\n\nplt.figure(figsize=(10, 10))\nplt.imshow(image_1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### <a id='4'>Utility File </a>"},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/paulorzp/rle-functions-run-lenght-encode-decode\ndef mask2rle(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels= img.T.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 \ndef rle2mask(mask_rle, shape=(1600,256)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (width,height) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"def read_single(img_path, msk_path):\n    \"\"\" Read the image and mask from the given path. \"\"\"\n    image = cv2.imread(img_path, cv2.IMREAD_COLOR)\n    mask = cv2.imread(msk_path, cv2.IMREAD_GRAYSCALE)\n    return image, mask\n\ndef read_data(image_paths, mask_paths, gloms_only=False):\n    images = []\n    masks = []\n\n    for img_path, msk_path in tqdm(zip(image_paths, mask_paths), total=len(image_paths)):\n\n        image, mask = read_single(img_path, msk_path)\n        mask_density = np.count_nonzero(mask)   \n        if gloms_only:\n            if(mask_density>0):\n                images.append(image)\n                masks.append(mask)\n        else:\n            images.append(image)\n            masks.append(mask)\n\n    images = np.array(images)\n    masks = np.array(masks)\n    print('images shape:', images.shape)\n    print('masks shape:', masks.shape)\n    return images, masks","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4 <a id='10'>Image + Segmentation Mask</a>\n[Table of contents](#0.1)"},{"metadata":{},"cell_type":"markdown","source":"## 4.1 <a id='11'>Image Tiff file </a>\n[Table of contents](#0.1)\n\nWe are given histological images of the kidney. These images are tiff format. We can load this data with tifffile module."},{"metadata":{"trusted":true},"cell_type":"code","source":"image_1 = tiff.imread('../input/hubmap-kidney-segmentation/train/' + train.iloc[2,0] + \".tiff\")\nimg_id_1 = train.iloc[2,0]\nprint(\"This image's id:\", img_id_1)\nimage_1.shape\n\nplt.figure(figsize=(5,5))\nplt.imshow(image_1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### mask\nWe can decode mask from encoding column of train.csv."},{"metadata":{"trusted":true},"cell_type":"code","source":"mask_1 = rle2mask(train.iloc[2, 1], (image_1.shape[1], image_1.shape[0]))\nmask_1.shape\n\nplt.figure(figsize=(10,10))\nplt.imshow(mask_1, cmap='coolwarm', alpha=0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10,10))\nplt.imshow(image_1)\nplt.imshow(mask_1, cmap='coolwarm', alpha=0.5)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 4.2 <a id='12'>Annotation json file</a>\n[Table of contents](#0.1)\n\nWe have also two kinds of annotation files."},{"metadata":{},"cell_type":"markdown","source":"#### *Glomerulus segmentation file*\nAccording to the description of dataset, the same information as the rle-encoded mask is stored in the .csv file"},{"metadata":{},"cell_type":"markdown","source":"#### *Anatomical structure file*\nThis file contains anatomical structure segmentations. They are intended to help us identify the various parts of the tissues"},{"metadata":{"trusted":true},"cell_type":"code","source":"with open(f\"../input/hubmap-kidney-segmentation/train/aaa6a05cc-anatomical-structure.json\") as f:\n    anatomical_structure_json = json.load(f)\n    \nanatomical_structure_json","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def flatten(l):\n    for el in l:\n        if isinstance(el, collections.abc.Iterable) and not isinstance(el, (str, bytes)):\n            yield from flatten(el)\n        else:\n            yield el\n\ndef draw_structure(structures, im):\n    \"\"\"\n    anatomical_structure: list of points of anatomical_structure poligon.\n    im: numpy array of image read from tiff file.\n    \"\"\"\n    \n    im = Image.fromarray(im)\n    draw = ImageDraw.Draw(im)\n    for structure in structures:\n        structure_flatten = list(flatten(structure[\"geometry\"][\"coordinates\"][0]))\n        structure = []\n        for i in range(0, len(structure_flatten), 2):\n            structure.append(tuple(structure_flatten[i:i+2]))\n        \n        draw.line(structure, width=100, fill='Red')\n    return im\n\nplt.figure(figsize=(8,8))\nimage_1_with_line = draw_structure(anatomical_structure_json, image_1)\nplt.imshow(image_1_with_line)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. <a id='13'>EDA</a>\n[Table of contents](#0.1)\n"},{"metadata":{},"cell_type":"markdown","source":"## 5.1.  <a id='14'>Individual Features</a>"},{"metadata":{"trusted":true},"cell_type":"code","source":"ds_info.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ds_info.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"There are 13 data. Each data has 16 colmuns.\n\n8 data are for training, and rest are test. It includes anonymized patient data."},{"metadata":{"trusted":true},"cell_type":"code","source":"df_info = ds_info\ndf_info[\"split\"] = \"test\"\ndf_info.loc[df_info[\"image_file\"].isin(os.listdir(os.path.join(\"../input/hubmap-kidney-segmentation\", \"train\"))), \n            \"split\"] = \"train\"\ndf_info[\"area\"] = df_info[\"width_pixels\"] * df_info[\"height_pixels\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16, 35))\nplt.subplot(6, 2, 1)\nsn.countplot(x=\"race\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 2)\nsn.countplot(x=\"ethnicity\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 3)\nsn.countplot(x=\"sex\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 4)\nsn.countplot(x=\"laterality\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 5)\nsn.histplot(x=\"age\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 6)\nsn.histplot(x=\"weight_kilograms\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 7)\nsn.histplot(x=\"height_centimeters\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 8)\nsn.histplot(x=\"bmi_kg/m^2\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 9)\nsn.histplot(x=\"percent_cortex\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 10)\nsn.histplot(x=\"percent_medulla\", hue=\"split\", data=df_info)\nplt.subplot(6, 2, 11)\nsn.histplot(x=\"area\", hue=\"split\", data=df_info);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 5.2. <a id='15'>Pandas Metadata Profiling</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://towardsdatascience.com/exploratory-data-analysis-with-pandas-profiling-de3aae2ddff3\n\nmetadata_profile = pp.ProfileReport(ds_info)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"metadata_profile","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 6. <a id='16'>Creating the dataset for training </a>\n[Table of contents](#0.1)"},{"metadata":{},"cell_type":"markdown","source":"## 6.1. <a id='17'>Idea</a>\n[Table of contents](#0.1)"},{"metadata":{},"cell_type":"markdown","source":"Resolution of images are huge and making it hard to analyse and use them to train any model. To make things easy, technique of tiling can be used. I'll start by using the image with the smallest resolution i.e, 7. aaa6a05cc.tiff\n\n### <div align = 'center'> Image Tiling <div/>\nFor the beginning I will split 'aaa6a05cc.tiff' and store all files into the folder split:\n\nImages will be stored in the folder split/images/ Mask-files will be stored in the folder split/masks/ Also I’m going to implement filtering. Images with 0-mask and located in the firs/last 2 rows/columns are totally useless for a further model training. Even in this case I will still have some 0-mask images, it also will be useful for the model\n\n#### Idea:\n* taking a random tile size (preferred 256 X 256 or 512 X 512)\n* aligning the tile with the image and cropping out\n* save the cropped file to the designated location\n* move the tile forward and repeat the process\n* repeat the same process with the corresponding annotation file\n    \n#### Input:\n* image file\n* train.csv for annotation\n\n#### Output:\n* A file containing info about created dataset\n* A zip file containg tiled out images and mask"},{"metadata":{},"cell_type":"markdown","source":"## 6.2. <a id='18'>Tiling</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"os.makedirs('../output')\ninput_dir = '../input/hubmap-kidney-segmentation/train'\noutput_dir = '../output'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#loading the CSVs\n\ndf = pd.read_csv(f'../input/hubmap-kidney-segmentation/train.csv')\nsub_df = pd.read_csv(f'../input/hubmap-kidney-segmentation/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Those folders will store our images\nos.makedirs(f'train_tiles/images', exist_ok=True)\nos.makedirs(f'train_tiles/masks', exist_ok=True)\n\n# This list will contain information about all our images\nmeta_ls = []\n\n#defining tile size\ntile_size = 256\n#we can decreses the tile size to 256 X 256 to get even more number of images after tiling\n\n# The break down starts here\nfor ix in range(1):\n    img_id = df.id[ix]\n    path = f\"../input/hubmap-kidney-segmentation/train/aaa6a05cc.tiff\"\n    img = skimage.io.imread(path).squeeze()\n    mask = rle2mask(df.encoding[ix], shape=img.shape[1::-1])\n\n    x_max, y_max = img.shape[:2]\n    \n    for x0 in tqdm(range(0, x_max, tile_size)):\n        x1 = min(x_max, x0 + tile_size)\n        for y0 in range(0, y_max, tile_size):\n            y1 = min(y_max, y0 + tile_size)\n\n            img_tile = img[x0:x1, y0:y1]\n            mask_tile = mask[x0:x1, y0:y1]\n\n            img_tile_path = f\"train_tiles/images/{img_id}_{x0}-{x1}x_{y0}-{y1}y.png\"\n            mask_tile_path = f\"train_tiles/masks/{img_id}_{x0}-{x1}x_{y0}-{y1}y.png\"\n\n            cv2.imwrite(img_tile_path, cv2.cvtColor(img_tile, cv2.COLOR_RGB2BGR))\n            cv2.imwrite(mask_tile_path, mask_tile)\n\n            meta_ls.append([\n                img_id, x0, x1, y0, y1, img_tile_path, mask_tile_path\n            ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Creating the meta file\n\nmeta_df = pd.DataFrame(meta_ls, columns=['image_id', 'x0', 'x1', 'y0', 'y1', 'image_tile_path', 'mask_tile_path'])\nmeta_df.to_csv(f'train_metadata.csv', index=False)\nmeta_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 6.3. <a id='19'>Visualisation</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Count of Split images\n\nlen(os.listdir('train_tiles/images'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from glob import glob\nimport random\n\nmultipleImages = glob('train_tiles/images/**')\ndef plotImages2():\n    r = random.sample(multipleImages, 9)\n    plt.figure(figsize=(20,20))\n    plt.subplot(331)\n    plt.imshow(cv2.imread(r[0])); plt.axis('off')\n    plt.subplot(332)\n    plt.imshow(cv2.imread(r[1])); plt.axis('off')\n    plt.subplot(333)\n    plt.imshow(cv2.imread(r[2])); plt.axis('off')\n    plt.subplot(334)\n    plt.imshow(cv2.imread(r[3])); plt.axis('off')\n    plt.subplot(335)\n    plt.imshow(cv2.imread(r[4])); plt.axis('off')\n    plt.subplot(336)\n    plt.imshow(cv2.imread(r[5])); plt.axis('off')\n    plt.subplot(337)\n    plt.imshow(cv2.imread(r[6])); plt.axis('off')\n    plt.subplot(338)\n    plt.imshow(cv2.imread(r[7])); plt.axis('off')\n    plt.subplot(339)\n    plt.imshow(cv2.imread(r[8])); plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plotImages2()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 8. <a id='20'>Data Preparation</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob\nimage_paths = glob.glob(\"./train_tiles/images/*.png\")\nmask_paths = glob.glob(\"./train_tiles/masks/*.png\")\nlen(image_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(mask_paths)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 8.1 <a id='21'>Filtering low band density</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"lowband_density_values = []\nmask_density_values = []\n\nfor img_path, msk_path in tqdm(zip(image_paths, mask_paths), total=len(image_paths)):\n    image, mask = read_single(img_path, msk_path)\n    img_hist = np.histogram(image)\n    #print(\"img_hist\", img_hist)\n    lowband_density = np.sum(img_hist[0][0:4])\n    mask_density = np.count_nonzero(mask)\n    #print(\"lowband_density\", lowband_density)\n    #print(\"highband_density\", highband_density)\n    #print(\"mask_density\", mask_density)\n    lowband_density_values.append(lowband_density)\n    mask_density_values.append(mask_density)\ntrain_helper_df = pd.DataFrame(data=list(zip(image_paths, mask_paths, lowband_density_values,\n                                             mask_density_values)),\n                               columns=['image_path','mask_path', 'lowband_density', 'mask_density'])\ntrain_helper_df.astype(dtype={'image_path':'object','mask_path':'object',\n                                      'lowband_density':'int64', 'mask_density':'int64'})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 7.1.1 <a>selecting images with tissues</a>\n[Table of contents](#0.1)\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"images_tissue = train_helper_df[train_helper_df.lowband_density>100].image_path\nmasks_tissue = train_helper_df[train_helper_df.lowband_density>100].mask_path\nimages_tissue.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images, masks = read_data(images_tissue[1200:1218], masks_tissue[1200:1218])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 7.1.2 <a>Visualisation</a>\n[Table of contents](#0.1)"},{"metadata":{"trusted":true},"cell_type":"code","source":"max_rows = 6\nmax_cols = 6\nfig, ax = plt.subplots(max_rows, max_cols, figsize=(20,18))\nfig.suptitle('Sample Images', y=0.93)\nplot_count = (max_rows*max_cols)//2\nfor idx, (img, mas) in enumerate(zip(images[:plot_count], masks[:plot_count])):\n    row = (idx//max_cols)*2\n    row_masks = row+1\n    col = idx % max_cols\n    ax[row, col].imshow(img)\n    #sns.distplot(img_array.flatten(), ax=ax[1]);\n    ax[row_masks, col].imshow(mas)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 8.1. <a id='22'>Augmentation</a>\n[Table of contents](#0.1)"},{"metadata":{},"cell_type":"markdown","source":"Augmentation is done only on images with gloms\n\nValidation samples are split and kept aside and it is not used for augmentation to avoid leakage of train data to val data"},{"metadata":{"trusted":true},"cell_type":"code","source":"image_90_per_tissues, image_val_files, mask_90_per_tissues, mask_val_files = train_test_split(images_tissue, masks_tissue, test_size=0.30, random_state=17)\nprint(\"Split Counts\\n\\tImage_90_per_files:\\t{0}\\n\\tMask_90_per_files:\\t{2}\\n\\tVal Images:\\t\\t{1}\\n\\tVal Masks:\\t\\t{3}\\n\"\n      .format(len(image_90_per_tissues), len(image_val_files), len(mask_90_per_tissues), len(mask_val_files)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#https://albumentations.ai/ \nhttps://www.kaggle.com/alexanderliao/image-augmentation-demo-with-albumentation\n\nfrom albumentations import (\nCLAHE,\nElasticTransform,\nGridDistortion,\nOpticalDistortion,\nHorizontalFlip,\nRandomBrightnessContrast,\nRandomGamma,\nHueSaturationValue,\nRGBShift,\nMedianBlur,\nGaussianBlur,\nGaussNoise,\nChannelShuffle,\nCoarseDropout\n)\n\ndef augment_data(image_paths, mask_paths):  \n\n    if not os.path.exists('hubmap_512x512_augmented/images_aug2'):\n        os.makedirs('hubmap_512x512_augmented/images_aug2')\n    if not os.path.exists('hubmap_512x512_augmented/masks_aug2'):\n        os.makedirs('hubmap_512x512_augmented/masks_aug2')\n\n    for image, mask in tqdm(zip(image_paths, mask_paths), total=len(image_paths)):\n        images_aug = []\n        masks_aug = []\n        image_name = Path(image).stem\n        mask_name = Path(mask).stem\n\n        x, y = read_single(image, mask)\n        mask_density = np.count_nonzero(y)\n\n        ## Augmenting only images with Gloms\n        if(mask_density>0):\n\n            try:\n                h, w, c = x.shape\n            except Exception as e:\n                image = image[:-1]\n                x, y = read_single(image, mask)\n                h, w, c = x.shape\n\n            aug = CLAHE(clip_limit=1.0, tile_grid_size=(8, 8), always_apply=False, p=1)\n            augmented = aug(image=x, mask=y)\n            x0 = augmented['image']\n            y0 = augmented['mask']\n\n            ## ElasticTransform\n            aug = ElasticTransform(p=1, alpha=120, sigma=512*0.05, alpha_affine=512*0.03)\n            augmented = aug(image=x, mask=y)\n            x1 = augmented['image']\n            y1 = augmented['mask']\n\n            ## Grid Distortion\n            aug = GridDistortion(p=1)\n            augmented = aug(image=x, mask=y)\n            x2 = augmented['image']\n            y2 = augmented['mask']\n\n            ## Optical Distortion\n            aug = OpticalDistortion(p=1, distort_limit=2, shift_limit=0.5)\n            augmented = aug(image=x, mask=y)\n            x3 = augmented['image']\n            y3 = augmented['mask']\n\n            ## Horizontal Flip\n            aug = HorizontalFlip(p=1)\n            augmented = aug(image=x, mask=y)\n            x4 = augmented['image']\n            y4 = augmented['mask']\n\n            ## Random Brightness and Contrast\n            aug = RandomBrightnessContrast(p=1)\n            augmented = aug(image=x, mask=y)\n            x5 = augmented['image']\n            y5 = augmented['mask']\n\n            aug = RandomGamma(p=1)\n            augmented = aug(image=x, mask=y)\n            x6 = augmented['image']\n            y6 = augmented['mask']\n\n            aug = HueSaturationValue(p=1)\n            augmented = aug(image=x, mask=y)\n            x7 = augmented['image']\n            y7 = augmented['mask']\n\n            aug = RGBShift(p=1)\n            augmented = aug(image=x, mask=y)\n            x8 = augmented['image']\n            y8 = augmented['mask']\n\n            aug = MedianBlur(p=1, blur_limit=5)\n            augmented = aug(image=x, mask=y)\n            x9 = augmented['image']\n            y9 = augmented['mask']\n\n            aug = GaussianBlur(p=1, blur_limit=3)\n            augmented = aug(image=x, mask=y)\n            x10 = augmented['image']\n            y10 = augmented['mask']\n\n            aug = GaussNoise(p=1)\n            augmented = aug(image=x, mask=y)\n            x11 = augmented['image']\n            y11 = augmented['mask']\n\n            aug = ChannelShuffle(p=1)\n            augmented = aug(image=x, mask=y)\n            x12 = augmented['image']\n            y12 = augmented['mask']\n\n            aug = CoarseDropout(p=1, max_holes=8, max_height=32, max_width=32)\n            augmented = aug(image=x, mask=y)\n            x13 = augmented['image']\n            y13 = augmented['mask']\n\n            images_aug.extend([\n                    x0, x1, x2, x3, x4, x5, x6,\n                    x7, x8, x9, x10, x11, x12,\n                    x13])\n\n            masks_aug.extend([\n                    y0, y1, y2, y3, y4, y5, y6,\n                    y7, y8, y9, y10, y11, y12,\n                    y13])\n\n            idx = 0\n            for i, m in zip(images_aug, masks_aug):\n                tmp_image_name = f\"{image_name}_{idx}.png\"\n                tmp_mask_name  = f\"{mask_name}_{idx}.png\"\n\n                image_path = os.path.join(\"hubmap_512x512_augmented/images_aug2/\", tmp_image_name)\n                mask_path  = os.path.join(\"hubmap_512x512_augmented/masks_aug2/\", tmp_mask_name)\n\n                cv2.imwrite(image_path, i)\n                cv2.imwrite(mask_path, m)\n\n                idx += 1\n\n    return images_aug, masks_aug\n\nimages_aug, masks_aug = augment_data(image_90_per_tissues, mask_90_per_tissues)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"aug_img_paths = glob.glob(\"/kaggle/input/hubmap-512x512-augmented/images_aug/*.png\")\naug_msk_paths = glob.glob(\"/kaggle/input/hubmap-512x512-augmented/masks_aug/*.png\")\naug_img_paths2 = glob.glob(\"/kaggle/input/hubmap-512x512-augmented/images_aug2/*.png\")\naug_msk_paths2 = glob.glob(\"/kaggle/input/hubmap-512x512-augmented/masks_aug2/*.png\")\n\naug_img_paths.extend(aug_img_paths2)\naug_msk_paths.extend(aug_msk_paths2)\nprint(\"Number of Augmented Images\", len(aug_img_paths))\nprint(\"Number of Augmented Masks\", len(aug_msk_paths))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"aug_img_paths = aug_img_paths[-100:]\naug_msk_paths = aug_msk_paths[-100:]\naug_imgs, aug_msks = read_data(aug_img_paths, aug_msk_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_rows = 10\nmax_cols = 4\nfig, ax = plt.subplots(max_rows, max_cols, figsize=(20,32))\nplot_count = (max_rows*max_cols)//2\nfor idx, (img, mas) in enumerate(zip(aug_imgs[:plot_count], aug_msks[:plot_count])):\n    row = (idx//max_cols)*2\n    row_masks = row+1\n    col = idx % max_cols\n    ax[row, col].imshow(img)\n    ax[row_masks, col].imshow(mas)","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}