{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Introduction\n\nThis is an exploratory notebook on the HuBMAP challenge introducing the tool rasterio to read and play with tiff\n\n![img](https://i.imgur.com/F4naKqh.png)\n\n## Part-1 : Crops and masks with rasterio\n\n### a. Load an image with rasterio\n\nLoading an image, checking the coordinate system and the linear transformation\n\n*rasterio*\n\n### b. Visualise Anatomical Structures\n\nWe use the annotated json to visualise the differente structues inside an image\n\n*json, rasterio, rasterio.mask*\n\n### c. Visualise glomerulus\n\nWe use the annotated json to generate masks and visualise the glomeruli\n\n*json, rasterio, rasterio.mask*\n\n### d. Generate overlay mask of Glomerulus on Anatomical Structure with rasterio\n\nIn this last part, we create a full downsized image with masks of glomeruli overlayed\n\n*json, rasterio, rasterio.mask*\n\n## Part-2 : EDA\n\n### a. Usefull surface, Glomeruli surface\n\nSome global stats, id per id:\n\n1. We want to check the total surface in pixel of the images\n2. We want to check the total space covered by glomeruli\n3. Rather than ploting the ratio of surface_glomeruli/total_surface, we check only the \"usefull\" surface, in which there is actually glomeruli\n\n*cv2, rasterio, rasterio.mask, json*\n\n### a. Height, width and surface of the glomeruli in an image\n\nIt is important to know how much space take a full glomerulus in order to calibrate correctly the crops\n\n### b. Size and oriention of glomeruli\n\nAs the glomeruli can have an orientation, we would like as well to know the global dimension of the glomeruli. \n\n### c. Biggest and smallest glomeruli in the set\n\nVisualisation of the extrema. Helpfull to identify possible mistakes in labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport glob\n\nfrom tqdm import tqdm\n\nimport plotly.graph_objects as go","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df1 = pd.read_csv('/kaggle/input/hubmap-kidney-segmentation/train.csv')\ndf1.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Part-1 : Crops and masks with rasterio"},{"metadata":{"trusted":true},"cell_type":"code","source":"id_ = 'cb2d976f4'\npath_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\npath_json1 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}-anatomical-structure.json'\npath_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load an image using rasterio\n\nRasterio is a powerfull tool to read and filter files in .tiff format.\n.tiff includes arrays of pixels as well as metadata\n\nThe metadata are:\n\ncrs: when existing, the coordinate system of the tiff\n\ntransform: the linear transformation, including coordinates of a pixel as well as its size"},{"metadata":{"trusted":true},"cell_type":"code","source":"import rasterio\n\nraster = rasterio.open(path_tiff)\nimg = raster.read()\ncrs = raster.crs\ntransform = raster.transform\nprint(f'shape : {img.shape}')\nprint(f'crs : {crs}')\nprint(f'transform : {transform}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Crop an image with rasterio.mask and polygons"},{"metadata":{},"cell_type":"markdown","source":"### Anatomical Structure"},{"metadata":{},"cell_type":"markdown","source":"The image is to big. We can use the polygons given in the dataset to crop directly around the areas of interest."},{"metadata":{"trusted":true},"cell_type":"code","source":"import json\nwith open(path_json1, 'r') as f:\n    aois = json.load(f)\n    \naoi = aois[0]['geometry']\naoi","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"rasterio.mask.mask take as input the raster file as well as a list of aoi.\n\nSeveral parameters are also available. Most important are:\n* crop: if True, crop the image around the aoi, overwise, only set the pixels outside the aoi to 0\n* filled: wether or not the pixels outside the bounding box are set to 0. "},{"metadata":{"trusted":true},"cell_type":"code","source":"from rasterio.mask import mask\n\ncropped_img, transform_c = mask(raster, [aoi], crop = True, filled = False)\nprint(cropped_img.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The file is much smaller. To visualise it, we need now to transpose it"},{"metadata":{"trusted":true},"cell_type":"code","source":"cropped_img_t = cropped_img.transpose(1,2,0)\nprint(cropped_img_t.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (20,20))\nplt.imshow(cropped_img_t)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Glomerulus\n\nGlomerulus are the areas to identify in the main tiffs. Let's plot a sample of them."},{"metadata":{"trusted":true},"cell_type":"code","source":"with open(path_json2, 'r') as f:\n    aois_g = json.load(f)\n\nplt.figure(figsize = (30,30))\nfor i in range(25):\n    aoi_g = aois_g[i]['geometry']\n    cropped_img_g, _ = mask(raster, [aoi_g], crop = True)\n    cropped_img_g_t = cropped_img_g.transpose(1,2,0)\n    plt.subplot(5,5,i+1)\n    fig = plt.imshow(cropped_img_g_t)\n    fig.axes.get_xaxis().set_visible(False)\n    fig.axes.get_yaxis().set_visible(False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\ndef resize(img,s=1, shape=None):\n    imgt = img.transpose(1,2,0)\n    if shape:\n        new_img = np.zeros((shape[0],shape[1],3)).astype(np.uint8)\n    else:\n        new_img = np.zeros((int(imgt.shape[0]/s),int(imgt.shape[1]/s),3)).astype(np.uint8)\n    for i in range(3):\n        temp = imgt[:,:,i]\n        new_img[:,:,i] = cv2.resize(temp,(new_img.shape[1],new_img.shape[0]))\n    new_img = new_img.transpose(2,0,1)\n    return new_img","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Generate overlay mask of Glomerulus on Anatomical Structure\n\nIn this part, we generate a subtiff of the anatomical structure, and generate an overlay mask of glomerulus "},{"metadata":{},"cell_type":"markdown","source":"### Save the subraster generated earlier"},{"metadata":{"trusted":true},"cell_type":"code","source":"cropped_img.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We need to save the raster using the tranform metadata used to generate the crop"},{"metadata":{"trusted":true},"cell_type":"code","source":"with rasterio.open('temp.tif','w',driver='GTiff',\n                   height=cropped_img.shape[1],\n                   width=cropped_img.shape[2],\n                   count=cropped_img.shape[0],\n                   dtype=cropped_img.dtype,\n                   crs = crs,\n                   transform=transform_c,) as f:\n    f.write(cropped_img)\n\nsubraster = rasterio.open('temp.tif')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Generate masks of glomerulus"},{"metadata":{"trusted":true},"cell_type":"code","source":"all_aois_g = [elmt['geometry'] for elmt in aois_g]\ncropped_img_g, transform = mask(subraster, all_aois_g, crop = False)\ncropped_img_g = cropped_img_g.transpose(1,2,0)\nprint(cropped_img_g.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (20,20))\nplt.imshow(cropped_img_g)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Overlay the mask"},{"metadata":{"trusted":true},"cell_type":"code","source":"glom_mask = cropped_img_g.copy()\nglom_mask[glom_mask>0]=255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (20,20))\nplt.imshow(cropped_img_t)\nplt.imshow(glom_mask, alpha = 0.5)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Part 2 - EDA\n\nThere is a total of 8 images in the train set."},{"metadata":{"trusted":true},"cell_type":"code","source":"ids = glob.glob('/kaggle/input/hubmap-kidney-segmentation/train/*.tiff')\nids = [elmt.split('/')[-1].split('.')[0] for elmt in ids]\nids","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Usefull Surface, Glomeruli Surface\n\nLet's generate for each id the following metrics:\n- tot_surface: the total number of pixel in an image\n- tot_annotated: the total number of pixels covered by the principale annotations\n- tot_glomeruli: the total number of pixels covered by glomeruli\n- tot_usefull_surface: the total surface annotated if there is glomeruli on it"},{"metadata":{"trusted":true},"cell_type":"code","source":"#In order to save memory, I reduce on the fly the size of images by 4.\nr = 4\n\nsurface_summary = {}\n\nfor id_ in tqdm(ids):\n    \n    tot_annotated = 0\n    tot_usefull_surface = 0\n    \n    path_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\n    path_json1 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}-anatomical-structure.json'\n    path_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'\n\n    ########LOAD ANNOTATIONS#####\n    with open(path_json1, 'r') as f:\n        aois1 = json.load(f)\n\n    with open(path_json2, 'r') as f:\n        aois2 = json.load(f)\n\n    polys1 = [elmt['geometry'] for elmt in aois1]\n    polys2 = [elmt['geometry'] for elmt in aois2]\n    \n    #######OPEN RASTER AND RESIZE##########\n    raster = rasterio.open(path_tiff)\n    crs = raster.crs\n    transform = raster.transform\n    img = raster.read()\n\n    # Resize\n    img = resize(img, r)\n    shape_ = img[0].shape\n    \n    #This array is used to remove pixels already visited, in case of overlapping of annotations\n    visited = np.ones(shape_)\n    \n    #Readjust affine transformation\n    transform = transform * transform.scale(r,r)\n\n    # Save resized\n    with rasterio.open(f'{id_}.tif','w',driver='GTiff',\n                       height=img.shape[1],\n                       width=img.shape[2],\n                       count=img.shape[0],\n                       dtype=img.dtype,\n                       crs = crs,\n                       transform=transform,) as f:\n        f.write(img)\n\n    raster = rasterio.open(f'{id_}.tif')\n    \n    #Generate masks\n    for poly in polys1:\n        mask1 = mask(raster, [poly])[0][0]\n        mask1[mask1>0] = 1\n        mask2 = mask(raster, polys2)[0][0]\n        mask2[mask2>0]= 1\n        \n        cg = (mask1*mask2*visited).sum()\n        tot_annotated += (mask1*visited).sum()\n        \n        if cg.sum()>0: #if there is glomeruli in the annotation\n            tot_usefull_surface += (mask1*visited).sum()\n            \n        visited = visited - mask1\n        visited[visited<0] = 0\n            \n    tot_surface = shape_[0]*shape_[1]\n    tot_glomeruli = mask2.sum()\n    \n    surface_summary[id_] = {}\n    surface_summary[id_]['tot_surface'] = tot_surface\n    surface_summary[id_]['tot_glomeruli'] = tot_glomeruli\n    surface_summary[id_]['tot_annotated'] = tot_annotated\n    surface_summary[id_]['tot_usefull_surface'] = tot_usefull_surface\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_surface = pd.DataFrame(surface_summary).T\n\ndf_surface['glomeruli_density_tot'] = df_surface.tot_glomeruli / df_surface.tot_surface\ndf_surface['glomeruli_density_annotated'] = df_surface.tot_glomeruli / df_surface.tot_annotated\ndf_surface['glomeruli_density_usefull'] = df_surface.tot_glomeruli / df_surface.tot_usefull_surface\ndf_surface['tot_annotated_ratio'] = df_surface.tot_annotated / df_surface.tot_surface\ndf_surface['tot_usefull_ratio'] = df_surface.tot_usefull_surface / df_surface.tot_surface\n\ndf_surface = np.round(df_surface, 3)\n\ndf_surface = df_surface.sort_values('glomeruli_density_usefull',ascending = False)\ndf_surface","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = go.Figure(\n    go.Bar(\n        x = df_surface.index,\n        y = df_surface.glomeruli_density_usefull\n    )\n)\n\nfig.update_layout(template = 'presentation', title = 'Density of Glomeruli per id')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Average height, width and surface of the glomeruli\n\nWe check here height, width, and surface occupied by each glomeruli"},{"metadata":{"trusted":true},"cell_type":"code","source":"glomeruli_metadata = {}\nfor id_ in ids:\n    glomeruli_metadata[id_] = {'width':[], 'height':[], 'surface':[]}\n    path_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\n    path_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'\n\n    with open(path_json2, 'r') as f:\n        aois2 = json.load(f)\n\n    polys2 = [elmt['geometry'] for elmt in aois2]\n    raster = rasterio.open(path_tiff)\n    \n    for poly in tqdm(polys2):\n        m, _ = mask(raster, [poly], crop = True)\n        m = m[0]\n        glomeruli_metadata[id_]['width'].append(m.shape[1])\n        glomeruli_metadata[id_]['height'].append(m.shape[0])\n    \n        m[m>0] = 1\n        glomeruli_metadata[id_]['surface'].append(np.sum(m))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Distributions"},{"metadata":{"trusted":true},"cell_type":"code","source":"import seaborn as sns\nplt.figure(figsize = (20,20))\nplt.subplot(3,1,1)\nplt.title('width')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(v['width'], label = k)\nplt.legend()\nplt.subplot(3,1,2)\nplt.title('height')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(v['height'], label = k)\nplt.legend()\nplt.subplot(3,1,3)\nplt.title('surface')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(v['surface'], label = k)\nplt.legend()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"widths = []\nheights = []\nareas = []\nfor ids_, dic in glomeruli_metadata.items():\n    widths+=dic['width']\n    heights+=dic['height']\n    areas += dic['surface']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import plotly.graph_objects as go\n\nfig = go.Figure()\n\nfig.add_trace(\n    go.Scatter(\n        x = widths,\n        y = heights,\n        opacity = 0.5,\n        mode = 'markers'\n    )\n)\nfig.update_layout(template = 'presentation', title = 'Space taken by the glomeruli')\nfig.update_xaxes(title = 'width')\nfig.update_yaxes(title = 'height')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"In the figure below, I plot average space taken by a glomerulus as well as maximum space, this can be use to assess the length of the crops to use later"},{"metadata":{},"cell_type":"markdown","source":"### Length, width, and orientation of glomeruli\n\nThe insights above give indication of the space taken by a glomeruli in an image. Now we might as well know the length and width of the glomeruli, regardless of their orientation in the image. \n\nFor that purpose, I use the feature regionprops_table from skimage"},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage.measure import regionprops_table\n\nglomeruli_metadata = {}\nfor id_ in tqdm(ids):\n    glomeruli_metadata[id_] = {'orientation':[], 'major_axis_length':[], 'minor_axis_length':[]}\n    path_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\n    path_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'\n\n    with open(path_json2, 'r') as f:\n        aois2 = json.load(f)\n\n    polys2 = [elmt['geometry'] for elmt in aois2]\n    raster = rasterio.open(path_tiff)\n    \n    for poly in polys2:\n        m, _ = mask(raster, [poly], crop = True)\n        m = m[0]\n        m[m>0] = 1\n        if m.sum()>0:\n            props = regionprops_table(m, properties=('orientation',\n                                                     'major_axis_length',\n                                                     'minor_axis_length'))\n\n            glomeruli_metadata[id_]['orientation'].append(props['orientation'])\n            glomeruli_metadata[id_]['major_axis_length'].append(props['major_axis_length'])\n            glomeruli_metadata[id_]['minor_axis_length'].append(props['minor_axis_length'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import seaborn as sns\nplt.figure(figsize = (20,20))\nplt.subplot(3,1,1)\nplt.title('orientation')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(np.abs(v['orientation']), label = k)\nplt.legend()\nplt.subplot(3,1,2)\nplt.title('major_axis_length')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(v['major_axis_length'], label = k)\nplt.legend()\nplt.subplot(3,1,3)\nplt.title('minor_axis_length')\nfor k,v in glomeruli_metadata.items():\n    sns.distplot(v['minor_axis_length'], label = k)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Representation of the average glomeruli"},{"metadata":{"trusted":true},"cell_type":"code","source":"widths = []\nheights = []\nfor ids_, dic in glomeruli_metadata.items():\n    widths+=[elmt[0] for elmt in dic['major_axis_length']]\n    heights+=[elmt[0] for elmt in dic['minor_axis_length']]\n    \nfig = go.Figure()\n\nfig.add_trace(\n    go.Scatter(\n        x = widths,\n        y = heights,\n        opacity = 0.5,\n        mode = 'markers'\n    )\n)\n\nfig.update_layout(template = 'presentation', title = 'Size of the glomeruli')\nfig.update_xaxes(title = 'major_axis_length')\nfig.update_yaxes(title = 'minor_axis_length')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualising the outliers\n\nWe observe from the figure above some very small glomeruli, and some glomeruli with strange proportions. \nIn the next plot, I will isolate those glomeruli and plot them with their dedicated masks"},{"metadata":{},"cell_type":"markdown","source":"## Very small glomeruli"},{"metadata":{"trusted":true},"cell_type":"code","source":"size = 500\np = int(size/2)\nimage_set = {}\nfor id_, dic in glomeruli_metadata.items():\n    glomeruli = np.where(np.hstack(dic['major_axis_length'])<100)[0]\n    if len(glomeruli):\n        print(f'{id_} -> {glomeruli}')\n        path_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\n        path_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'\n        with open(path_json2, 'r') as f:\n            aois_g = json.load(f)\n            \n        polys2 = [elmt['geometry'] for elmt in aois_g]\n        #Open the associated tiff with rasterio\n        raster = rasterio.open(path_tiff)\n        #Get polygons\n        for arg in glomeruli:\n            x,y = np.array(polys2[arg]['coordinates']).mean(axis=1)[0]\n            x1,x2,y1,y2 = x-p,x+p,y-p,y+p\n            # Generate new square polygon with extended coordinates\n            poly = {'type':'Polygon', 'coordinates':[[[x1,y1],[x1,y2],[x2,y2],[x2,y1]]]}\n            # Crop the figure\n            cimg, ctrans = mask(raster, [poly], crop = True)\n            #Save temporary the image raster\n            with rasterio.open('temp.tif','w',driver='GTiff',\n                   height=cimg.shape[1],\n                   width=cimg.shape[2],\n                   count=cimg.shape[0],\n                   dtype=cimg.dtype,\n                   crs = crs,\n                   transform=ctrans,) as f:\n                \n                f.write(cimg)\n            \n            #Reload the image as tiff\n            craster = rasterio.open('temp.tif')\n            #Generate the mask based on crop\n            cmask, _ = mask(craster, [polys2[arg]], crop = False)\n            cmask[cmask>0] = 1\n            cmask = cmask.astype(float)\n            image_set[id_ + '-' + str(arg)] = {}\n            image_set[id_ + '-' + str(arg)]['image'] = cimg.transpose(1,2,0)\n            image_set[id_ + '-' + str(arg)]['mask'] = cmask[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (30,10))\ni = 0\nfor k,v in image_set.items():\n    plt.subplot(1,5,i+1)\n    cimg = v['image']\n    cmask = v['mask']\n    plt.title(k)\n    plt.imshow(cimg)\n    plt.imshow(cmask, alpha = 0.5)\n    i+=1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Very big glomeruli"},{"metadata":{"trusted":true},"cell_type":"code","source":"size = 1000\np = int(size/2)\nimage_set = {}\nfor id_, dic in glomeruli_metadata.items():\n    glomeruli = np.where(np.hstack(dic['major_axis_length'])>600)[0]\n    if len(glomeruli):\n        print(f'{id_} -> {glomeruli}')\n        path_tiff = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.tiff'\n        path_json2 = f'/kaggle/input/hubmap-kidney-segmentation/train/{id_}.json'\n        with open(path_json2, 'r') as f:\n            aois_g = json.load(f)\n            \n        polys2 = [elmt['geometry'] for elmt in aois_g]\n        #Open the associated tiff with rasterio\n        raster = rasterio.open(path_tiff)\n        #Get polygons\n        for arg in glomeruli:\n            x,y = np.array(polys2[arg]['coordinates']).mean(axis=1)[0]\n            x1,x2,y1,y2 = x-p,x+p,y-p,y+p\n            # Generate new square polygon with extended coordinates\n            poly = {'type':'Polygon', 'coordinates':[[[x1,y1],[x1,y2],[x2,y2],[x2,y1]]]}\n            # Crop the figure\n            cimg, ctrans = mask(raster, [poly], crop = True)\n            #Save temporary the image raster\n            with rasterio.open('temp.tif','w',driver='GTiff',\n                   height=cimg.shape[1],\n                   width=cimg.shape[2],\n                   count=cimg.shape[0],\n                   dtype=cimg.dtype,\n                   crs = crs,\n                   transform=ctrans,) as f:\n                \n                f.write(cimg)\n            \n            #Reload the image as tiff\n            craster = rasterio.open('temp.tif')\n            #Generate the mask based on crop\n            cmask, _ = mask(craster, [polys2[arg]], crop = False)\n            cmask[cmask>0] = 1\n            cmask = cmask.astype(float)\n            image_set[id_ + '-' + str(arg)] = {}\n            image_set[id_ + '-' + str(arg)]['image'] = cimg.transpose(1,2,0)\n            image_set[id_ + '-' + str(arg)]['mask'] = cmask[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (20,10))\ni = 0\nfor k,v in image_set.items():\n    plt.subplot(2,3,i+1)\n    cimg = v['image']\n    cmask = v['mask']\n    plt.title(k)\n    plt.imshow(cimg)\n    plt.imshow(cmask, alpha = 0.3)\n    i+=1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Below is also a list of suspicious glomeruli identified by scrolling through the dataset"}],"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}