{"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":"# Abdominal Trauma RGB Mask UNET\nfrom segmentation image, predict organs in CT scan images<br/>\nhttps://www.kaggle.com/stpeteishii/abdominal-trauma-unet-target-organ","metadata":{"papermill":{"duration":0.009655,"end_time":"2023-07-11T04:08:31.528281","exception":false,"start_time":"2023-07-11T04:08:31.518626","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"images: https://www.kaggle.com/code/stpeteishii/one-patient-images-slide-show <br/>\nmasks: https://www.kaggle.com/code/stpeteishii/segmentation-image-of-the-matched-id","metadata":{}},{"cell_type":"markdown","source":"https://arxiv.org/pdf/1505.04597.pdf","metadata":{"papermill":{"duration":0.008294,"end_time":"2023-07-11T04:08:31.545451","exception":false,"start_time":"2023-07-11T04:08:31.537157","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!pip install imantics --quiet","metadata":{"papermill":{"duration":15.417197,"end_time":"2023-07-11T04:08:46.970986","exception":false,"start_time":"2023-07-11T04:08:31.553789","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:16.029016Z","iopub.execute_input":"2023-08-07T05:32:16.030058Z","iopub.status.idle":"2023-08-07T05:32:27.044323Z","shell.execute_reply.started":"2023-08-07T05:32:16.030022Z","shell.execute_reply":"2023-08-07T05:32:27.042961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport json\nimport random\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport imantics\nfrom PIL import Image\nfrom skimage.transform import resize\nfrom sklearn.model_selection import train_test_split\n%matplotlib inline","metadata":{"papermill":{"duration":8.983267,"end_time":"2023-07-11T04:08:55.963588","exception":false,"start_time":"2023-07-11T04:08:46.980321","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.046955Z","iopub.execute_input":"2023-08-07T05:32:27.047697Z","iopub.status.idle":"2023-08-07T05:32:27.057811Z","shell.execute_reply.started":"2023-08-07T05:32:27.047658Z","shell.execute_reply":"2023-08-07T05:32:27.056278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_dir ='/kaggle/input/one-patient-images-slide-show'\nmasks_dir = '/kaggle/input/segmentation-image-of-the-matched-id'\norgans=['bowel','liver','spleen','right kidney','left kidney']","metadata":{"papermill":{"duration":0.02292,"end_time":"2023-07-11T04:08:55.996944","exception":false,"start_time":"2023-07-11T04:08:55.974024","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.059524Z","iopub.execute_input":"2023-08-07T05:32:27.060098Z","iopub.status.idle":"2023-08-07T05:32:27.069705Z","shell.execute_reply.started":"2023-08-07T05:32:27.060064Z","shell.execute_reply":"2023-08-07T05:32:27.068729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_listdir0 = sorted(os.listdir(images_dir))\nimages_listdir=[]\nfor i in range(len(images_listdir0)):\n    if i%4==0:\n        images_listdir+=[images_listdir0[i]]\nimages_listdir= images_listdir[50:100]\nmasks_listdir = sorted(os.listdir(masks_dir))[120:170]\nN=list(range(9))\nrandom_N = N\n#np.random.choice(N, size = 9, replace = False)","metadata":{"papermill":{"duration":0.257623,"end_time":"2023-07-11T04:08:56.264361","exception":false,"start_time":"2023-07-11T04:08:56.006738","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.073084Z","iopub.execute_input":"2023-08-07T05:32:27.073479Z","iopub.status.idle":"2023-08-07T05:32:27.086492Z","shell.execute_reply.started":"2023-08-07T05:32:27.073454Z","shell.execute_reply":"2023-08-07T05:32:27.085544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(images_listdir))\nprint(len(masks_listdir))","metadata":{"papermill":{"duration":0.027463,"end_time":"2023-07-11T04:08:56.301016","exception":false,"start_time":"2023-07-11T04:08:56.273553","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.088322Z","iopub.execute_input":"2023-08-07T05:32:27.088661Z","iopub.status.idle":"2023-08-07T05:32:27.099731Z","shell.execute_reply.started":"2023-08-07T05:32:27.08863Z","shell.execute_reply":"2023-08-07T05:32:27.09876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_size=512\ninput_image_size=(512,512)","metadata":{"papermill":{"duration":0.020017,"end_time":"2023-07-11T04:08:56.336291","exception":false,"start_time":"2023-07-11T04:08:56.316274","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.100868Z","iopub.execute_input":"2023-08-07T05:32:27.101162Z","iopub.status.idle":"2023-08-07T05:32:27.110994Z","shell.execute_reply.started":"2023-08-07T05:32:27.101132Z","shell.execute_reply":"2023-08-07T05:32:27.110144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_image(path):\n    img = cv2.imread(path)\n    img = cv2.resize(img, (image_size, image_size))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    return img","metadata":{"papermill":{"duration":0.018858,"end_time":"2023-07-11T04:08:56.363872","exception":false,"start_time":"2023-07-11T04:08:56.345014","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.112188Z","iopub.execute_input":"2023-08-07T05:32:27.112962Z","iopub.status.idle":"2023-08-07T05:32:27.121783Z","shell.execute_reply.started":"2023-08-07T05:32:27.112931Z","shell.execute_reply":"2023-08-07T05:32:27.120858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"number=60","metadata":{"papermill":{"duration":0.018704,"end_time":"2023-07-11T04:08:56.391595","exception":false,"start_time":"2023-07-11T04:08:56.372891","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.123347Z","iopub.execute_input":"2023-08-07T05:32:27.123684Z","iopub.status.idle":"2023-08-07T05:32:27.133274Z","shell.execute_reply.started":"2023-08-07T05:32:27.123653Z","shell.execute_reply":"2023-08-07T05:32:27.132392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Input images ","metadata":{"papermill":{"duration":0.008863,"end_time":"2023-07-11T04:08:56.409542","exception":false,"start_time":"2023-07-11T04:08:56.400679","status":"completed"},"tags":[]}},{"cell_type":"code","source":"rows = 3\ncols = 3\nfig, ax = plt.subplots(rows, cols, figsize = (10,10))\nfor i, ax in enumerate(ax.flat):\n    if i < len(random_N):\n        img = read_image(f\"{images_dir}/{images_listdir[i]}\")\n        ax.set_title(f\"{images_listdir[i]}\")\n        ax.imshow(img)\n        ax.axis('off')","metadata":{"papermill":{"duration":1.818676,"end_time":"2023-07-11T04:08:58.237091","exception":false,"start_time":"2023-07-11T04:08:56.418415","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:27.134543Z","iopub.execute_input":"2023-08-07T05:32:27.134802Z","iopub.status.idle":"2023-08-07T05:32:28.477016Z","shell.execute_reply.started":"2023-08-07T05:32:27.13478Z","shell.execute_reply":"2023-08-07T05:32:28.475985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Ground truth masks","metadata":{"papermill":{"duration":0.020571,"end_time":"2023-07-11T04:08:58.277611","exception":false,"start_time":"2023-07-11T04:08:58.25704","status":"completed"},"tags":[]}},{"cell_type":"code","source":"fig, ax = plt.subplots(rows, cols, figsize = (10,10))\nfor i, ax in enumerate(ax.flat):\n    if i < len(random_N):\n        if os.path.exists(os.path.join(masks_dir,masks_listdir[i])):\n            img = read_image(f\"{masks_dir}/{masks_listdir[i]}\")\n            img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n            ax.set_title(f\"{masks_listdir[i]}\")\n            ax.imshow(img)\n            ax.axis('off')\n        else:\n            print('not exist')","metadata":{"papermill":{"duration":0.905126,"end_time":"2023-07-11T04:08:59.201955","exception":false,"start_time":"2023-07-11T04:08:58.296829","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:35:33.286476Z","iopub.execute_input":"2023-08-07T05:35:33.286875Z","iopub.status.idle":"2023-08-07T05:35:34.35433Z","shell.execute_reply.started":"2023-08-07T05:35:33.286843Z","shell.execute_reply":"2023-08-07T05:35:34.353256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(rows, cols, figsize = (10,10))\nfor i, ax in enumerate(ax.flat):\n    if i < len(random_N):\n        if os.path.exists(os.path.join(masks_dir,masks_listdir[i])):\n            img = read_image(f\"{masks_dir}/{masks_listdir[i]}\")\n            #img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n            ax.set_title(f\"{masks_listdir[i]}\")\n            ax.imshow(img)\n            ax.axis('off')\n        else:\n            print('not exist')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#MASKS=np.zeros((1,image_size, image_size, 1), dtype=bool)\nMASKS=np.zeros((1,image_size, image_size, 3),dtype=np.uint8) #####\nIMAGES=np.zeros((1,image_size, image_size, 3),dtype=np.uint8)\n\nfor j,file in enumerate(images_listdir): \n    try:\n        image = read_image(f\"{images_dir}/{file}\")\n        image_ex = np.expand_dims(image, axis=0)\n        IMAGES = np.vstack([IMAGES, image_ex])\n        mask = read_image(f\"{masks_dir}/{masks_listdir[j]}\") \n        #mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)\n        mask_ex = np.expand_dims(mask, axis=0)    \n        MASKS = np.vstack([MASKS, mask_ex])\n    except:\n        print(file)\n        continue","metadata":{"papermill":{"duration":1.160612,"end_time":"2023-07-11T04:09:00.38412","exception":false,"start_time":"2023-07-11T04:08:59.223508","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.545388Z","iopub.status.idle":"2023-08-07T05:32:29.546327Z","shell.execute_reply.started":"2023-08-07T05:32:29.546067Z","shell.execute_reply":"2023-08-07T05:32:29.546089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images=np.array(IMAGES)[1:number+1]\nmasks=np.array(MASKS)[1:number+1]\nprint(images.shape,masks.shape)","metadata":{"papermill":{"duration":0.042314,"end_time":"2023-07-11T04:09:00.448602","exception":false,"start_time":"2023-07-11T04:09:00.406288","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.547831Z","iopub.status.idle":"2023-08-07T05:32:29.549829Z","shell.execute_reply.started":"2023-08-07T05:32:29.549418Z","shell.execute_reply":"2023-08-07T05:32:29.549441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_train, images_test, masks_train, masks_test = train_test_split(\n    images, masks, test_size=0.3, random_state=42)","metadata":{"_kg_hide-input":true,"papermill":{"duration":0.040675,"end_time":"2023-07-11T04:09:00.511171","exception":false,"start_time":"2023-07-11T04:09:00.470496","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.551869Z","iopub.status.idle":"2023-08-07T05:32:29.552484Z","shell.execute_reply.started":"2023-08-07T05:32:29.552219Z","shell.execute_reply":"2023-08-07T05:32:29.552242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(images_train), len(masks_train))","metadata":{"papermill":{"duration":0.032989,"end_time":"2023-07-11T04:09:00.573399","exception":false,"start_time":"2023-07-11T04:09:00.54041","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.554396Z","iopub.status.idle":"2023-08-07T05:32:29.554839Z","shell.execute_reply.started":"2023-08-07T05:32:29.554613Z","shell.execute_reply":"2023-08-07T05:32:29.554634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# U-Net","metadata":{"papermill":{"duration":0.02079,"end_time":"2023-07-11T04:09:00.614825","exception":false,"start_time":"2023-07-11T04:09:00.594035","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def conv_block(input, num_filters):\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(input)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    conv = tf.keras.layers.Conv2D(num_filters, 3, padding=\"same\")(conv)\n    conv = tf.keras.layers.BatchNormalization()(conv)\n    conv = tf.keras.layers.Activation(\"relu\")(conv)\n    return conv\n\ndef encoder_block(input, num_filters):\n    skip = conv_block(input, num_filters)\n    pool = tf.keras.layers.MaxPool2D((2,2))(skip)\n    return skip, pool\n\ndef decoder_block(input, skip, num_filters):\n    up_conv = tf.keras.layers.Conv2DTranspose(num_filters, (2,2), strides=2, padding=\"same\")(input)\n    conv = tf.keras.layers.Concatenate()([up_conv, skip])\n    conv = conv_block(conv, num_filters)\n    return conv\n\ndef Unet(input_shape):\n    inputs = tf.keras.layers.Input(input_shape)\n\n    skip1, pool1 = encoder_block(inputs, 64)\n    skip2, pool2 = encoder_block(pool1, 128)\n    skip3, pool3 = encoder_block(pool2, 256)\n    skip4, pool4 = encoder_block(pool3, 512)\n\n    bridge = conv_block(pool4, 1024)\n\n    decode1 = decoder_block(bridge, skip4, 512)\n    decode2 = decoder_block(decode1, skip3, 256)\n    decode3 = decoder_block(decode2, skip2, 128)\n    decode4 = decoder_block(decode3, skip1, 64)\n    outputs = tf.keras.layers.Conv2D(3, 1, padding=\"same\", activation=\"softmax\")(decode4) #####   \n    #outputs = tf.keras.layers.Conv2D(1, 1, padding=\"same\", activation=\"sigmoid\")(decode4)\n    model = tf.keras.models.Model(inputs, outputs, name=\"U-Net\")\n    return model\n\nunet_model = Unet((512,512,3))\nunet_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n#unet_model.summary()","metadata":{"_kg_hide-output":true,"papermill":{"duration":3.40184,"end_time":"2023-07-11T04:09:04.037345","exception":false,"start_time":"2023-07-11T04:09:00.635505","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.556871Z","iopub.status.idle":"2023-08-07T05:32:29.557818Z","shell.execute_reply.started":"2023-08-07T05:32:29.557581Z","shell.execute_reply":"2023-08-07T05:32:29.557604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train\nSuitable number epoch range is narrow.","metadata":{"papermill":{"duration":0.021696,"end_time":"2023-07-11T04:09:04.081495","exception":false,"start_time":"2023-07-11T04:09:04.059799","status":"completed"},"tags":[]}},{"cell_type":"code","source":"unet_result = unet_model.fit(\n    images_train, masks_train, \n    validation_split = 0.3, batch_size = 4, epochs =1500)","metadata":{"papermill":{"duration":147.201421,"end_time":"2023-07-11T04:11:31.304006","exception":false,"start_time":"2023-07-11T04:09:04.102585","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.558923Z","iopub.status.idle":"2023-08-07T05:32:29.559521Z","shell.execute_reply.started":"2023-08-07T05:32:29.559287Z","shell.execute_reply":"2023-08-07T05:32:29.559311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* epochs =800: single color mask\n* epochs =1200: single color mask","metadata":{}},{"cell_type":"markdown","source":"# Predict valid images","metadata":{"papermill":{"duration":0.058091,"end_time":"2023-07-11T04:11:31.42581","exception":false,"start_time":"2023-07-11T04:11:31.367719","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def show_result(idx, og, unet, target, p):\n    \n    fig, axs = plt.subplots(1, 3, figsize=(12,12))\n    axs[0].set_title(\"Original \"+str(idx) )\n    axs[0].imshow(og)\n    axs[0].axis('off')\n    \n    axs[1].set_title(\"U-Net: p>\"+str(p))\n    axs[1].imshow(unet*0.9)\n    axs[1].axis('off')\n    \n    axs[2].set_title(\"Ground Truth\")\n    axs[2].imshow(target)\n    axs[2].axis('off')\n\n    plt.show()","metadata":{"papermill":{"duration":0.070807,"end_time":"2023-07-11T04:11:31.553458","exception":false,"start_time":"2023-07-11T04:11:31.482651","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.561048Z","iopub.status.idle":"2023-08-07T05:32:29.561993Z","shell.execute_reply.started":"2023-08-07T05:32:29.561729Z","shell.execute_reply":"2023-08-07T05:32:29.561756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unet_predict = unet_model.predict(images_test)","metadata":{"papermill":{"duration":5.678511,"end_time":"2023-07-11T04:11:37.295638","exception":false,"start_time":"2023-07-11T04:11:31.617127","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.563275Z","iopub.status.idle":"2023-08-07T05:32:29.563843Z","shell.execute_reply.started":"2023-08-07T05:32:29.563614Z","shell.execute_reply":"2023-08-07T05:32:29.563635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(images_test)","metadata":{"papermill":{"duration":0.068633,"end_time":"2023-07-11T04:11:37.422135","exception":false,"start_time":"2023-07-11T04:11:37.353502","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.56544Z","iopub.status.idle":"2023-08-07T05:32:29.566362Z","shell.execute_reply.started":"2023-08-07T05:32:29.566132Z","shell.execute_reply":"2023-08-07T05:32:29.566156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"r1,r2,r3,r4=0.7,0.8,0.9,0.99","metadata":{"papermill":{"duration":0.066144,"end_time":"2023-07-11T04:11:37.545376","exception":false,"start_time":"2023-07-11T04:11:37.479232","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.56759Z","iopub.status.idle":"2023-08-07T05:32:29.568468Z","shell.execute_reply.started":"2023-08-07T05:32:29.568236Z","shell.execute_reply":"2023-08-07T05:32:29.568257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unet_predict1 = (unet_predict > r1).astype(np.uint8)\nunet_predict2 = (unet_predict > r2).astype(np.uint8)\nunet_predict3 = (unet_predict > r3).astype(np.uint8)\nunet_predict4 = (unet_predict > r4).astype(np.uint8)","metadata":{"papermill":{"duration":0.075937,"end_time":"2023-07-11T04:11:37.684847","exception":false,"start_time":"2023-07-11T04:11:37.60891","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.569706Z","iopub.status.idle":"2023-08-07T05:32:29.570626Z","shell.execute_reply.started":"2023-08-07T05:32:29.570392Z","shell.execute_reply":"2023-08-07T05:32:29.570415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_test_idx = random.sample(range(len(unet_predict)), 3)\nfor idx in show_test_idx: \n    show_result(idx, images_test[idx], unet_predict1[idx], masks_test[idx], r1)\n    show_result(idx, images_test[idx], unet_predict2[idx], masks_test[idx], r2)\n    show_result(idx, images_test[idx], unet_predict3[idx], masks_test[idx], r3)\n    show_result(idx, images_test[idx], unet_predict4[idx], masks_test[idx], r4)\n    print()","metadata":{"papermill":{"duration":3.719208,"end_time":"2023-07-11T04:11:41.462814","exception":false,"start_time":"2023-07-11T04:11:37.743606","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-08-07T05:32:29.571865Z","iopub.status.idle":"2023-08-07T05:32:29.572877Z","shell.execute_reply.started":"2023-08-07T05:32:29.572621Z","shell.execute_reply":"2023-08-07T05:32:29.572645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the mask image, organs can be identified by the shading of gray. I wanted to use UNET to predict organ specific color using RGB, but the result was a single color image. This shows that it is necessary not only to convert the mask image to RGB, but also to prepare a color mask image other than gray.","metadata":{}},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.088366,"end_time":"2023-07-11T04:11:41.641552","exception":false,"start_time":"2023-07-11T04:11:41.553186","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]}]}