{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":61446,"databundleVersionId":6962461,"sourceType":"competition"}],"dockerImageVersionId":30558,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')\n\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport tifffile as tiff\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.utils import plot_model\nfrom sklearn.model_selection import train_test_split\nimport os\nimport numpy as np\nimport random\n\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, BatchNormalization, Activation, Concatenate","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-11-23T19:00:50.632657Z","iopub.execute_input":"2023-11-23T19:00:50.633024Z","iopub.status.idle":"2023-11-23T19:00:50.640221Z","shell.execute_reply.started":"2023-11-23T19:00:50.632988Z","shell.execute_reply":"2023-11-23T19:00:50.639262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import tensorflow as tf\n\n# # Check if GPU is available and output the device name\n# gpu_devices = tf.config.experimental.list_physical_devices('GPU')\n# if gpu_devices:\n#     print(\"GPU is available:\", gpu_devices)\n#     for device in gpu_devices:\n#         tf.config.experimental.set_memory_growth(device, True)\n# else:\n#     print(\"GPU is not available, using CPU instead.\")\n","metadata":{"execution":{"iopub.status.busy":"2023-11-20T20:40:16.696311Z","iopub.execute_input":"2023-11-20T20:40:16.696858Z","iopub.status.idle":"2023-11-20T20:40:16.701144Z","shell.execute_reply.started":"2023-11-20T20:40:16.696830Z","shell.execute_reply":"2023-11-20T20:40:16.700238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the seed value\nseed_value = 42\n\n# 1. Set `PYTHONHASHSEED` environment variable at a fixed value\nos.environ['PYTHONHASHSEED'] = str(seed_value)\n\n# 2. Set `python` built-in pseudo-random generator at a fixed value\nrandom.seed(seed_value)\n\n# 3. Set `numpy` pseudo-random generator at a fixed value\nnp.random.seed(seed_value)\n\n# 4. Set the `tensorflow` pseudo-random generator at a fixed value\ntf.random.set_seed(seed_value)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:00:53.897771Z","iopub.execute_input":"2023-11-23T19:00:53.898154Z","iopub.status.idle":"2023-11-23T19:00:53.903762Z","shell.execute_reply.started":"2023-11-23T19:00:53.898123Z","shell.execute_reply":"2023-11-23T19:00:53.902617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the base path\nbase_path = '/kaggle/input/blood-vessel-segmentation/train'\n\n# Initialize lists to store image and label paths\nimage_files = []\nlabel_files = []\n\n# Iterate over each subdirectory in the train directory\nfor dataset in os.listdir(base_path):\n    # Construct the paths to the image and label subdirectories\n    images_path = os.path.join(base_path, dataset, 'images')\n    labels_path = os.path.join(base_path, dataset, 'labels')\n    \n    # Check if these paths are directories\n    if os.path.isdir(images_path) and os.path.isdir(labels_path):\n        # List and sort the image and label files in these directories\n        image_files += sorted([os.path.join(images_path, f) for f in os.listdir(images_path) if f.endswith('.tif')])\n        label_files += sorted([os.path.join(labels_path, f) for f in os.listdir(labels_path) if f.endswith('.tif')])\n\n# Check the number of images and labels gathered\nprint(f\"Total images: {len(image_files)}\")\nprint(f\"Total labels: {len(label_files)}\")","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:02:05.735645Z","iopub.execute_input":"2023-11-23T19:02:05.736012Z","iopub.status.idle":"2023-11-23T19:02:07.877492Z","shell.execute_reply.started":"2023-11-23T19:02:05.735980Z","shell.execute_reply":"2023-11-23T19:02:07.876525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import matplotlib.pyplot as plt\n# import tifffile as tiff\n\n# # Set the base path\n# base_path = '/kaggle/input/blood-vessel-segmentation/train'  \n\n# # Replace 'kidney_1_dense' with the dataset you want to explore\n# dataset = 'kidney_1_voi'\n\n# # Paths to images and labels\n# images_path = os.path.join(base_path, dataset, 'images')\n# labels_path = os.path.join(base_path, dataset, 'labels')\n\n# # List the files in the directories\n# image_files = sorted([os.path.join(images_path, f) for f in os.listdir(images_path) if f.endswith('.tif')])\n# label_files = sorted([os.path.join(labels_path, f) for f in os.listdir(labels_path) if f.endswith('.tif')])\n\n# # Function to display a set of images\n# def show_images(images, titles=None, cmap='gray'):\n#     n = len(images)\n#     fig, axes = plt.subplots(1, n, figsize=(20, 10))\n#     if not isinstance(axes, np.ndarray):\n#         axes = [axes]\n#     for idx, ax in enumerate(axes):\n#         ax.imshow(images[idx], cmap=cmap)\n#         if titles:\n#             ax.set_title(titles[idx])\n#         ax.axis('off')\n#     plt.tight_layout()\n#     plt.show()\n\n# # Load and display the first image and its mask\n# first_image = tiff.imread(image_files[0])\n# first_label = tiff.imread(label_files[0])\n\n# show_images([first_image, first_label], titles=['First Image', 'First Label'])\n\n# # Basic statistics about the images\n# image_shapes = [tiff.imread(file).shape for file in image_files]\n\n# print(f\"Number of images: {len(image_files)}\")\n# print(f\"Image shapes: {set(image_shapes)}\")\n\n# # It's useful to see the distribution of pixel values\n# pixel_values = first_image.flatten()\n# plt.hist(pixel_values, bins=50, color='blue', alpha=0.7)\n# plt.title('Pixel Value Distribution')\n# plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-20T20:40:16.702100Z","iopub.execute_input":"2023-11-20T20:40:16.702381Z","iopub.status.idle":"2023-11-20T20:40:17.221009Z","shell.execute_reply.started":"2023-11-20T20:40:16.702358Z","shell.execute_reply":"2023-11-20T20:40:17.219955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_image(path):\n    # Load the image using tifffile\n    image = tiff.imread(path)\n    \n    # If the image has more than one channel, extract just one channel\n    if image.ndim > 2 and image.shape[2] > 1:\n        image = image[..., 0]\n    \n    # Normalize the image to [0, 1] range\n    image = image / 255.0\n    \n    # Convert image to a TensorFlow tensor\n    image_tensor = tf.convert_to_tensor(image, dtype=tf.float32)\n    \n    # Add a channel dimension if it does not exist\n    if image_tensor.ndim == 2:\n        image_tensor = image_tensor[..., tf.newaxis]\n    \n    # Ensure image tensor is 3D at this point\n    if image_tensor.ndim != 3:\n        raise ValueError('Image tensor must be 3 dimensions [height, width, channels]')\n    \n    # Resize the image to the desired size\n    image_tensor = tf.image.resize(image_tensor, [256, 256])\n    \n    return image_tensor\n\ndef preprocess_mask(path):\n    # Load the mask using tifffile\n    mask = tiff.imread(path)\n    \n    # If the mask has more than one channel, extract just one channel\n    if mask.ndim > 2 and mask.shape[2] > 1:\n        mask = mask[..., 0]\n    \n    # Normalize the mask to be in [0, 1]\n    mask = mask / 255.0 if mask.max() > 1 else mask\n    \n    # Convert mask to a TensorFlow tensor\n    mask_tensor = tf.convert_to_tensor(mask, dtype=tf.float32)\n    \n    # Add a channel dimension if it does not exist\n    if mask_tensor.ndim == 2:\n        mask_tensor = mask_tensor[..., tf.newaxis]\n    \n    # Ensure mask tensor is 3D at this point\n    if mask_tensor.ndim != 3:\n        raise ValueError('Mask tensor must be 3 dimensions [height, width, channels]')\n    \n    # Resize the mask to the desired size\n    mask_tensor = tf.image.resize(mask_tensor, [256, 256], method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)\n    \n    # The resize operation could push the values away from 0 and 1, we threshold to ensure it's a proper mask\n    mask_tensor = tf.where(mask_tensor > 0.5, 1, 0)\n    \n    return mask_tensor","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:07:32.491901Z","iopub.execute_input":"2023-11-23T19:07:32.492723Z","iopub.status.idle":"2023-11-23T19:07:32.502694Z","shell.execute_reply.started":"2023-11-23T19:07:32.492692Z","shell.execute_reply":"2023-11-23T19:07:32.501786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Subset 10% of the dataset for quick experiments\nsubset_size = int(0.9 * len(image_files))\nimage_files_subset = image_files[:subset_size]\nlabel_files_subset = label_files[:subset_size]\n\n# Preprocess and load images into memory (This might take a lot of RAM, be careful with large datasets)\nimages = np.array([preprocess_image(f) for f in image_files_subset])\nmasks = np.array([preprocess_mask(f) for f in label_files_subset])\n\n# Split into train and validation sets\nX_train, X_val, y_train, y_val = train_test_split(images, masks, test_size=0.3, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:07:33.639360Z","iopub.execute_input":"2023-11-23T19:07:33.639997Z","iopub.status.idle":"2023-11-23T19:15:34.845305Z","shell.execute_reply.started":"2023-11-23T19:07:33.639935Z","shell.execute_reply":"2023-11-23T19:15:34.844051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Building the SegNet Model\ndef encoder_block(input_tensor, n_filters, kernel_size=3, batchnorm=True):\n    # first layer\n    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer=\"he_normal\",\n               padding=\"same\")(input_tensor)\n    if batchnorm:\n        x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    # second layer\n    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer=\"he_normal\",\n               padding=\"same\")(x)\n    if batchnorm:\n        x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    return x\n\ndef decoder_block(input_tensor, skip_tensor, n_filters, kernel_size=3, batchnorm=True):\n    x = UpSampling2D(size=(2, 2))(input_tensor)\n    x = Concatenate()([x, skip_tensor])\n    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer=\"he_normal\",\n               padding=\"same\")(x)\n    if batchnorm:\n        x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer=\"he_normal\",\n               padding=\"same\")(x)\n    if batchnorm:\n        x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n    return x\n\ndef get_segnet_model(input_img, n_filters=64, n_classes=1, dropout=0.1, batchnorm=True):\n    # Contracting Path (encoder)\n    c1 = encoder_block(input_img, n_filters * 1, kernel_size=3, batchnorm=batchnorm)\n    p1 = MaxPooling2D((2, 2))(c1)\n    \n    c2 = encoder_block(p1, n_filters * 2, kernel_size=3, batchnorm=batchnorm)\n    p2 = MaxPooling2D((2, 2))(c2)\n    \n    c3 = encoder_block(p2, n_filters * 4, kernel_size=3, batchnorm=batchnorm)\n    p3 = MaxPooling2D((2, 2))(c3)\n    \n    c4 = encoder_block(p3, n_filters * 8, kernel_size=3, batchnorm=batchnorm)\n    p4 = MaxPooling2D((2, 2))(c4)\n    \n    # Expanding Path (decoder)\n    u6 = decoder_block(c4, c3, n_filters * 4, kernel_size=3, batchnorm=batchnorm)\n    u7 = decoder_block(u6, c2, n_filters * 2, kernel_size=3, batchnorm=batchnorm)\n    u8 = decoder_block(u7, c1, n_filters * 1, kernel_size=3, batchnorm=batchnorm)\n    \n    # Output layer\n    output_img = Conv2D(n_classes, (1, 1), activation='sigmoid')(u8)\n    \n    return Model(inputs=input_img, outputs=output_img)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:15:34.847488Z","iopub.execute_input":"2023-11-23T19:15:34.848027Z","iopub.status.idle":"2023-11-23T19:15:34.862673Z","shell.execute_reply.started":"2023-11-23T19:15:34.847994Z","shell.execute_reply":"2023-11-23T19:15:34.861766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras import backend as K\nfrom keras.losses import binary_crossentropy\nimport tensorflow as tf\n\ndef dice_coef(y_true, y_pred, smooth=1):\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 + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n\ndef iou_coef(y_true, y_pred, smooth=1):\n  intersection = K.sum(K.abs(y_true * y_pred), axis=[1,2,3])\n  union = K.sum(y_true,[1,2,3])+K.sum(y_pred,[1,2,3])-intersection\n  iou = K.mean((intersection + smooth) / (union + smooth), axis=0)\n  return iou\n\ndef dice_loss(y_true, y_pred):\n    smooth = 1.\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = y_true_f * y_pred_f\n    score = (2. * K.sum(intersection) + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    return 1. - score\n\ndef bce_dice_loss(y_true, y_pred):\n    return binary_crossentropy(tf.cast(y_true, tf.float32), y_pred) + 0.5 * dice_loss(tf.cast(y_true, tf.float32), y_pred)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:15:34.863737Z","iopub.execute_input":"2023-11-23T19:15:34.864076Z","iopub.status.idle":"2023-11-23T19:15:34.878299Z","shell.execute_reply.started":"2023-11-23T19:15:34.864050Z","shell.execute_reply":"2023-11-23T19:15:34.877188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ModelCheckpoint, LearningRateScheduler, TensorBoard\n\n# Early Stopping\nearly_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1)\n\n# Learning Rate Scheduler\ndef lr_scheduler(epoch, lr):\n    decay_rate = 0.1\n    decay_step = 30\n    if epoch % decay_step == 0 and epoch:\n        return lr * decay_rate\n    return lr\n\nlr_scheduler = LearningRateScheduler(lr_scheduler, verbose=1)\n\n# ModelCheckpoint\ncheckpoint_path = \"/kaggle/working/model_checkpoint.h5\"\nmodel_checkpoint = ModelCheckpoint(checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:15:34.880441Z","iopub.execute_input":"2023-11-23T19:15:34.880816Z","iopub.status.idle":"2023-11-23T19:15:34.891116Z","shell.execute_reply.started":"2023-11-23T19:15:34.880785Z","shell.execute_reply":"2023-11-23T19:15:34.890157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Adjust the input shape to match your dataset (height, width, channels)\ninput_img = Input((256, 256, 1), name='img')\nmodel = get_segnet_model(input_img)\nmodel.compile(optimizer='adam', loss=bce_dice_loss,metrics=[dice_coef,iou_coef])\n# model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-20T20:57:25.937569Z","iopub.execute_input":"2023-11-20T20:57:25.937932Z","iopub.status.idle":"2023-11-20T21:02:44.420079Z","shell.execute_reply.started":"2023-11-20T20:57:25.937902Z","shell.execute_reply":"2023-11-20T21:02:44.419168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom keras.models import load_model\n\ncheckpoint_path = \"/kaggle/working/model_checkpoint.h5\"\n\n# Function to create a new model instance\ndef create_model():\n    input_img = Input((256, 256, 1), name='img')\n    model = get_segnet_model(input_img)\n    model.compile(optimizer='adam', loss=bce_dice_loss, metrics=[dice_coef, iou_coef])\n    return model\n\n# Check if a checkpoint exists\nif os.path.exists(checkpoint_path):\n    print(\"Loading model from checkpoint\")\n    model = load_model(checkpoint_path, custom_objects={'bce_dice_loss': bce_dice_loss, \n                                                        'dice_coef': dice_coef, \n                                                        'iou_coef': iou_coef})\n    print(\"Model Loaded from Checkpoint\")\nelse:\n    print(\"Creating a new model\")\n    model = create_model()","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:16:06.095632Z","iopub.execute_input":"2023-11-23T19:16:06.096015Z","iopub.status.idle":"2023-11-23T19:16:06.843795Z","shell.execute_reply.started":"2023-11-23T19:16:06.095959Z","shell.execute_reply":"2023-11-23T19:16:06.842874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\n# Assume 'train_images', 'train_masks', 'val_images', and 'val_masks' are already loaded and preprocessed as per previous steps\nresults = model.fit(\n    X_train, y_train,\n    batch_size=16,\n    epochs=60,\n    validation_data=(X_val, y_val),\n    callbacks=[early_stopping, lr_scheduler, model_checkpoint]\n)\n\n    ","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:16:23.734278Z","iopub.execute_input":"2023-11-23T19:16:23.735168Z","iopub.status.idle":"2023-11-23T19:18:56.046829Z","shell.execute_reply.started":"2023-11-23T19:16:23.735129Z","shell.execute_reply":"2023-11-23T19:18:56.046026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Extract the history from the results\nhistory = results.history\n\n# Plotting Training and Validation Loss\nplt.figure(figsize=(12, 4))\nplt.subplot(1, 2, 1)\nplt.plot(history['loss'], label='Train Loss')\nplt.plot(history['val_loss'], label='Validation Loss')\nplt.title('Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\n\n# Plotting Training and Validation Dice Coefficient\nplt.subplot(1, 2, 2)\nplt.plot(history['dice_coef'], label='Train Dice Coefficient')\nplt.plot(history['val_dice_coef'], label='Validation Dice Coefficient')\nplt.title('Dice Coefficient Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Dice Coefficient')\nplt.legend()\n\nplt.show()\n\n# Plotting Training and Validation IoU Coefficient\nplt.figure(figsize=(12, 4))\nplt.subplot(1, 2, 1)\nplt.plot(history['iou_coef'], label='Train IoU Coefficient')\nplt.plot(history['val_iou_coef'], label='Validation IoU Coefficient')\nplt.title('IoU Coefficient Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('IoU Coefficient')\nplt.legend()\n\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:18:58.271096Z","iopub.execute_input":"2023-11-23T19:18:58.271755Z","iopub.status.idle":"2023-11-23T19:18:59.124434Z","shell.execute_reply.started":"2023-11-23T19:18:58.271723Z","shell.execute_reply":"2023-11-23T19:18:59.123345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Assuming X_val and y_val are your validation images and masks\nnum_samples = 5  # Choose the number of samples you want to display\nsample_indices = random.sample(range(len(X_val)), num_samples)\n\nsample_images = X_val[sample_indices]\nsample_true_masks = y_val[sample_indices]\n","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:19:17.445188Z","iopub.execute_input":"2023-11-23T19:19:17.445549Z","iopub.status.idle":"2023-11-23T19:19:17.451025Z","shell.execute_reply.started":"2023-11-23T19:19:17.445518Z","shell.execute_reply":"2023-11-23T19:19:17.449999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_pred_masks = model.predict(sample_images)\n\n# Thresholding example (adjust threshold as needed)\nsample_pred_masks = (sample_pred_masks > 0.5).astype(np.uint8)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:19:21.599004Z","iopub.execute_input":"2023-11-23T19:19:21.599640Z","iopub.status.idle":"2023-11-23T19:19:22.324320Z","shell.execute_reply.started":"2023-11-23T19:19:21.599609Z","shell.execute_reply":"2023-11-23T19:19:22.323549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(num_samples):\n    plt.figure(figsize=(12, 5))\n\n    # Display original image\n    plt.subplot(1, 3, 1)\n    plt.imshow(sample_images[i], cmap='gray')\n    plt.title('Original Image')\n    plt.axis('off')\n\n    # Display true mask\n    plt.subplot(1, 3, 2)\n    plt.imshow(sample_true_masks[i], cmap='gray')\n    plt.title('True Mask')\n    plt.axis('off')\n\n    # Display predicted mask\n    plt.subplot(1, 3, 3)\n    plt.imshow(sample_pred_masks[i], cmap='gray')\n    plt.title('Predicted Mask')\n    plt.axis('off')\n\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:19:25.342143Z","iopub.execute_input":"2023-11-23T19:19:25.342998Z","iopub.status.idle":"2023-11-23T19:19:26.978860Z","shell.execute_reply.started":"2023-11-23T19:19:25.342958Z","shell.execute_reply":"2023-11-23T19:19:26.977857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load test images (assuming similar folder structure as training)\ntest_base_path = '/kaggle/input/blood-vessel-segmentation/test'\ntest_image_files = []\n\nfor dataset in os.listdir(test_base_path):\n    images_path = os.path.join(test_base_path, dataset, 'images')\n    if os.path.isdir(images_path):\n        test_image_files += sorted([os.path.join(images_path, f) for f in os.listdir(images_path) if f.endswith('.tif')])\n\n# Preprocess test images (similar to training images preprocessing)\ntest_images = np.array([preprocess_image(f) for f in test_image_files])","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:11.668343Z","iopub.execute_input":"2023-11-23T19:24:11.669080Z","iopub.status.idle":"2023-11-23T19:24:11.868223Z","shell.execute_reply.started":"2023-11-23T19:24:11.669047Z","shell.execute_reply":"2023-11-23T19:24:11.867243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict masks\npredicted_masks = model.predict(test_images)\n# predicted_masks = model.predict(X_val)\n\n# Post-process masks: threshold and resize to original size\nthresholded_masks = (predicted_masks > 0.5).astype(np.uint8)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:14.473513Z","iopub.execute_input":"2023-11-23T19:24:14.474477Z","iopub.status.idle":"2023-11-23T19:24:14.966726Z","shell.execute_reply.started":"2023-11-23T19:24:14.474432Z","shell.execute_reply":"2023-11-23T19:24:14.965753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    rle = ' '.join(str(x) for x in runs)\n    if rle=='':\n        rle = '1 0'\n    return rle","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:17.291957Z","iopub.execute_input":"2023-11-23T19:24:17.292717Z","iopub.status.idle":"2023-11-23T19:24:17.299023Z","shell.execute_reply.started":"2023-11-23T19:24:17.292684Z","shell.execute_reply":"2023-11-23T19:24:17.297908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\nrles = [rle_encode(mask.reshape(256, 256)) for mask in thresholded_masks]\nids = [f'{p.split(\"/\")[-3]}_{os.path.basename(p).split(\".\")[0]}' for p in test_image_files]\n\nsubmission = pd.DataFrame({\n    \"id\": ids,\n    \"rle\": rles\n})","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:20.148777Z","iopub.execute_input":"2023-11-23T19:24:20.149141Z","iopub.status.idle":"2023-11-23T19:24:20.158570Z","shell.execute_reply.started":"2023-11-23T19:24:20.149111Z","shell.execute_reply":"2023-11-23T19:24:20.157578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:23.243481Z","iopub.execute_input":"2023-11-23T19:24:23.244288Z","iopub.status.idle":"2023-11-23T19:24:23.266009Z","shell.execute_reply.started":"2023-11-23T19:24:23.244257Z","shell.execute_reply":"2023-11-23T19:24:23.264888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-23T19:24:26.134495Z","iopub.execute_input":"2023-11-23T19:24:26.134899Z","iopub.status.idle":"2023-11-23T19:24:26.145286Z","shell.execute_reply.started":"2023-11-23T19:24:26.134857Z","shell.execute_reply":"2023-11-23T19:24:26.144219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}