{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.python.client import device_lib\nprint(device_lib.list_local_devices())","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"!mkdir ../input_c\n!mkdir ../input_c/segmentation\n!mkdir ../input_c/segmentation/test\n!mkdir ../input_c/segmentation/train\n!mkdir ../input_c/segmentation/train/augmentation\n!mkdir ../input_c/segmentation/train/image\n!mkdir ../input_c/segmentation/train/mask\n!mkdir ../input_c/segmentation/train/dilate","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input_c/segmentation","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\n\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom skimage.color import rgb2gray\nfrom tensorflow.keras import Input\nfrom tensorflow.keras.models import Model, load_model, save_model\nfrom tensorflow.keras.layers import Input, Activation, BatchNormalization, Dropout, Lambda, Conv2D, Conv2DTranspose, MaxPooling2D, concatenate\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom glob import glob\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.__version__","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"INPUT_C_DIR = os.path.join(\"..\", \"input_c\")\nINPUT_DIR = os.path.join(\"..\", \"input\")\n\nSEGMENTATION_DIR = os.path.join(INPUT_C_DIR, \"segmentation\")\nSEGMENTATION_TEST_DIR = os.path.join(SEGMENTATION_DIR, \"test\")\nSEGMENTATION_TRAIN_DIR = os.path.join(SEGMENTATION_DIR, \"train\")\nSEGMENTATION_AUG_DIR = os.path.join(SEGMENTATION_TRAIN_DIR, \"augmentation\")\nSEGMENTATION_IMAGE_DIR = os.path.join(SEGMENTATION_TRAIN_DIR, \"image\")\nSEGMENTATION_MASK_DIR = os.path.join(SEGMENTATION_TRAIN_DIR, \"mask\")\nSEGMENTATION_DILATE_DIR = os.path.join(SEGMENTATION_TRAIN_DIR, \"dilate\")\nSEGMENTATION_SOURCE_DIR = os.path.join(INPUT_DIR, \\\n                                       \"pulmonary-chest-xray-abnormalities\")\n\nSHENZHEN_TRAIN_DIR = os.path.join(SEGMENTATION_SOURCE_DIR, \"ChinaSet_AllFiles\", \\\n                                  \"ChinaSet_AllFiles\")\nSHENZHEN_IMAGE_DIR = os.path.join(SHENZHEN_TRAIN_DIR, \"CXR_png\")\nSHENZHEN_MASK_DIR = os.path.join(INPUT_DIR, \"shcxr-lung-mask\", \"mask\", \"mask\")\n\nMONTGOMERY_TRAIN_DIR = os.path.join(SEGMENTATION_SOURCE_DIR, \\\n                                    \"Montgomery\", \"MontgomerySet\")\nMONTGOMERY_IMAGE_DIR = os.path.join(MONTGOMERY_TRAIN_DIR, \"CXR_png\")\nMONTGOMERY_LEFT_MASK_DIR = os.path.join(MONTGOMERY_TRAIN_DIR, \\\n                                        \"ManualMask\", \"leftMask\")\nMONTGOMERY_RIGHT_MASK_DIR = os.path.join(MONTGOMERY_TRAIN_DIR, \\\n                                         \"ManualMask\", \"rightMask\")\n\nDILATE_KERNEL = np.ones((15, 15), np.uint8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(MONTGOMERY_LEFT_MASK_DIR)\n!ls MONTGOMERY_LEFT_MASK_DIR","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"montgomery_left_mask_dir = glob(os.path.join(MONTGOMERY_LEFT_MASK_DIR, '*.png'))\n#montgomery_test = montgomery_left_mask_dir[0:50]\nmontgomery_train= montgomery_left_mask_dir[:]\n\nfor left_image_file in tqdm(montgomery_left_mask_dir):\n    base_file = os.path.basename(left_image_file)\n    image_file = os.path.join(MONTGOMERY_IMAGE_DIR, base_file)\n    right_image_file = os.path.join(MONTGOMERY_RIGHT_MASK_DIR, base_file)\n\n    image = cv2.imread(image_file)\n    left_mask = cv2.imread(left_image_file, cv2.IMREAD_GRAYSCALE)\n    right_mask = cv2.imread(right_image_file, cv2.IMREAD_GRAYSCALE)\n    \n    image = cv2.resize(image, (512, 512))\n    left_mask = cv2.resize(left_mask, (512, 512))\n    right_mask = cv2.resize(right_mask, (512, 512))\n    \n    mask = np.maximum(left_mask, right_mask)\n    mask_dilate = cv2.dilate(mask, DILATE_KERNEL, iterations=1)\n    \n    if (left_image_file in montgomery_train):\n        cv2.imwrite(os.path.join(SEGMENTATION_IMAGE_DIR, base_file), \\\n                    image)\n        cv2.imwrite(os.path.join(SEGMENTATION_MASK_DIR, base_file), \\\n                    mask)\n        cv2.imwrite(os.path.join(SEGMENTATION_DILATE_DIR, base_file), \\\n                    mask_dilate)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def add_colored_dilate(image, mask_image, dilate_image):\n    mask_image_gray = cv2.cvtColor(mask_image, cv2.COLOR_BGR2GRAY)\n    dilate_image_gray = cv2.cvtColor(dilate_image, cv2.COLOR_BGR2GRAY)\n    \n    mask = cv2.bitwise_and(mask_image, mask_image, mask=mask_image_gray)\n    dilate = cv2.bitwise_and(dilate_image, dilate_image, mask=dilate_image_gray)\n    \n    mask_coord = np.where(mask!=[0,0,0])\n    dilate_coord = np.where(dilate!=[0,0,0])\n\n    mask[mask_coord[0],mask_coord[1],:]=[255,0,0]\n    dilate[dilate_coord[0],dilate_coord[1],:] = [0,0,255]\n\n    ret = cv2.addWeighted(image, 0.7, dilate, 0.3, 0)\n    ret = cv2.addWeighted(ret, 0.7, mask, 0.3, 0)\n\n    return ret\n\ndef add_colored_mask(image, mask_image):\n    mask_image_gray = cv2.cvtColor(mask_image, cv2.COLOR_BGR2GRAY)\n                                        \n    mask = cv2.bitwise_and(mask_image, mask_image, mask=mask_image_gray)\n    \n    mask_coord = np.where(mask!=[0,0,0])\n\n    mask[mask_coord[0],mask_coord[1],:]=[255,0,0]\n\n    ret = cv2.addWeighted(image, 0.7, mask, 0.3, 0)\n\n    return ret\n\ndef diff_mask(ref_image, mask_image):\n    mask_image_gray = cv2.cvtColor(mask_image, cv2.COLOR_BGR2GRAY)\n    \n    mask = cv2.bitwise_and(mask_image, mask_image, mask=mask_image_gray)\n    \n    mask_coord = np.where(mask!=[0,0,0])\n\n    mask[mask_coord[0],mask_coord[1],:]=[255,0,0]\n\n    ret = cv2.addWeighted(ref_image, 0.7, mask, 0.3, 0)\n    return ret","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"shenzhen_mask_dir = glob(os.path.join(SHENZHEN_MASK_DIR, '*.png'))\n#shenzhen_test = shenzhen_mask_dir[0:50]\nshenzhen_train= shenzhen_mask_dir[:]\n\nfor mask_file in tqdm(shenzhen_mask_dir):\n    base_file = os.path.basename(mask_file).replace(\"_mask\", \"\")\n    image_file = os.path.join(SHENZHEN_IMAGE_DIR, base_file)\n\n    image = cv2.imread(image_file)\n    mask = cv2.imread(mask_file, cv2.IMREAD_GRAYSCALE)\n        \n    image = cv2.resize(image, (512, 512))\n    mask = cv2.resize(mask, (512, 512))\n    mask_dilate = cv2.dilate(mask, DILATE_KERNEL, iterations=1)\n    \n    if (mask_file in shenzhen_train):\n        cv2.imwrite(os.path.join(SEGMENTATION_IMAGE_DIR, base_file), \\\n                    image)\n        cv2.imwrite(os.path.join(SEGMENTATION_MASK_DIR, base_file), \\\n                    mask)\n        cv2.imwrite(os.path.join(SEGMENTATION_DILATE_DIR, base_file), \\\n                    mask_dilate)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_files = glob(os.path.join(SEGMENTATION_IMAGE_DIR, \"*.png\"))\n#test_files = glob(os.path.join(SEGMENTATION_TEST_DIR, \"*.png\"))\nmask_files = glob(os.path.join(SEGMENTATION_MASK_DIR, \"*.png\"))\ndilate_files = glob(os.path.join(SEGMENTATION_DILATE_DIR, \"*.png\"))\n\n(len(train_files), \\\n len(mask_files), \\\n len(dilate_files))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# From: https://github.com/zhixuhao/unet/blob/master/data.py\ndef train_generator(data_frame, batch_size, train_path, aug_dict,\n        image_color_mode=\"rgb\",\n        mask_color_mode=\"grayscale\",\n        image_save_prefix=\"image\",\n        mask_save_prefix=\"mask\",\n        save_to_dir=None,\n        target_size=(256,256),\n        seed=1):\n    '''\n    can generate image and mask at the same time use the same seed for\n    image_datagen and mask_datagen to ensure the transformation for image\n    and mask is the same if you want to visualize the results of generator,\n    set save_to_dir = \"your path\"\n    '''\n    image_datagen = ImageDataGenerator(**aug_dict)\n    mask_datagen = ImageDataGenerator(**aug_dict)\n    \n    image_generator = image_datagen.flow_from_dataframe(\n        data_frame,\n        directory = train_path,\n        x_col = \"filename\",\n        class_mode = None,\n        color_mode = image_color_mode,\n        target_size = target_size,\n        batch_size = batch_size,\n        save_to_dir = save_to_dir,\n        save_prefix  = image_save_prefix,\n        seed = seed)\n\n    mask_generator = mask_datagen.flow_from_dataframe(\n        data_frame,\n        directory = train_path,\n        x_col = \"dilate\",\n        class_mode = None,\n        color_mode = mask_color_mode,\n        target_size = target_size,\n        batch_size = batch_size,\n        save_to_dir = save_to_dir,\n        save_prefix  = mask_save_prefix,\n        seed = seed)\n\n    train_gen = zip(image_generator, mask_generator)\n    \n    for (img, mask) in train_gen:\n        img, mask = adjust_data(img, mask)\n        yield (img,mask)\n\ndef adjust_data(img,mask):\n    img = img / 255\n    mask = mask / 255\n    mask[mask > 0.5] = 1\n    mask[mask <= 0.5] = 0\n    \n    return (img, mask)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# From: https://github.com/jocicmarko/ultrasound-nerve-segmentation/blob/master/train.py\ndef dice_coef(y_true, y_pred):\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = K.sum(y_true_f * y_pred_f)\n    return (2. * intersection + 1) / (K.sum(y_true_f) + K.sum(y_pred_f) + 1)\n\ndef dice_coef_loss(y_true, y_pred):\n    return -dice_coef(y_true, y_pred)\n\ndef iou(y_true, y_pred):\n    intersection = K.sum(K.abs(y_true * y_pred))\n    sum_ = K.sum(K.square(y_true)) + K.sum(K.square(y_pred))\n    jac = (intersection + 1) / (sum_ - intersection + 1)\n    return jac","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def unet(input_size=(128, 128, 3)):\n    inputs = Input(input_size)\n    \n    conv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)\n    conv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv1)\n    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n\n    conv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool1)\n    conv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv2)\n    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n\n    conv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool2)\n    conv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv3)\n    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n\n    conv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool3)\n    conv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv4)\n    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n\n    conv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(pool4)\n    conv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(conv5)\n\n    up6 = concatenate([Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(conv5), conv4], axis=3)\n    conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(up6)\n    conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv6)\n\n    up7 = concatenate([Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(conv6), conv3], axis=3)\n    conv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(up7)\n    conv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv7)\n\n    up8 = concatenate([Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(conv7), conv2], axis=3)\n    conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(up8)\n    conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv8)\n\n    up9 = concatenate([Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(conv8), conv1], axis=3)\n    conv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(up9)\n    conv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv9)\n\n    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)\n\n    return Model(inputs=[inputs], outputs=[conv10])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas\nfrom sklearn.model_selection import KFold\n\ndf = pandas.DataFrame(data={\"filename\": train_files, 'mask' : mask_files, 'dilate' : dilate_files})\n\nkf = KFold(n_splits = 5, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator_args = dict(rotation_range=0.2,\n                            width_shift_range=0.05,\n                            height_shift_range=0.05,\n                            shear_range=0.05,\n                            zoom_range=0.05,\n                            horizontal_flip=True,\n                            fill_mode='nearest')\n\nhistories = []\nlosses = []\naccuracies = []\ndicecoefs = []\nious = []\n\nBATCH_SIZE = 4\nEPOCHS = 120\n\nfor k, (train_index, test_index) in enumerate(kf.split(df)):\n    train_data_frame = df.iloc[train_index]\n    test_data_frame = df.iloc[test_index]\n    \n    train_gen = train_generator(train_data_frame, BATCH_SIZE,\n                                None,\n                                train_generator_args,\n                                target_size=(512,512))\n\n    test_gener = train_generator(test_data_frame, BATCH_SIZE,\n                                None,\n                                train_generator_args,\n                                target_size=(512,512))\n\n    model = unet(input_size=(512,512,3))\n    model.compile(optimizer=Adam(lr=2e-6), loss=dice_coef_loss, \\\n                      metrics=[iou, dice_coef, 'binary_accuracy'])\n    model.summary()\n\n    model_checkpoint = ModelCheckpoint(str(k+1) + '_unet_lung_seg.hdf5', \n                                       verbose=1, \n                                       save_best_only=True)\n\n    history = model.fit_generator(train_gen,\n                                  steps_per_epoch=len(train_data_frame) / BATCH_SIZE, \n                                  epochs=EPOCHS, \n                                  callbacks=[model_checkpoint],\n                                  validation_data = test_gener,\n                                  validation_steps=len(test_data_frame) / BATCH_SIZE)\n    \n    model = load_model(str(k+1) + '_unet_lung_seg.hdf5', custom_objects={'dice_coef_loss': dice_coef_loss, 'iou': iou, 'dice_coef': dice_coef})\n    \n    test_gen = train_generator(test_data_frame, BATCH_SIZE,\n                                None,\n                                train_generator_args,\n                                target_size=(512,512))\n    results = model.evaluate(test_gen, steps=len(test_data_frame))\n    results = dict(zip(model.metrics_names,results))\n    \n    histories.append(history)\n    accuracies.append(results['binary_accuracy'])\n    losses.append(results['loss'])\n    dicecoefs.append(results['dice_coef'])\n    ious.append(results['iou'])\n    \n    break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('accuracies : ', accuracies)\nprint('losses : ', losses)\nprint('dicecoefs : ', dicecoefs)\nprint('ious : ', ious)\n\nprint('-----------------------------------------------------------------------------')\nprint('-----------------------------------------------------------------------------')\n\nprint('average accuracy : ', np.mean(np.array(accuracies)))\nprint('average loss : ', np.mean(np.array(losses)))\nprint('average dicecoefs : ', np.mean(np.array(dicecoefs)))\nprint('average ious : ', np.mean(np.array(ious)))\nprint()\n\nprint('standard deviation of accuracy : ', np.std(np.array(accuracies)))\nprint('standard deviation of loss : ', np.std(np.array(losses)))\nprint('standard deviation of dicecoefs : ', np.std(np.array(dicecoefs)))\nprint('standard deviation of ious : ', np.std(np.array(ious)))\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pickle\n\nfor h, history in enumerate(histories):\n\n    keys = history.history.keys()\n    fig, axs = plt.subplots(1, len(keys)//2, figsize = (25, 5))\n    fig.suptitle('No. ' + str(h+1) + ' Fold Results', fontsize=30)\n\n    for k, key in enumerate(list(keys)[:len(keys)//2]):\n        training = history.history[key]\n        validation = history.history['val_' + key]\n\n        epoch_count = range(1, len(training) + 1)\n\n        axs[k].plot(epoch_count, training, 'r--')\n        axs[k].plot(epoch_count, validation, 'b-')\n        axs[k].legend(['Training ' + key, 'Validation ' + key])\n        \n    with open(str(h+1) + '_mri_trainHistoryDict', 'wb') as file_pi:\n        pickle.dump(history.history, file_pi)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = load_model('1_unet_lung_seg.hdf5', custom_objects={'dice_coef_loss': dice_coef_loss, 'iou': iou, 'dice_coef': dice_coef})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(10):\n    index = np.random.randint(0, len(train_files))\n    img = cv2.imread(train_files[index])\n    img = cv2.resize(img, (512,512))\n    img = img / 255\n    img = img[np.newaxis, :, :, :]\n    pred = model.predict(img)\n\n    plt.figure(figsize=(12,12))\n    plt.subplot(1,3,1)\n    plt.imshow(cv2.imread(train_files[index]))\n    plt.title('Original Image')\n    plt.subplot(1,3,2)\n    plt.imshow(np.squeeze(cv2.imread(dilate_files[index])))\n    plt.title('Original Mask')\n    plt.subplot(1,3,3)\n    plt.imshow(np.squeeze(pred) > .5)\n    plt.title('Prediction')\n    plt.show()","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}