{"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":"# Things to keep in mind!!!!\n- pt no. 109(no FLAIR) & **123(no T1w)** & 709(no FLAIR) should be excluded!\n- choice : **zero-mean normalization & 3D normalization** (following sangwook's advice)\n- For the 1st trial, will use a single modality. **\"T1w\"**\n- Data augmentation : 4*3(flipped, high sigma deform, very very weak gaussian noise) per each pt.\n> In total, **7592 images** will use as the train set. (= (4*3+1)*(585-1))  ","metadata":{}},{"cell_type":"markdown","source":"# 0. Load required libraries & csv files.","metadata":{}},{"cell_type":"code","source":"# Install required packages\n! pip install natsort","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:50:37.214183Z","iopub.execute_input":"2021-08-11T16:50:37.214689Z","iopub.status.idle":"2021-08-11T16:50:43.60367Z","shell.execute_reply.started":"2021-08-11T16:50:37.214634Z","shell.execute_reply":"2021-08-11T16:50:43.602433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd \nimport matplotlib.pyplot as plt\n\nimport os \nimport cv2\nimport numpy as np\nimport glob\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nfrom torch.utils.data import Dataset #, DataLoader\nimport torch\nimport SimpleITK as sitk\n\nfrom skimage.transform import resize\n# to sort file names by its order\nfrom natsort import natsorted\n%matplotlib inline\n\n# To get a center of mass for an image (Later, will get patch images from the com.)\nfrom skimage import filters\nfrom skimage.measure import regionprops\n\n# Global variables\nmodalities = ['FLAIR', 'T1w', 'T1wCE', 'T2w']","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:50:43.606031Z","iopub.execute_input":"2021-08-11T16:50:43.606482Z","iopub.status.idle":"2021-08-11T16:50:43.618993Z","shell.execute_reply.started":"2021-08-11T16:50:43.606421Z","shell.execute_reply":"2021-08-11T16:50:43.617866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load y : labels & preds\ntrain_labels = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv')\npreds_labels = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/sample_submission.csv')\n#train_labels = pd.read_csv('../png_data/train_labels.csv')\n#preds_labels = pd.read_csv('../png_data/sample_submission.csv')\n\nprint(f'Number of patients = {len(train_labels)}'.format())\ntrain_labels.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:50:43.620653Z","iopub.execute_input":"2021-08-11T16:50:43.620996Z","iopub.status.idle":"2021-08-11T16:50:43.654929Z","shell.execute_reply.started":"2021-08-11T16:50:43.620966Z","shell.execute_reply":"2021-08-11T16:50:43.653641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. Create \"DataGenerator\"","metadata":{}},{"cell_type":"code","source":"# Reference: https://www.kaggle.com/ayuraj/brain-tumor-eda-and-interactive-viz-with-w-b\ndef ReadMRI(path, voi_lut = True, fix_monochrome = True):\n    # Original from: https://www.kaggle.com/raddar/convert-dicom-to-np-array-the-correct-way\n    dicom = pydicom.read_file(path)\n    \n    # VOI LUT (if available by DICOM device) is used to transform raw DICOM data to \n    # \"human-friendly\" view\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n               \n    # depending on this value, X-ray may look inverted - fix that:\n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n        \n    # min-max normalization\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    \n    return data\n\ndef load_imgs(idx, train=True): \n    images_idx = {}\n    for modal in modalities:\n        images_modal = []\n        if train:\n            file_path_list = glob.glob('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train/'+idx+'/'+modal+'/*')\n        else:\n            file_path_list = glob.glob('../input/rsna-miccai-brain-tumor-radiogenomic-classification/test/'+idx+'/'+modal+'/*')\n            \n        # Should be sorted again. \n        file_path_list = natsorted(file_path_list)\n        \n        for file_path in file_path_list:\n            image = ReadMRI(file_path)\n            # In case, a direc is empty!\n            if len(image) == 0:\n                print('yes')\n                image = np.zeros((1,256,256)) # pt no. 109(no FLAIR) & 123(no T1w) & 709(no FLAIR) >> excluded! \n            images_modal.append(image)\n        images_idx[modal] = np.array(images_modal)\n        \n    return images_idx","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:50:43.656505Z","iopub.execute_input":"2021-08-11T16:50:43.656814Z","iopub.status.idle":"2021-08-11T16:50:43.666334Z","shell.execute_reply.started":"2021-08-11T16:50:43.65678Z","shell.execute_reply":"2021-08-11T16:50:43.665171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check sample image - pt no.00000\n# Not registrated.\n# Just to check how long would \"load_imgs\" be. \n# %%time 위에 주석 달면 time 체크 불가....!?\nfor i in range(1):\n    idx = str(train_labels.BraTS21ID[i]).zfill(5)\n    print(idx)\n    imgs = load_imgs(idx)\n    img_ = imgs[modalities[0]]#.mean(axis=0)\n    print(img_.shape)\n# Again, just to check sample\nfig, ax = plt.subplots(2,2, figsize=(10,10))\nfor i in range(2):\n    for j in range(2):\n        m = ax[i,j].imshow(imgs[modalities[2*i+j]].mean(axis=0), cmap='gray')\n        ax[i,j].set_title(modalities[2*i+j])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:01.486751Z","iopub.execute_input":"2021-08-11T16:51:01.48715Z","iopub.status.idle":"2021-08-11T16:51:09.967802Z","shell.execute_reply.started":"2021-08-11T16:51:01.487116Z","shell.execute_reply":"2021-08-11T16:51:09.966529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 1. Create a data loader with N4biasFieldCorrectionImageFilter\nclass PreprocessedImage2Dver(Dataset):\n    def __init__(self, list_BraTS21ID, list_labels=None,\n                dim=(512, 512), n_modals=len(modalities), n_classes=2,\n                 num_slices_from_center:int=3,\n                 is_train=True, transform = None): # For single pt. \n        self.dim = dim\n        ### ????? 1. How to do batch norm for this task..?\n        #self.batch_size = batch_size\n        self.list_labels = list_labels\n        self.is_train = (list_labels is not None)\n        self.list_BraTS21ID = list_BraTS21ID\n        self.n_modals = n_modals # number of modalities\n        self.num_slices_from_center = num_slices_from_center\n        \n    \n    def __getitem__(self, index):\n        BraTS21ID_temp = self.list_BraTS21ID[index] #self.list_BraTS21ID[index*self.batch_size:(index+1)*self.batch_size] # index로 적어준 batch 만 진행!\n        \n        X = self.__data_generation(BraTS21ID_temp)\n        \n        if self.is_train:\n            y = self.list_labels[index] #self.list_labels[index*self.batch_size:(index+1)*self.batch_size]\n            return np.array(X), np.array(y)\n        else:\n            return np.array(X)\n    \n    def __data_generation(self, BraTS21ID_temp):\n        new_imgs = np.zeros((self.num_slices_from_center*2,  *self.dim, self.n_modals))\n        #print(new_imgs.shape)\n        #new_imgs = None\n        \n        idx = str(BraTS21ID_temp).zfill(5)\n        imgs = load_imgs(idx, train=self.is_train) # imgs = {'FLAIR': ~, 'T1w': ~, 'T1wCE': ~} lib다. \n        \n        index_modal = 0\n        for modal in modalities:\n            corrct_norm_imgs_modal = []\n\n            img_modal = imgs[modal] #.shape :  ex. (288, 256, 256) \n            \n            if img_modal.shape[0] < self.num_slices_from_center *2 :\n                print('The number of slice is smaller than total number of slices!!')\n                break\n            \n            central_slices = int(img_modal.shape[0]/2)\n            \n            list_slices = list(range(central_slices-self.num_slices_from_center, central_slices+self.num_slices_from_center))\n            for slice_i in list_slices:\n                img_slice_i = resize(img_modal[slice_i,:,:], self.dim)  #According to skimage API, \"2-D interpolation\".\n                #img_slice_i = cv2.resize(img_modal[slice_i,:,:], dsize= self.dim, interpolation = cv2.INTER_LINEAR) #???\n                img_slice_i_ndarray = np.array(img_slice_i, dtype = 'float32')\n\n                # 1. Removing radiofrequency inhomogeneity using N4BiasFieldCorrection\n                # ref : https://www.kaggle.com/josepc/rsna-effnet\n                inputImage = sitk.GetImageFromArray(img_slice_i_ndarray)\n                maskImage = sitk.GetImageFromArray((img_slice_i_ndarray>0.1)*1) #sitk.OtsuThreshold(inputImage, 0,1,200) \n                inputImage = sitk.Cast(inputImage, sitk.sitkFloat32) #?? 왜 32로?\n                maskImage = sitk.Cast(maskImage, sitk.sitkUInt8) #?? 왜 8로?\n                corrector = sitk.N4BiasFieldCorrectionImageFilter()\n                numberFittingLevels = 4 # ??\n                maxIter = 100 # ??\n                if maxIter is not None:\n                    corrector.SetMaximumNumberOfIterations([maxIter]*numberFittingLevels) # ??\n                corrected_image = corrector.Execute(inputImage, maskImage)\n                \n                corrected_image = sitk.GetArrayFromImage(corrected_image)\n                \n                '''max_2D = np.amax(corrected_image) \n                min_2D = np.amin(corrected_image)\n                mean_2D = np.mean(corrected_image)\n                normalized_corrected_image = (corrected_image-min_2D)/(max_2D-min_2D)'''\n                \n                corrct_norm_imgs_modal.append(corrected_image)\n            \n    \n            corrct_norm_imgs_modal = np.array(corrct_norm_imgs_modal)\n            \n            # 2. \"Zero-mean\" Normalization (Normalization type does effect models' performances)\n            mean_3D = np.mean(corrct_norm_imgs_modal)\n            std_3D = np.std(corrct_norm_imgs_modal)\n            \n            corrct_norm_imgs_modal = (corrct_norm_imgs_modal-mean_3D)/std_3D\n            \n            new_imgs[:, :, :, index_modal] = corrct_norm_imgs_modal\n            \n            index_modal += 1\n        \n        return new_imgs # shape = (num_slices_from_center*2, *dim, n_modals) !!! not 3D. 4D.","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:14.882584Z","iopub.execute_input":"2021-08-11T16:51:14.883139Z","iopub.status.idle":"2021-08-11T16:51:14.897624Z","shell.execute_reply.started":"2021-08-11T16:51:14.883103Z","shell.execute_reply":"2021-08-11T16:51:14.896534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check a sample preprocessed image\n### - num_slices_from_center:int=3\n### - for \"pt no.00002\" \n### - for 2D slice image at center","metadata":{"execution":{"iopub.status.busy":"2021-08-11T14:08:45.180394Z","iopub.execute_input":"2021-08-11T14:08:45.18079Z","iopub.status.idle":"2021-08-11T14:08:45.18689Z","shell.execute_reply.started":"2021-08-11T14:08:45.18075Z","shell.execute_reply":"2021-08-11T14:08:45.185854Z"}}},{"cell_type":"code","source":"# Do train_test_split. \n# - Train : Test = 8:2 / Stratified random sampling / random_state = 42\nfrom sklearn.model_selection import train_test_split\nX_train, X_val, y_train, y_val = train_test_split(train_labels.BraTS21ID, train_labels.MGMT_value,\n                                                 test_size = .2, random_state = 42, stratify = train_labels.MGMT_value)\n\ndim = (256, 256) \ntrain_set = PreprocessedImage2Dver(X_train, y_train, dim=dim)\nval_set = PreprocessedImage2Dver(X_val, y_val, dim=dim)\ntest_set = PreprocessedImage2Dver(preds_labels.BraTS21ID,  dim = dim)\n\nsample_preprocessed_imgs = train_set[1][0] # pt no.00002\n\ncenter_slice_idx = int(sample_preprocessed_imgs.shape[0]/2)\n#print(center_slice_idx) # In this cas, returns 3. \nimg_at_center = sample_preprocessed_imgs[center_slice_idx] # slice at center\n\n# Again, just to check sample preprocessed image.\nfig, ax = plt.subplots(2,2, figsize=(10,10))\nfor i in range(2):\n    for j in range(2):\n        m = ax[i,j].imshow(img_at_center[:, :, 2*i+j],  cmap = 'gray')\n        ax[i,j].set_title(modalities[2*i+j])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:15.135199Z","iopub.execute_input":"2021-08-11T16:51:15.135575Z","iopub.status.idle":"2021-08-11T16:51:44.074602Z","shell.execute_reply.started":"2021-08-11T16:51:15.135537Z","shell.execute_reply":"2021-08-11T16:51:44.073813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check a sampled space of a sample_img (FLAIR ver). \nprint(img_at_center[100:150, 100:130, 0])","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.075779Z","iopub.execute_input":"2021-08-11T16:51:44.076192Z","iopub.status.idle":"2021-08-11T16:51:44.083057Z","shell.execute_reply.started":"2021-08-11T16:51:44.076162Z","shell.execute_reply":"2021-08-11T16:51:44.082014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Do \"Data augmentation\" ","metadata":{}},{"cell_type":"markdown","source":"## 1) Horizontal flipped","metadata":{}},{"cell_type":"code","source":"def do_hflip_2D(img): # For 3D image.\n    return np.flip(img, axis=1)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.084971Z","iopub.execute_input":"2021-08-11T16:51:44.085304Z","iopub.status.idle":"2021-08-11T16:51:44.095456Z","shell.execute_reply.started":"2021-08-11T16:51:44.085273Z","shell.execute_reply":"2021-08-11T16:51:44.094639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2) Gaussian noise applied\n#### - As the standard deviation of **\"sample_T1w\"** image is about 0.79,\n####   (>> print(np.std(sample_T1w)) #0.78577...)\n####   Gaussian noise from mean=0 & std=0.1. (To give noises as small as possible)\n#### ????? How to choose mean & std of gaussian noise?","metadata":{}},{"cell_type":"code","source":"def apply_gaussian_noise(img, mean:float=0., std:float=.05):\n    gaussian_noise = np.random.normal(mean, std, img.shape)\n    img_with_noise = img + gaussian_noise\n    return img_with_noise","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.096817Z","iopub.execute_input":"2021-08-11T16:51:44.097269Z","iopub.status.idle":"2021-08-11T16:51:44.107385Z","shell.execute_reply.started":"2021-08-11T16:51:44.097226Z","shell.execute_reply":"2021-08-11T16:51:44.106416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3) Deformed (high sigma)","metadata":{}},{"cell_type":"code","source":"# ref : https://www.hj-chung.com/post/elastic-distortion/\ndef do_elastic_distortion(img, rows, cols, sigma=200., alpha=.5):\n    #true_dst = np.zeros((rows,cols,ch))\n\n    # Sampling from Unif(-1, 1)\n    dx = np.random.uniform(-1,1,(rows,cols))\n    dy = np.random.uniform(-1,1,(rows,cols))\n\n    # STD of gaussian kernel\n    sig = sigma\n\n    dx_gauss = cv2.GaussianBlur(dx, (7,7), sig)\n    dy_gauss = cv2.GaussianBlur(dy, (7,7), sig)\n\n    n = np.sqrt(dx_gauss**2 + dy_gauss**2) # for normalization\n\n    # Strength of distortion\n    alpha = alpha\n\n    ndx = alpha * dx_gauss/ n\n    ndy = alpha * dy_gauss/ n\n\n    indy, indx = np.indices((rows, cols), dtype=np.float32)\n\n    # dst_img = cv2.remap(img,ndx - indx_x, ndy - indx_y, cv2.INTER_LINEAR)\n\n    map_x = ndx + indx\n    map_x = map_x.reshape(rows, cols).astype(np.float32)\n    map_y = ndy + indy\n    map_y = map_y.reshape(rows, cols).astype(np.float32)\n\n    dst = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR)\n    \n    return dst","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.109093Z","iopub.execute_input":"2021-08-11T16:51:44.109561Z","iopub.status.idle":"2021-08-11T16:51:44.120614Z","shell.execute_reply.started":"2021-08-11T16:51:44.109519Z","shell.execute_reply":"2021-08-11T16:51:44.119652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example1. Flipped image\nsample_T1w = img_at_center[:,:,1]\nhflipped_sample_T1w = do_hflip_2D(sample_T1w)\n\nplt.figure(figsize=(10,10))\nplt.subplot(3,2,1)\nplt.imshow(sample_T1w, cmap='gray')\nplt.title('Original T1w image')\n\nplt.subplot(3,2,2)\nplt.imshow(hflipped_sample_T1w, cmap='gray')\nplt.title('Flipped T1w image')\nplt.show()\n\n# --------------------------------------------------------------\n# Example2. Gaussian noise applied image\n#sample_T1w = img_at_center[:,:,1]\nnoised_sample_T1w = apply_gaussian_noise(sample_T1w, std=0.1)\n\nplt.figure(figsize=(10,10))\nplt.subplot(3,2,3)\nplt.imshow(sample_T1w, cmap='gray')\nplt.title('Original T1w image')\n\nplt.subplot(3,2,4)\nplt.imshow(noised_sample_T1w, cmap='gray')\nplt.title('Gaussian noise applied T1w image')\nplt.show()\n\n# --------------------------------------------------------------\n# Example3. Distorted image (Elastic deformed image)\n#sample_T1w = img_at_center[:,:,1]\ndistored_sample_T1w = do_elastic_distortion(sample_T1w,  sample_T1w.shape[0], sample_T1w.shape[1])\n\nplt.figure(figsize=(10,10))\nplt.subplot(3,2,5)\nplt.imshow(sample_T1w, cmap='gray')\nplt.title('Original T1w image')\n\nplt.subplot(3,2,6)\nplt.imshow(noised_sample_T1w, cmap='gray')\nplt.title('Deformed(Distorted) T1w image')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.122266Z","iopub.execute_input":"2021-08-11T16:51:44.122716Z","iopub.status.idle":"2021-08-11T16:51:44.81128Z","shell.execute_reply.started":"2021-08-11T16:51:44.122647Z","shell.execute_reply":"2021-08-11T16:51:44.810367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3) Get 2D patch images. (4 patches per each image)\n#### - 4 patch images from the center of mass point + margin.\n#### - 2D patch size(w x h) = 100 x 100 (80+20, 80+20)","metadata":{}},{"cell_type":"code","source":"# Should check shape[0] & shape[1] are even or odd number.\ndef get_center_of_mass_coordinates(img):\n    threshold_value = filters.threshold_otsu(img)\n    labeled_foreground = (img > threshold_value).astype(int)\n    properties = regionprops(labeled_foreground, img)\n    center_of_mass = properties[0].centroid\n    center_of_mass = (int(x) for x in center_of_mass) # Float to int\n    return center_of_mass\n\ndef get_2D_patches_per_vertex(img, \n                              central_patch_size:tuple=(80,80), margin_size:tuple=(20,20)):\n    orig_h, orig_w = img.shape\n    com_h, com_w = get_center_of_mass_coordinates(img)\n    \n    left_top_patch = img[com_h-int(central_patch_size[0]/2)-margin_size[0]:com_h+int(central_patch_size[0]/2),\\\n                        com_w-int(central_patch_size[1]/2)-margin_size[1]:com_w+int(central_patch_size[1]/2)] \n    right_top_patch = img[com_h-int(central_patch_size[0]/2)-margin_size[0]:com_h+int(central_patch_size[0]/2),\\\n                        com_w-int(central_patch_size[1]/2):com_w+int(central_patch_size[1]/2)+margin_size[1]] \n    left_bottom_patch = img[com_h-int(central_patch_size[0]/2):com_h+int(central_patch_size[0]/2)+margin_size[0],\\\n                        com_w-int(central_patch_size[1]/2)-margin_size[1]:com_w+int(central_patch_size[1]/2)] \n    right_bottom_patch = img[com_h-int(central_patch_size[0]/2):com_h+int(central_patch_size[0]/2)+margin_size[0],\\\n                        com_w-int(central_patch_size[1]/2):com_w+int(central_patch_size[1]/2)+margin_size[1]] \n    \n    # In case, the generated patch size is wrong. Print warning message. \n    if left_top_patch.shape[0] != central_patch_size[0]+margin_size[0]:\n        print('Check the size of patch & margin! Dose not match 100 x 100!')\n        \n    #print(left_top_patch.shape)\n    #print(right_top_patch.shape)\n    #print(left_bottom_patch.shape)\n    #print(right_bottom_patch.shape)\n    \n    return (left_top_patch, right_top_patch, left_bottom_patch, right_bottom_patch)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.812448Z","iopub.execute_input":"2021-08-11T16:51:44.812825Z","iopub.status.idle":"2021-08-11T16:51:44.823226Z","shell.execute_reply.started":"2021-08-11T16:51:44.812795Z","shell.execute_reply":"2021-08-11T16:51:44.822199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example\nleft_top_patch, right_top_patch, left_bottom_patch, right_bottom_patch = get_2D_patches_per_vertex(sample_T1w)\n\nplt.figure(figsize=(10,10))\nplt.imshow(sample_T1w, cmap='gray')\nplt.show()\n\nplt.figure(figsize=(10,10))\nplt.subplot(2,2,1)\nplt.imshow(left_top_patch, cmap='gray')\nplt.title('Left top cropped image')\n\nplt.subplot(2,2,2)\nplt.imshow(right_top_patch, cmap='gray')\nplt.title('Right top cropped image')\n\nplt.subplot(2,2,3)\nplt.imshow(left_bottom_patch, cmap='gray')\nplt.title('Left bottom cropped image')\n\nplt.subplot(2,2,4)\nplt.imshow(right_bottom_patch, cmap='gray')\nplt.title('Right bottom cropped image')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:44.825279Z","iopub.execute_input":"2021-08-11T16:51:44.825562Z","iopub.status.idle":"2021-08-11T16:51:45.518347Z","shell.execute_reply.started":"2021-08-11T16:51:44.825535Z","shell.execute_reply":"2021-08-11T16:51:45.517671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4) Combine above augmentation procedures","metadata":{}},{"cell_type":"code","source":"def get_4x3_augmented_2D_imgs(img): # return : dictionary\n    # 1. Horizontal flipped image\n    hflipped_img = do_hflip_2D(img)\n    \n    #2. Gaussian noise applied image\n    gaussian_noise_img = apply_gaussian_noise(img)\n    \n    #3. Deformed image\n    deformed_img = do_elastic_distortion(img,  img.shape[0], img.shape[1], sigma=200, alpha=.5)\n    \n    augmented_imgs = {'original_img':img,\n                     'hflipped_imgs':list(get_2D_patches_per_vertex(hflipped_img)),\n                     'gaussian_noised_imgs':list(get_2D_patches_per_vertex(gaussian_noise_img)),\n                     'deformed_imgs':list(get_2D_patches_per_vertex(deformed_img))}\n    return augmented_imgs\n\ndef plot_cropped_imgs_together(imgs:list):\n\n    plt.figure(figsize=(10,10))\n    plt.subplot(2,2,1)\n    plt.imshow(imgs[0], cmap='gray')\n    plt.title('Left top cropped image')\n\n    plt.subplot(2,2,2)\n    plt.imshow(imgs[1], cmap='gray')\n    plt.title('Right top cropped image')\n\n    plt.subplot(2,2,3)\n    plt.imshow(imgs[2], cmap='gray')\n    plt.title('Left bottom cropped image')\n\n    plt.subplot(2,2,4)\n    plt.imshow(imgs[3], cmap='gray')\n    plt.title('Right bottom cropped image')\n\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:45.51959Z","iopub.execute_input":"2021-08-11T16:51:45.519849Z","iopub.status.idle":"2021-08-11T16:51:45.528471Z","shell.execute_reply.started":"2021-08-11T16:51:45.519824Z","shell.execute_reply":"2021-08-11T16:51:45.527407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"augmented_imgs = get_4x3_augmented_2D_imgs(sample_T1w)\n\nhflipped_imgs = augmented_imgs['hflipped_imgs']\ngaussian_noised_imgs = augmented_imgs['gaussian_noised_imgs']\ndeformed_imgs = augmented_imgs['deformed_imgs']\n\nprint('Horizontally flipped images')\nplot_cropped_imgs_together(hflipped_imgs)\n\nprint('\\n')\nprint('Gaussian noise applied images')\nplot_cropped_imgs_together(gaussian_noised_imgs)\n\nprint('\\n')\nprint('Deformed images')\nplot_cropped_imgs_together(deformed_imgs)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T16:51:45.529946Z","iopub.execute_input":"2021-08-11T16:51:45.530224Z","iopub.status.idle":"2021-08-11T16:51:47.629184Z","shell.execute_reply.started":"2021-08-11T16:51:45.530197Z","shell.execute_reply":"2021-08-11T16:51:47.628157Z"},"trusted":true},"execution_count":null,"outputs":[]}]}