{"cells":[{"metadata":{},"cell_type":"markdown","source":"**ICH preprocessing functions**\n\nMany thanks to Ryan Epp for listing the different ways to window dicom images and the skeleton code. His work can be found [here](https://www.kaggle.com/reppic/gradient-sigmoid-windowing)\n\n*Abdullah Hasan*","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport json\n\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport pydicom\nfrom keras import layers\nfrom keras.applications import DenseNet121\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import Callback, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.initializers import Constant\nfrom keras.utils import Sequence\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\nfrom keras.models import Model, load_model\nfrom keras.layers import GlobalAveragePooling2D, Dense, Activation, concatenate, Dropout\nfrom keras.initializers import glorot_normal, he_normal\nfrom keras.regularizers import l2\nfrom tensorflow.python.ops import array_ops\nfrom tqdm import tqdm\nfrom sklearn.model_selection import train_test_split, StratifiedKFold\nfrom keras import backend as K\nimport tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Load csv files and restructure","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"BASE_PATH = '../input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/'\nTRAIN_DIR = 'stage_2_train/'\nTEST_DIR = 'stage_2_test/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(BASE_PATH + 'stage_2_train.csv')\n#sub_df = pd.read_csv(BASE_PATH + 'stage_1_sample_submission.csv')\n\ntrain_df['id'] = train_df['ID'].apply(lambda st: \"ID_\" + st.split('_')[1])\ntrain_df['subtype'] = train_df['ID'].apply(lambda st: st.split('_')[2])\ntrain_df['filename'] = train_df['ID'].apply(lambda st: \"ID_\" + st.split('_')[1] + \".png\")\ntrain_df['type'] = train_df['ID'].apply(lambda st: st.split('_')[2])\n\nprint(train_df.shape)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_df = train_df\npivot_df = pivot_df[['Label', 'filename', 'type']].drop_duplicates().pivot(index='filename', columns='type', values='Label').reset_index()\n\nprint(pivot_df.shape)\npivot_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The following are functions that take either a dicom file or the pixel data from a dicom file and apply the relevant function\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def map_to_gradient(grey_img):\n    rainbow_img = np.zeros((grey_img.shape[0], grey_img.shape[1], 3))\n    rainbow_img[:, :, 0] = np.clip(4 * grey_img - 2, 0, 1.0) * (grey_img > 0) * (grey_img <= 1.0)\n    rainbow_img[:, :, 1] =  np.clip(4 * grey_img * (grey_img <=0.75), 0,1) + np.clip((-4*grey_img + 4) * (grey_img > 0.75), 0, 1)\n    rainbow_img[:, :, 2] = np.clip(-4 * grey_img + 2, 0, 1.0) * (grey_img > 0) * (grey_img <= 1.0)\n    return rainbow_img\n\ndef rainbow_window(dcm):\n    grey_img = window_image(dcm, 40, 80)\n    return map_to_gradient(grey_img)\n\ndef sigmoid_window(dcm, window_center, window_width, U=1.0, eps=(1.0 / 255.0)):\n    _, _, intercept, slope = get_windowing(dcm)\n    img = dcm.pixel_array * slope + intercept\n    ue = np.log((U / eps) - 1.0)\n    W = (2 / window_width) * ue\n    b = ((-2 * window_center) / window_width) * ue\n    z = W * img + b\n    img = U / (1 + np.power(np.e, -1.0 * z))\n    img = (img - np.min(img)) / (np.max(img) - np.min(img))\n    return img\n\ndef sigmoid_bsb_window(dcm):\n    brain_img = sigmoid_window(dcm, 40, 80)\n    subdural_img = sigmoid_window(dcm, 80, 200)\n    bone_img = sigmoid_window(dcm, 600, 2000)\n    \n    bsb_img = np.zeros((brain_img.shape[0], brain_img.shape[1], 3))\n    bsb_img[:, :, 0] = brain_img\n    bsb_img[:, :, 1] = subdural_img\n    bsb_img[:, :, 2] = bone_img\n    return bsb_img\n\ndef window_image(dcm, window_center, window_width):\n    _, _, intercept, slope = get_windowing(dcm)\n    img = dcm.pixel_array * slope + intercept\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    img[img < img_min] = img_min\n    img[img > img_max] = img_max\n    img = (img - np.min(img)) / (np.max(img) - np.min(img))\n    return img\n\ndef bsb_window(dcm):\n    brain_img = window_image(dcm, 40, 80)\n    subdural_img = window_image(dcm, 80, 200)\n    bone_img = window_image(dcm, 600, 2000)\n    \n    bsb_img = np.zeros((brain_img.shape[0], brain_img.shape[1], 3))\n    bsb_img[:, :, 0] = brain_img\n    bsb_img[:, :, 1] = subdural_img\n    bsb_img[:, :, 2] = bone_img\n    return bsb_img\n    \ndef get_first_of_dicom_field_as_int(x):\n    #get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)\n    if type(x) == pydicom.multival.MultiValue:\n        return int(x[0])\n    else:\n        return int(x)\n\ndef get_windowing(data):\n    dicom_fields = [data[('0028','1050')].value, #window center\n                    data[('0028','1051')].value, #window width\n                    data[('0028','1052')].value, #intercept\n                    data[('0028','1053')].value] #slope\n    return [get_first_of_dicom_field_as_int(x) for x in dicom_fields]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Pull a random image from every class available","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = [\"epidural\",\"intraparenchymal\",\"intraventricular\",\"subarachnoid\",\"subdural\"]\nEDA = pivot_df[pivot_df[\"any\"]==0].sample(n=1)\nEDA['title'] = \"any\"\nfor label in labels:\n    d = pivot_df[pivot_df[label] == 1].sample(n=1)\n    d['title'] = label\n    EDA = EDA.append(d,ignore_index=True)\nEDA","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Function to apply the different windowing functions correctly","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def process_dcm(dcm,type=\"WINDOW\"):\n    if type == \"WINDOW\":\n        window_center , window_width, intercept, slope = get_windowing(dcm)\n        win_img = window_image(dcm, window_center, window_width)\n        return win_img\n    elif type == \"SIGMOID\":\n        window_center , window_width, intercept, slope = get_windowing(dcm)\n        test_img = dcm.pixel_array\n        win_img = sigmoid_window(dcm, window_center, window_width)\n        return win_img\n    elif type == \"BSB\":\n        win_img = bsb_window(dcm)\n        return win_img\n    elif type == \"SIGMOID_BSB\":\n        return sigmoid_bsb_window(dcm)\n    elif type == \"GRADIENT\":\n        win_img = rainbow_window(dcm)\n        return win_img\n        ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Apply all the windowing functions to every image in our EDA dataset and save the plots","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('/kaggle/working/windows/'):\n    os.makedirs('/kaggle/working/windows/')\nt = [\"WINDOW\",\"SIGMOID\",\"BSB\",\"SIGMOID_BSB\",\"GRADIENT\"]\n#t = [\"GRADIENT\"]\nfor window in t:\n    for index,row in EDA.iterrows():\n        f,ax = plt.subplots(1,1,figsize=(10,10))\n        file = row[\"filename\"]\n        dcm = pydicom.dcmread(BASE_PATH + TRAIN_DIR + file.split(\".\")[0] + \".dcm\")\n        img = (process_dcm(dcm,window) * 255.0).astype(np.uint8)\n        ax.set_title(\"Type: \" + row['title'] + \"  Window: \" + window )\n        ax.imshow(img,cmap=\"bone\")\n        plt.savefig(\"/kaggle/working/\" + window + \"_\" + row[\"title\"] + \".png\")\n        plt.show()\n        \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}