{"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"},{"sourceId":7278136,"sourceType":"datasetVersion","datasetId":4219741}],"dockerImageVersionId":30615,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport glob\nimport random\nimport numpy as np\nfrom PIL import Image\nimport cv2\nfrom tqdm import tqdm\nimport tensorflow as tf\nfrom tensorflow.keras.layers import Conv3D, MaxPool3D, concatenate, Input, Dropout, PReLU, Conv3DTranspose, BatchNormalization, TimeDistributed, Conv2D, ConvLSTM2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras import optimizers\nfrom tensorflow.keras.callbacks import ModelCheckpoint, TensorBoard, LambdaCallback\nimport csv\nimport gc\n\npatch_size=[64,64,64]\n\ndef unet_core(x, filter_size=8, kernel_size=(3, 3, 3)):\n    x = Conv3D(filters=filter_size,\n               kernel_size=kernel_size,\n               padding='same',\n               kernel_initializer='he_normal',dtype=tf.float32)(x)\n    x = BatchNormalization()(x)\n    x = PReLU()(x)\n    x = Conv3D(filters=filter_size,\n               kernel_size=kernel_size,\n               padding='same',\n               kernel_initializer='he_normal',dtype=tf.float32)(x)\n    x = BatchNormalization()(x)\n    x = PReLU()(x)\n    return x\n\ndef unet3d(patch_size=[64,64,64,1], n_label=1):\n    input_layer = Input(shape=patch_size,dtype=tf.float32)\n    d1 = unet_core(input_layer, filter_size=96, kernel_size=(3, 3, 3))\n    l = MaxPool3D(strides=(2, 2, 2))(d1)\n    d2 = unet_core(l, filter_size=96*2, kernel_size=(3, 3, 3))\n    l = MaxPool3D(strides=(2, 2, 2))(d2)\n    d3 = unet_core(l, filter_size=96*4, kernel_size=(3, 3, 3))\n    l = MaxPool3D(strides=(2, 2, 2))(d3)\n    d4 = unet_core(l, filter_size=96*8, kernel_size=(3, 3, 3))\n    l = MaxPool3D(strides=(2, 2, 2))(d4)\n\n    b = unet_core(l, filter_size=96*16, kernel_size=(3, 3, 3))\n\n    l = Conv3DTranspose(filters=96*8, kernel_size=(2, 2, 2),  padding='same', strides=2, kernel_initializer='he_normal',dtype=tf.float32)(b)\n    l = concatenate([l, d4])\n    u4 = unet_core(l, filter_size=96*4, kernel_size=(3, 3, 3))\n    l = Conv3DTranspose(filters=192, kernel_size=(2, 2, 2),  padding='same', strides=2, kernel_initializer='he_normal',dtype=tf.float32)(u4)\n    l = concatenate([l, d3])\n    u3 = unet_core(l, filter_size=96*4, kernel_size=(3, 3, 3))\n    l = Conv3DTranspose(filters=192, kernel_size=(2, 2, 2),  padding='same', strides=2, kernel_initializer='he_normal',dtype=tf.float32)(u3)\n    l = concatenate([l, d2])\n    u2 = unet_core(l, filter_size=96*2, kernel_size=(3, 3, 3))\n    l = Conv3DTranspose(filters=96*2, kernel_size=(2, 2, 2),  padding='same', strides=2, kernel_initializer='he_normal',dtype=tf.float32)(u2)\n    l = concatenate([l, d1])\n    u1 = unet_core(l, filter_size=96, kernel_size=(3, 3, 3))\n    output_layer = Conv3D(filters=n_label, kernel_size=(1, 1, 1), activation='sigmoid')(u1)\n    model = Model(input_layer, output_layer)\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-12-25T13:59:09.839119Z","iopub.execute_input":"2023-12-25T13:59:09.839411Z","iopub.status.idle":"2023-12-25T13:59:13.598895Z","shell.execute_reply.started":"2023-12-25T13:59:09.839379Z","shell.execute_reply":"2023-12-25T13:59:13.597494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gpus = tf.config.experimental.list_physical_devices('GPU')\ntf.config.experimental.set_memory_growth(gpus[0], True)\ntf.config.experimental.set_virtual_device_configuration(\n  gpus[0],\n  [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=15024)])\n\nif not gpus:\n    raise BaseException('ERROR: No GPU devices found; please make sure you have a GPU and TensorFlow GPU installed.')\nelse:\n    print('Running on GPU')\n\nstrategy = tf.distribute.MirroredStrategy()","metadata":{"execution":{"iopub.status.busy":"2023-12-25T13:59:13.604824Z","iopub.execute_input":"2023-12-25T13:59:13.605467Z","iopub.status.idle":"2023-12-25T13:59:14.851840Z","shell.execute_reply.started":"2023-12-25T13:59:13.605431Z","shell.execute_reply":"2023-12-25T13:59:14.850671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.backend.clear_session()\nwith strategy.scope():\n    model = unet3d()\n    model.load_weights('/kaggle/input/unet3dmodel/unet_3d.h5')","metadata":{"execution":{"iopub.status.busy":"2023-12-25T13:59:14.853006Z","iopub.execute_input":"2023-12-25T13:59:14.853293Z","iopub.status.idle":"2023-12-25T13:59:25.663488Z","shell.execute_reply.started":"2023-12-25T13:59:14.853269Z","shell.execute_reply":"2023-12-25T13:59:25.662438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def normalize_mean_std(tmp):\n    tmp_std = np.std(tmp) + 0.0001\n    tmp_mean = np.mean(tmp)\n    tmp = (tmp - tmp_mean) / tmp_std\n    return tmp\n\ndef sixtyfour(num):\n    rem = num%64\n    if rem>0:\n        num += (64-rem)\n    return num\n\ndef get_patch_indices(image_shape, patch_size):\n    max_indices = [(image_shape[dim]-1) / patch_size[dim] +1 for dim in range(3)]\n    se = []\n    for i in range(int(max_indices[0])):\n        for j in range(int(max_indices[1])):\n            for k in range(int(max_indices[2])):\n                s1 = i*patch_size[0]\n                s2 = j*patch_size[1]\n                s3 = k*patch_size[2]\n                e1 = (i+1)*patch_size[0]\n                e2 = (j+1)*patch_size[1]\n                e3 = (k+1)*patch_size[2]    \n                s = [s1,s2,s3]\n                e = [e1,e2,e3]\n                se.append((s,e))\n    return se\n\n\ndef extract_patch(data, start_indices, end_indices, target_shape=(64, 64, 64), pad_value=0):\n    patch = data[start_indices[0]:end_indices[0], start_indices[1]:end_indices[1], start_indices[2]:end_indices[2]]\n    pad_width = [(0, max(0 , target_shape[i] - patch.shape[i])) for i in range(len(target_shape))]\n    padded_patch = np.pad(patch, pad_width, mode='constant', constant_values=pad_value)\n    return tf.convert_to_tensor(np.expand_dims(padded_patch, axis=-1), dtype=tf.uint8)\n\ndef load_data(image_dir, idx, image_ext='.tif'):\n    image_paths = [os.path.join(image_dir, fname) for fname in sorted(os.listdir(image_dir)) if fname.endswith(image_ext)]\n    return image_paths[idx*64:(idx+1)*64] #depth is 64","metadata":{"execution":{"iopub.status.busy":"2023-12-25T13:59:25.665806Z","iopub.execute_input":"2023-12-25T13:59:25.666159Z","iopub.status.idle":"2023-12-25T13:59:25.680038Z","shell.execute_reply.started":"2023-12-25T13:59:25.666129Z","shell.execute_reply":"2023-12-25T13:59:25.679146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_metadata(path,idx):\n    files = sorted(os.listdir(os.path.join(path,'images')))\n    files = files[idx*64:(idx+1)*64]\n    d = len(files)\n    for file in files:\n        filepath = os.path.join(path,'images',file)\n        img = np.array(Image.open(filepath))\n        h,w = img.shape\n        break\n    kidney = os.path.basename(path)\n    return {'kidney':kidney,'path':path,'depth':d,'height':h,'width':w,'names':sorted([os.path.splitext(f)[0] for f in files])}\n\ndef sign(a):\n  if a>0:\n    return 1\n  else:\n    return 0\n\ndef getmask(predictions):\n    return (predictions>0.5)\n\ndef crop_padding(mask,depth,height,width):\n    return mask[:depth, :height, :width]\n\ndef rle2d(img):\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    res = ' '.join(str(x) for x in runs)\n    if len(res)==0:\n        return '1 10'\n    return res\n\ndef rle3d(img3d):\n    encoded = []\n    for img in img3d:\n        encoded.append(rle2d(img))\n    return encoded\n\ndef postprocess_kidney(predictions, metadata):\n    mask = getmask(predictions)\n    depth = metadata['depth']\n    height = metadata['height']\n    width = metadata['width']\n    d = sixtyfour(depth)\n    h = sixtyfour(height)\n    w = sixtyfour(width)\n    mask = mask.reshape((d,h,w))\n    result3d = crop_padding(mask,depth,height,width)\n    result_encoded = rle3d(result3d)\n    key_list = [f\"{metadata['kidney']}_{n}\" for n in metadata['names']]\n    pairs = zip(key_list, result_encoded)\n    result_dict = dict(pairs)\n    return result_dict\n\ndef save_dict_to_csv(data_dict, column_names = ['id','rle'], csv_file_path='submission.csv'):\n    with open(csv_file_path, 'w', newline='') as csv_file:\n        csv_writer = csv.writer(csv_file)\n        csv_writer.writerow(column_names)\n        for key, value in data_dict.items():\n            csv_writer.writerow([key, value])\n    print(f'Data has been saved to {csv_file_path}')\n","metadata":{"execution":{"iopub.status.busy":"2023-12-25T13:59:25.681591Z","iopub.execute_input":"2023-12-25T13:59:25.681896Z","iopub.status.idle":"2023-12-25T13:59:25.700934Z","shell.execute_reply.started":"2023-12-25T13:59:25.681853Z","shell.execute_reply":"2023-12-25T13:59:25.699774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator:\n    def __init__(self, kidney, idx, batch_size=1, patch_size=[64,64,64], labels=[0,1]):\n        self.idx = idx\n        self.batch_size=batch_size\n        self.patch_size = np.asarray(patch_size)\n        self.labels = labels\n        self.data=dict()\n        print(\"Reading data...\")\n        image_3d = []\n        for _img in load_data(os.path.join(kidney,'images'),self.idx):\n            image_3d.append(self._preprocess_image(_img))\n        self.data['image'] = np.array(image_3d)\n        self.data['meta'] = generate_metadata(kidney,idx)\n        del image_3d\n        print(\"Reading data completed {}\".format(len(self.data)))\n        \n    def get_item(self):\n        se = get_patch_indices(self.data['image'].shape, self.patch_size)\n        for sese in se:\n            image_patch = extract_patch(self.data['image'], sese[0], sese[1])\n            yield image_patch\n\n    def _preprocess_image(self, image_path):\n        image = np.array(Image.open(image_path))\n        image = image - np.min(image)\n        image = image / np.max(image)\n        image = (image*255).astype(np.uint8)\n        return image\n\nkidney_list=[\n    \"/kaggle/input/blood-vessel-segmentation/test/kidney_5\",\n    \"/kaggle/input/blood-vessel-segmentation/test/kidney_6\"\n]\n\nkidneys_rle=dict()\nwith strategy.scope():\n    for kidney in kidney_list:\n        idxrange = len(os.listdir(os.path.join(kidney,'images')))\n        idxlist = list(range(idxrange//64 + sign(idxrange%64)))\n        for idx in idxlist:\n            test_generator=Generator(kidney, idx = idx, patch_size=patch_size)\n            meta = test_generator.data['meta']\n            test_tf_gen = tf.data.Dataset.from_generator(test_generator.get_item,\n                            output_signature=(tf.TensorSpec(shape=tf.TensorShape(patch_size+[1]), dtype=tf.float32)))\n            test_tf_gen = test_tf_gen.map(tf.image.per_image_standardization)\n            test_batches = test_tf_gen.batch(1)\n            preds = model.predict(test_batches)\n            rles = postprocess_kidney(preds, meta)\n            kidneys_rle.update(rles)\n            del test_generator\n            del meta\n            del test_tf_gen\n            del test_batches\n            del preds\n            del rles\n            gc.collect()\n    \nsave_dict_to_csv(kidneys_rle)","metadata":{"execution":{"iopub.status.busy":"2023-12-25T14:01:20.930489Z","iopub.execute_input":"2023-12-25T14:01:20.931393Z","iopub.status.idle":"2023-12-25T14:03:51.609753Z","shell.execute_reply.started":"2023-12-25T14:01:20.931357Z","shell.execute_reply":"2023-12-25T14:03:51.608714Z"},"trusted":true},"execution_count":null,"outputs":[]}]}