{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Competition Overview\n\n- 37 trillion cells in body\n- determine function and relationship\n- understand cellular activity\n<br>\n- Human BioMolecular Atlas Program (HuBMAP)\n- development of framework for mapping human body at cellular level\n\n**mapping kidney at single cell resolution**\n\n- detect functional tissue units **FTUs** in different tissue preparation pipelines\n- FTU: 3d block of cells around a cappilary in diffusion distance from any other cell in same block\n- **goal: glomeruli FTU detector**\n\nuses:\n- understand relationships between cell and tissue organization and function\n- cell and tissue anatomy\n- develop pharmaceutical therapies"},{"metadata":{},"cell_type":"markdown","source":"# Expected Submission File\n\nValues to describe a mask<br>\nincluding a header: img,pixels\n\n**RLE**:\n* Run-length encoding\n* reduces file size\n* continuous number string with only numbers and spaces\n* **PIXEL_ID_A** *followed by* **RUN_LENGTH_A** *followed by* **PIXEL_ID_B** *followed by* **RUN_LENGTH_B**<br>\n\n**PIXEL_IDs**:<br>\n(1,1)(2,1)(3,1)<br>\n(1,2)(2,2)(3,2)<br>\n(1,3)(2,3)(3,3)<br>\n\nturns to:<br>\n(1)(2)(3)<br>\n(4)(5)(6)<br>\n(7)(8)(9)<br>\n\n**Result**:<br>\nimg,pixels<br>\n1,1 1 5 1<br>\n2,1 1<br>\n3,1 1<br>\netc.\n        "},{"metadata":{},"cell_type":"markdown","source":"# input data\n\n**Test set**: 5 tiff images<br>\n**Train set**: 8 tiff images<br>\n\n**train.csv**:<br>\n* mask of glomeruli in image\n* RLE encoded\n* id column: image id\n* encoding column: RLE encoded mask data\n\n**img.json**: <br>\n* one for each image\n* geometry: pixel coords of a glomerulus Polygon as [[x1,y1],[x2,y2],...]\n* HAS SAME INFO AS TRAIN.CSV\n\n**img-anatomical-structure.json**: <br>\n* one for each image\n* geometry: pixel coords of Medulla and Cortex as [[x1,y1],[x2,y2],...]\n\n**HuBMAP-20-dataset_information.csv**:<br>\n* additional info on image sources"},{"metadata":{},"cell_type":"markdown","source":"# Initial Overview of Files:"},{"metadata":{"trusted":true},"cell_type":"code","source":"ls ../input/hubmap-kidney-segmentation","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ls ../input/hubmap-kidney-segmentation/train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ls ../input/hubmap-kidney-segmentation/test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\ntraindir=\"../input/hubmap-kidney-segmentation/train/\"\ntestdir=\"../input/hubmap-kidney-segmentation/test/\"\ntrain = os.listdir(traindir)\ntest = os.listdir(testdir)\nprint(f\"Train files: {len(train)}. ---> {train[:3]}\")\nprint(f\"Test files :  {len(test)}. ---> {test[:3]}\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image dimensions\n\nsome seem to be (h, w, channels)<br>\nothers seem to be (1, 1, channels, h, w) <br>      "},{"metadata":{"trusted":true},"cell_type":"code","source":"import tifffile as tff\nshapes=[]\nfor file in train:\n    if '.tiff' in file:\n        image = tff.imread(traindir+file)\n        print(image.shape)\n        shapes.append(image.shape)\n#for file in test:\n#    if '.tiff' in file:\n#        image = tff.imread(testdir+file)\n#        shapes.append[image.shape]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tifffile as tff\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport os\ndef get_imgs(folder_path):\n    imgs=[]\n    for file in os.listdir(folder_path):\n        if '.tiff' in file:\n            imgs.append(file)\n    return imgs\ndef read_image(folder_path,img_name):\n    image = tff.imread(folder_path+'/'+img_name)\n    if image.shape[0]==1:\n        print('reshape from '+str(image.shape))\n        h=image.shape[3]\n        w=image.shape[4]\n        image=np.ravel(image, order='C')\n        image=np.reshape(image, (3, h, w))\n        image = np.dstack((image[0],image[1],image[2]))\n        print('to '+str(image.shape))\n    else:\n        print('shape '+str(image.shape))\n        print('no reshape')\n    return image\ndef downscale(image,factor):\n    newimg=[]\n    for index in range(len(image)):\n        if index%factor==0:\n            row=[]\n            for px_index in range(len(image[index])):\n                if px_index%factor==0:\n                    row.append(image[index][px_index])\n            newimg.append(row)\n    return np.asarray(newimg)\ndef show_image(image):\n    plt.figure(figsize=(10, 10))\n    plt.imshow(image)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"load list of .tiff image files"},{"metadata":{"trusted":true},"cell_type":"code","source":"traindir='../input/hubmap-kidney-segmentation/train/'\nimgs=get_imgs(traindir)\nimgs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Choose an image"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_NAME=imgs[3]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## choose downscaling factor (save RAM)"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_FACTOR=20\n#enter a downscaling factor here if the image is too big for RAM or just to speed up loading","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image=read_image(traindir,IMG_NAME)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ORIGINAL_SHAPE=image.shape\nprint(ORIGINAL_SHAPE)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## downscale image so it does not overload RAM"},{"metadata":{"trusted":true},"cell_type":"code","source":"image=downscale(image,IMG_FACTOR)\n#only necessary if downscaling image is wanted! -> otherwise adds unnecessary time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_image(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nkidney_data=pd.read_csv(\"../input/hubmap-kidney-segmentation/train.csv\")\nprint(kidney_data.shape)\nkidney_data","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Utility Functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"import json\nimport numpy as np\nimport pandas as pd\n\ndef json_to_df(json_path):\n   with open(json_path) as json_file:\n       json_data = json.load(json_file)\n   json_data_df = pd.json_normalize(json_data)\n   return json_data_df\n\ndef PolyArea(x_list,y_list):\n    #uses the shoelace formula to calculate polygon area from a set of cartesian coords\n    #https://stackoverflow.com/questions/24467972/calculate-area-of-polygon-given-x-y-coordinates\n    return 0.5*np.abs(np.dot(x_list,np.roll(y_list,1))-np.dot(y_list,np.roll(x_list,1)))\n\ndef json_to_coords(json_data_df):\n    geom=json_data_df['geometry.coordinates']\n    polygons=[]\n    for x in geom:\n        polygons.append(x[0])\n    return polygons\ndef dimensions(polygon):\n    x_list=[]\n    y_list=[]\n    for x,y in polygon:\n        x_list.append(x)\n        y_list.append(y)\n    h=max(y_list)-min(y_list)\n    w=max(x_list)-min(x_list)\n    area=PolyArea(x_list,y_list)\n    return h,w,area\ndef bbox(polygon,padding):\n    \"\"\"\n    polygon: 2D array of 1D arrays of x and y coords\n    padding: pixel buffer around polygon\n    \"\"\"\n    x_list=[]\n    y_list=[]\n    for x,y in polygon:\n        x_list.append(x)\n        y_list.append(y)\n    x1=int((min(x_list))-padding)\n    x2=int((max(x_list))+padding)\n    y1=int((min(y_list))-padding)\n    y2=int((max(y_list))+padding)\n    #image=image[y1:y2,x1:x2]\n    #return image\n    return x1,x2,y1,y2 #only return coords instead of img to save memory\ndef dim_list(polygons):\n    h_list=[]\n    w_list=[]\n    area_list=[]\n    for polygon in polygons:\n        h,w,area=dimensions(polygon)\n        h_list.append(h)\n        w_list.append(w)\n        area_list.append(area)\n    combined_list=list(zip(h_list,w_list,area_list))\n    result=pd.DataFrame(combined_list, columns=['height','width','area'])\n    return result\ndef x_and_y(polygon,factor):\n    x_list=[]\n    y_list=[]\n    for x,y in polygon:\n        x_list.append(x/factor)\n        y_list.append(y/factor)\n    return x_list,y_list\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# analyzing data"},{"metadata":{"trusted":true},"cell_type":"code","source":"json_path='../input/hubmap-kidney-segmentation/train/'+IMG_NAME.split('.')[0]+'.json'\njson_data_df=json_to_df(json_path)\npolygons=json_to_coords(json_data_df)\ndimensions=dim_list(polygons)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dimensions","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# visualizing data"},{"metadata":{"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.jointplot(x=dimensions['width'], y=dimensions['height'], kind=\"kde\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\nimport pandas as pd\nimport seaborn as sns\n\nf, (ax_box, ax_hist) = plt.subplots(2, sharex=True, gridspec_kw= {\"height_ratios\": (0.2, 1)})\nmean=dimensions['area'].mean()\nmedian=dimensions['area'].median()\n\nsns.boxplot(dimensions[\"area\"], ax=ax_box)\nax_box.axvline(mean, color='r', linestyle='--')\nax_box.axvline(median, color='g', linestyle='-')\n\nsns.distplot(dimensions[\"area\"], ax=ax_hist)\nax_hist.axvline(mean, color='r', linestyle='--')\nax_hist.axvline(median, color='g', linestyle='-')\n\nplt.legend({'Mean':mean,'Median':median})\n\nax_box.set(xlabel='')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\nplt.figure(figsize=(10, 10))\nplt.imshow(image)\nfor polygon in polygons:\n    x_list,y_list=x_and_y(polygon,IMG_FACTOR)\n    plt.fill(x_list,y_list)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## show a bbox image"},{"metadata":{"trusted":true},"cell_type":"code","source":"image=read_image(traindir,IMG_NAME)\nx1,x2,y1,y2=bbox(polygons[0],0)\nimagepatch=image[y1:y2,x1:x2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imagepatch.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_image(imagepatch)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# New approach: use RLE data"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\ntrain_path='../input/hubmap-kidney-segmentation/train.csv'\ntrain_data=pd.read_csv(train_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\ndef rle_decode(img_name,csv_path):\n    train_data=pd.read_csv(csv_path)\n    #this function does not work properly, so I commented it out\n    #rle_data=train_data.loc[train_data['id'] == img_id]['encoding'] \n    rle_location=train_data.loc[train_data['id'] == img_name.split('.')[0]]\n    id=rle_location.index[0]\n    rle_data=str(train_data.iloc[id,1])\n    #rle_list=rle_data.split()\n    #rle_list = list(map(int, rle_list)) #convert to int\n    #rle_pixels=[]\n    #rle_runs=[]\n    #for index, element in enumerate(rle_list):\n    #    if index % 2 == 0:\n    #        rle_pixels.append(int(round(0.1*(rle_list[index]))))\n    #    else:\n    #        rle_runs.append(int(round(0.1*(rle_list[index]))))\n    #results=list(zip(rle_pixels,rle_runs))\n    #return results\n    return rle_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"csv_path='../input/hubmap-kidney-segmentation/train.csv'\nresults=rle_decode(IMG_NAME,csv_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\n\ndef rleToMask(rleString,h,w):\n#https://www.kaggle.com/robertkag/rle-to-mask-converter\n  numbers = [int(numstring) for numstring in rleString.split(' ')]\n  rledata = np.array(numbers).reshape(-1,2) # -1 means unknown value\n  mask = np.zeros(h*w,dtype=np.uint8)\n  for pixel,length in rledata:\n    pixel -= 1\n    mask[pixel:pixel+length] = 255\n  mask = (mask.reshape(w,h)).T\n  return mask\ndef combine(mask,image):\n    for i,row in enumerate(image):\n        for k,val in enumerate(row):\n            if mask[i][k]!=0:\n                #image[i][k][0]=0\n                image[i][k][1]=0\n                image[i][k][2]=0\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask=rleToMask(results,ORIGINAL_SHAPE[0],ORIGINAL_SHAPE[1])\nmaskpatch=combine(mask[y1:y2,x1:x2],image[y1:y2,x1:x2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_image(maskpatch)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask=downscale(mask,IMG_FACTOR)\nimage=downscale(image,IMG_FACTOR)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask=combine(mask,image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_image(mask)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Overview of all variables and functions and their assignments in this notebook \n-->Do not execute this! only meant as notes!"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%script echo skipping\n#this is only a summary of variables and functions and should not be executed!\n\n\ntraindir=\"../input/hubmap-kidney-segmentation/train/\"\ntestdir=\"../input/hubmap-kidney-segmentation/test/\"\ntrain = os.listdir(traindir)\ntest = os.listdir(testdir)\nshapes=[] #original imageshapes\nget_imgs(folder_path) #list of tiff files in a directory\nread_image(folder_path,img_name) #reads image and reshapes the img array to (h,w,ch) if needed\ndownscale(image,factor) #downsamples image by skipping every n-th column and row (n=factor)\nshow_image(image) #shows an image plot with fixed size (10,10)\nimgs=get_imgs(traindir)\nIMG_NAME=imgs[3]\nIMG_FACTOR=20\nimage=read_image(traindir,IMG_NAME) #ORIGINAL\nORIGINAL_SHAPE=image.shape\nimage=downscale(image,IMG_FACTOR) #DOWNSCALE\nkidney_data=pd.read_csv(\"../input/hubmap-kidney-segmentation/train.csv\")\njson_to_df(json_path) #returns json data in dataframe\nPolyArea(x_list,y_list) #gives area of a polgon\njson_to_coords(json_data_df) #gets only polygons from dataframe\ndimensions(polygon) #gets h,w,and area of one polygon\nbbox(polygon,padding) #gets xmin,xmax,ymin,ymax of one polygon\ndim_list(polygons) #makes dataframe with h,w,area of each polygon\nx_and_y(polygon,factor) #gets x and y coords of one polygon as lists\njson_path= filepath of json of one img\njson_data_df= json data of one img of json_path\npolygons= coords of json_data_df\ndimensions= dataframe with h,w,area of each polygon\nmean=dimensions['area'].mean() #polygons only of current img\nmedian=dimensions['area'].median() #polygons only of current img\nimage=read_image(traindir,IMG_NAME) #ORIGINAL\nx1,x2,y1,y2=bbox(polygons[0],0) #edge coords of first polygon in list\nimagepatch=image[y1:y2,x1:x2] #patch of bbox\ntrain_path='../input/hubmap-kidney-segmentation/train.csv'\ntrain_data=pd.read_csv(train_path)\nrle_decode(img_name,csv_path) #returns rle_data of one img as string\ncsv_path='../input/hubmap-kidney-segmentation/train.csv'\nresults=rle_decode(IMG_NAME,csv_path)\nrleToMask(rleString,h,w) #returns mask as numpy array with background=0 and object=255, array is size of image\ncombine(mask,image) #colors mask areas onto image, output is numpy array\nmask= original size img mask as numpy array\nmaskpatch= only bbox section of combined mask+img\nmask=downscale(mask,IMG_FACTOR)\nimage=downscale(image,IMG_FACTOR)\nmask=combine(mask,image)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# NEXT STEP: train network\nhttps://www.kaggle.com/philipjamessullivan/p-sullivan-2-train-network"}],"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}