{"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":"markdown","source":"# UWM DataSet Visualization\n### Purpose of this Notebook\n\n- The main purpose of this notebook is to import the data and visualize the images simultaneously with the segmentation data\n- The segmentation data is in an encoded format with three regions: stomach, small_bowel and large_bowel.\n- For more info on the data, please visit competition page.","metadata":{}},{"cell_type":"code","source":"#Import of packages\nimport pandas as pd;\nimport matplotlib.image as mpimg\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport random","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:13:53.493172Z","iopub.execute_input":"2022-07-06T09:13:53.493609Z","iopub.status.idle":"2022-07-06T09:13:53.499517Z","shell.execute_reply.started":"2022-07-06T09:13:53.493575Z","shell.execute_reply":"2022-07-06T09:13:53.498321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Import of datasets and basic exploration\n\n- let us import the images which is situated in the train folder. \n- Let us also import the csv file that contains the ID's and organ masks for the training images","metadata":{}},{"cell_type":"code","source":"csv_path   = \"../input/uw-madison-gi-tract-image-segmentation/train.csv\"; # path for csv file\nimage_dir  =  \"../input/uw-madison-gi-tract-image-segmentation/train\";\ntrain_csv  = pd.read_csv(csv_path);\ntrain_csv.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:03:43.588987Z","iopub.execute_input":"2022-07-06T09:03:43.590123Z","iopub.status.idle":"2022-07-06T09:03:44.249718Z","shell.execute_reply.started":"2022-07-06T09:03:43.590075Z","shell.execute_reply":"2022-07-06T09:03:44.2484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Segmentation mask is not available for much of the data.\n- Let us remove rows where segmentation mask is not given.","metadata":{}},{"cell_type":"code","source":"train_csv = train_csv[train_csv.segmentation.notna()].reset_index(drop=False);\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:03:44.251944Z","iopub.execute_input":"2022-07-06T09:03:44.252301Z","iopub.status.idle":"2022-07-06T09:03:44.276225Z","shell.execute_reply.started":"2022-07-06T09:03:44.252272Z","shell.execute_reply":"2022-07-06T09:03:44.274806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_csv[\"class\"].unique());\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:03:44.277718Z","iopub.execute_input":"2022-07-06T09:03:44.278066Z","iopub.status.idle":"2022-07-06T09:03:44.287749Z","shell.execute_reply.started":"2022-07-06T09:03:44.278032Z","shell.execute_reply":"2022-07-06T09:03:44.286432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- there are three regions in the organ classes.","metadata":{}},{"cell_type":"markdown","source":"### Masks in Image Segmentation\n\n#### Image Segmentation\n\nImage segmentation is a process where an image is partitioned into multiple regions based on some condition.\nHere, such partition will be based on the mask data. In other words, during image segmentation, we extract all the pixels within a defined mask.\n\n#### Run Length Encoding\n\nMark can be described in a RLE format where the odd digits represents the mask location and the even\ndigit represents the no. of pixel that follows occurs after the mask in a given row. A nice tutorials\ncan be found here:\n\nhttps://ccshenyltw.medium.com/run-length-encode-and-decode-a33383142e6b\n\nI take the first example from the above link to illustrate RLE\n\nImage: [0, 0, 0, 1, 0].\n\n![image.png](attachment:39d30ed3-880d-4ab7-a249-a12ccc453efc.png)!\n\nMask2Rle encode: ‘4 1’\n\nIn our case most of the images are of size 266*266 and if we flatten it, it is an array of 1x70756 pixels.\n\nLets say a mask is given as \n\nmask = [28094 3 28358 7 28623 9 28889 9 29155 9 29421 9];\n\n- What first two numbers means is that: there is a mask at index 28094 and the following 3 signifies mask stretches 3      pixels to the right.\n- Similarly the third and fourth number signifies: there is a mask at index 28358 and it extends 7 pixels to the right. ","metadata":{},"attachments":{"39d30ed3-880d-4ab7-a249-a12ccc453efc.png":{"image/png":"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"}}},{"cell_type":"markdown","source":"### RLE code to Image function\n\nHere, I burrow the function from Satinsby to convert rle mask to images.\nref.: https://www.kaggle.com/stainsby/fast-tested-rle\n","metadata":{}},{"cell_type":"code","source":"# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\n\ndef rle2mask(mask_rle,shape):\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)","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:08:48.846672Z","iopub.execute_input":"2022-07-06T09:08:48.847079Z","iopub.status.idle":"2022-07-06T09:08:48.855756Z","shell.execute_reply.started":"2022-07-06T09:08:48.847043Z","shell.execute_reply":"2022-07-06T09:08:48.854574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Extract File Path\n ","metadata":{}},{"cell_type":"markdown","source":"- Here we will create new columns that includes, image name and path to image directory\n- image dimensions etc.","metadata":{}},{"cell_type":"code","source":"data_directory = '../input/uw-madison-gi-tract-image-segmentation/train/';\nfullpath_to_image = [];\nheight            = [];\nwidth             = [];\nday               = [];\ncase              = [];\nslice_num         = [];\nfullpath_to_image = [];\nimage             = [];\nfor i in range(len(train_csv)):\n    items1 = train_csv.id.iloc[i].split('_');\n    path1 = data_directory+items1[0]+'/'+items1[0]+'_'+items1[1]+'/scans/';\n    path2 = items1[2]+'_'+items1[3];\n    import os\n\n    image_name = [file for file in os.listdir(path1) if file.endswith('.png') and \\\n             path2 in file];\n    # lets extract image size from its name\n    items2     = str(image_name).split('_');\n    height.append(int(items2[2]));\n    width.append(int(items2[3]));\n    day.append(items1[1]);\n    case.append(items1[0]);\n    slice_num.append(items1[3]);\n    # lets compute the full path to the image\n    fullpath_to_image.append(path1+image_name[0]);\n    # image name\n    image.append(image_name[0])\n\ntrain_csv.loc[:,\"height\"] =  height;\ntrain_csv.loc[:,\"width\"] =  width;\ntrain_csv.loc[:,\"day\"] =  day;\ntrain_csv.loc[:,\"case\"] =  case;\ntrain_csv.loc[:,\"slice\"] =  slice_num;\ntrain_csv.loc[:,\"image\"] =  image;\ntrain_csv.loc[:,\"image_path\"] =  fullpath_to_image;","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:03:44.301432Z","iopub.execute_input":"2022-07-06T09:03:44.302177Z","iopub.status.idle":"2022-07-06T09:04:11.223746Z","shell.execute_reply.started":"2022-07-06T09:03:44.302139Z","shell.execute_reply":"2022-07-06T09:04:11.222656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:04:11.225019Z","iopub.execute_input":"2022-07-06T09:04:11.225355Z","iopub.status.idle":"2022-07-06T09:04:11.248996Z","shell.execute_reply.started":"2022-07-06T09:04:11.225308Z","shell.execute_reply":"2022-07-06T09:04:11.247867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"../input/uw-madison-gi-tract-image-segmentation/train/case123/case123_day20/scans/slice_0065_266_266_1.50_1.50.png","metadata":{}},{"cell_type":"markdown","source":"### Lets create a unique id for each images","metadata":{}},{"cell_type":"code","source":"train_csv['id_image'] = train_csv.groupby(['id']).ngroup();\nprint('no. of unique images: ', train_csv.id_image.max()+1);\ntrain_csv = train_csv[['id_image','id','image_path','slice','case','day','width','height','class','segmentation']];\n# lets group by unique images\ntrain_csv = train_csv.groupby(['id_image']);\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:05:02.252039Z","iopub.execute_input":"2022-07-06T09:05:02.2525Z","iopub.status.idle":"2022-07-06T09:05:02.302001Z","shell.execute_reply.started":"2022-07-06T09:05:02.252462Z","shell.execute_reply":"2022-07-06T09:05:02.300725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Lets define a function that plots mask and MRI scan","metadata":{}},{"cell_type":"markdown","source":"- First lets define a function that plots mask and the scanned image simultaneously.\n- We will keep its input argument as image_id that we created and the matplotlib axis","metadata":{}},{"cell_type":"code","source":"\ndef plot_image_id(image_id,ax):\n    '''\n    image_id: unique id of image, an integer from 0 to 16590\n    ax: matplotlib axis\n    plots stomach with red, small_bowel with green and large_bowel with blue\n    '''\n    X      = train_csv[['id','class','segmentation','width','height','image_path']].get_group((image_id));\n    img = mpimg.imread(X.image_path.iloc[0]);\n    img /= img.max();\n    ax.imshow(img,cmap='gray_r',vmin=0, vmax=0.5); # to increase the contrast, I limit to Vmax to 0.5\n\n    image_mask = [];\n\n    for i in range(len(X)):\n        image_mask = rle2mask(X.segmentation.iloc[i],(X.width.iloc[0],X.height.iloc[0]));  \n        if(X[\"class\"].iloc[i]=='stomach'):\n            ax.contour(image_mask,cmap='Reds',alpha=0.7,vmin=0, vmax=1);\n        if(X[\"class\"].iloc[i]=='small_bowel'):\n            ax.contour(image_mask,cmap='Greens',alpha=0.7,vmin=0, vmax=1);\n        if(X[\"class\"].iloc[i]=='large_bowel'):\n            ax.contour(image_mask,cmap='Blues',alpha=0.7,vmin=0, vmax=1); \n            \n    ax.set_title(X.id.iloc[0],fontsize=14)   \n    \n    return ax\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:30:22.951956Z","iopub.execute_input":"2022-07-06T09:30:22.952359Z","iopub.status.idle":"2022-07-06T09:30:22.964509Z","shell.execute_reply.started":"2022-07-06T09:30:22.952307Z","shell.execute_reply":"2022-07-06T09:30:22.962901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### lets test our plotting function with passing 16 random integers (image_id's)\n- contour colors: stomach with red, small_bowel with green and large_bowel with blue\n","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(4,4,figsize=(50,50))\nimages_to_plot = random.sample(range(0, 16590), 16)\ncount = 0;\nfor i in range(4):\n    for j in range(4):\n        plot_image_id(images_to_plot[count],ax[i,j]);\n        count = count+1;","metadata":{"execution":{"iopub.status.busy":"2022-07-06T09:59:09.789517Z","iopub.execute_input":"2022-07-06T09:59:09.789922Z","iopub.status.idle":"2022-07-06T09:59:15.580168Z","shell.execute_reply.started":"2022-07-06T09:59:09.789891Z","shell.execute_reply":"2022-07-06T09:59:15.579319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Visualization successful\n\n- We have succesfully able to visualize scans and masks simultaneously.\n- I have kept plotting functions very simplistic so as to maintain clarity.","metadata":{}}]}