{"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":"code","source":"!pip install monai[pydicom]==1.0.0\n# refer to: https://www.kaggle.com/competitions/rsna-2022-cervical-spine-fracture-detection/discussion/341412\n!pip install -qU \"python-gdcm\" pydicom pylibjpeg","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-22T10:52:26.227398Z","iopub.execute_input":"2022-09-22T10:52:26.227907Z","iopub.status.idle":"2022-09-22T10:52:53.848177Z","shell.execute_reply.started":"2022-09-22T10:52:26.22787Z","shell.execute_reply":"2022-09-22T10:52:53.846627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nfrom monai.transforms import LoadImaged, EnsureChannelFirstd, ResampleToMatchd, Orientationd, Compose\nimport monai\nimport numpy as np\nfrom tqdm import tqdm\nimport multiprocessing\nfrom ipywidgets import interactive, widgets, fixed\nfrom matplotlib import animation, rc; rc('animation', html='jshtml')\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:52:53.851096Z","iopub.execute_input":"2022-09-22T10:52:53.851531Z","iopub.status.idle":"2022-09-22T10:53:01.03622Z","shell.execute_reply.started":"2022-09-22T10:52:53.851486Z","shell.execute_reply":"2022-09-22T10:53:01.034949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_dir = \"../input/rsna-2022-cervical-spine-fracture-detection/train_images/\"\nmask_dir = \"../input/rsna-2022-cervical-spine-fracture-detection/segmentations/\"\nmask_list = os.listdir(mask_dir)\nimage_list = os.listdir(image_dir)","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:53:01.03778Z","iopub.execute_input":"2022-09-22T10:53:01.038481Z","iopub.status.idle":"2022-09-22T10:53:01.148111Z","shell.execute_reply.started":"2022-09-22T10:53:01.03842Z","shell.execute_reply":"2022-09-22T10:53:01.146855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = Compose(\n    [\n        LoadImaged(reader=(\"PydicomReader\", \"nibabelreader\"), keys=[\"image\", \"seg\"]),\n        EnsureChannelFirstd(keys=[\"image\", \"seg\"]),\n        # unify the orientations of image and mask\n        Orientationd(keys=[\"image\", \"seg\"], axcodes=\"RAS\"),\n    ]\n)","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:53:01.150691Z","iopub.execute_input":"2022-09-22T10:53:01.151079Z","iopub.status.idle":"2022-09-22T10:53:01.159968Z","shell.execute_reply.started":"2022-09-22T10:53:01.151042Z","shell.execute_reply":"2022-09-22T10:53:01.158733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# refer to:\n# https://www.kaggle.com/code/itsuki9180/a-segmentation-is-in-reverse-order\n\ndef create_animation(img, seg, seg_rev=False, fps=10):\n\n    images = img\n    segs = seg\n    \n    if seg_rev:\n        segs = segs[::-1]\n    ims_sgs = [np.concatenate([images[i], segs[i]], axis=1) for i in range(len(images))]\n    \n    # Stack images\n    animation_arr = np.stack(ims_sgs, axis=0)\n    \n    del images, ims_sgs\n    gc.collect()\n    \n    # Initialise plot\n    fig = plt.figure(figsize=(5,5), dpi=160)  # if size is too big then gif gets truncated\n    im = plt.imshow(animation_arr[0], cmap='bone')\n    plt.axis('off')\n    \n    # Load next frame\n    def animate_func(i):\n        im.set_array(animation_arr[i])\n        return [im]\n    plt.close()\n    \n    # Animation function\n    anim = animation.FuncAnimation(fig, animate_func, frames = animation_arr.shape[0], interval = 1000//fps)\n    \n    return anim","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:53:01.16142Z","iopub.execute_input":"2022-09-22T10:53:01.162749Z","iopub.status.idle":"2022-09-22T10:53:01.173116Z","shell.execute_reply.started":"2022-09-22T10:53:01.162696Z","shell.execute_reply":"2022-09-22T10:53:01.172015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_sample = \"1.2.826.0.1.3680043.25704\"\nmask_sample = f\"{img_sample}.nii\"\n\ndata = {\"image\": os.path.join(image_dir, img_sample), \"seg\": os.path.join(mask_dir, mask_sample)}\noutput = transform(data)\n\nimg = output[\"image\"].numpy().transpose([0, 3, 2, 1])[0]\nseg = output[\"seg\"].numpy().transpose([0, 3, 2, 1])[0]\n\nimg = (img-np.min(img))/(np.max(img)-np.min(img)+1e-6)\nimg = (img*255).astype(np.uint8)\n\nseg = np.where(seg>0, 255, 0).astype(np.uint8)\n\n\ncreate_animation(img, seg, fps=30)","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:53:01.175099Z","iopub.execute_input":"2022-09-22T10:53:01.175582Z","iopub.status.idle":"2022-09-22T10:53:45.484344Z","shell.execute_reply.started":"2022-09-22T10:53:01.175537Z","shell.execute_reply":"2022-09-22T10:53:45.482617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check \"wrong\" case\nimg_sample = \"1.2.826.0.1.3680043.1363\"\nmask_sample = f\"{img_sample}.nii\"\n\ndata = {\"image\": os.path.join(image_dir, img_sample), \"seg\": os.path.join(mask_dir, mask_sample)}\noutput = transform(data)\n\nimg = output[\"image\"].numpy().transpose([0, 3, 2, 1])[0]\nseg = output[\"seg\"].numpy().transpose([0, 3, 2, 1])[0]\n\nimg = (img-np.min(img))/(np.max(img)-np.min(img)+1e-6)\nimg = (img*255).astype(np.uint8)\n\nseg = np.where(seg>0, 255, 0).astype(np.uint8)\n\n\ncreate_animation(img, seg, fps=30)","metadata":{"execution":{"iopub.status.busy":"2022-09-22T10:53:45.486366Z","iopub.execute_input":"2022-09-22T10:53:45.487988Z","iopub.status.idle":"2022-09-22T10:54:27.135931Z","shell.execute_reply.started":"2022-09-22T10:53:45.48792Z","shell.execute_reply":"2022-09-22T10:54:27.132647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save all images with masks","metadata":{}},{"cell_type":"markdown","source":"I already run the following code locally, and upload all gif files into a [dataset](https://www.kaggle.com/datasets/yiheng/rsna-2022-mask-visualize)","metadata":{}},{"cell_type":"code","source":"# save_dir = \"vis_output\"\n\n# os.makedirs(save_dir, exist_ok=True)\n# fps = 30\n\n# def save_gif(i):\n#     mask_sample = mask_list[i]\n#     img_sample = mask_sample.split(\".nii\")[0]\n\n#     data = {\"image\": os.path.join(image_dir, img_sample), \"seg\": os.path.join(mask_dir, mask_sample)}\n#     output = transform(data)\n\n#     img = output[\"image\"].numpy().transpose([0, 3, 2, 1])[0]\n#     seg = output[\"seg\"].numpy().transpose([0, 3, 2, 1])[0]\n\n#     img = (img-np.min(img))/(np.max(img)-np.min(img)+1e-6)\n#     img = (img*255).astype(np.uint8)\n\n#     seg = np.where(seg>0, 255, 0).astype(np.uint8)\n#     anim = create_animation(img, seg, fps=fps)\n#     anim.save(os.path.join(save_dir, f\"{img_sample}.gif\"), fps=fps)\n#     print(f\"{img_sample}.gif is saved.\")\n    \n#     return mask_sample","metadata":{"execution":{"iopub.status.busy":"2022-09-21T02:35:31.226112Z","iopub.execute_input":"2022-09-21T02:35:31.226688Z","iopub.status.idle":"2022-09-21T02:35:31.240315Z","shell.execute_reply.started":"2022-09-21T02:35:31.226616Z","shell.execute_reply":"2022-09-21T02:35:31.238816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print(os.cpu_count())","metadata":{"execution":{"iopub.status.busy":"2022-09-21T02:26:00.362657Z","iopub.execute_input":"2022-09-21T02:26:00.363135Z","iopub.status.idle":"2022-09-21T02:26:00.368299Z","shell.execute_reply.started":"2022-09-21T02:26:00.363097Z","shell.execute_reply":"2022-09-21T02:26:00.367267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# idxs = list(range(len(mask_list)))\n\n# with multiprocessing.Pool(1) as pool:\n#     imap = pool.imap(save_gif, idxs)\n#     results = list(tqdm(imap, total=len(idxs)))","metadata":{"execution":{"iopub.status.busy":"2022-09-21T02:35:33.337761Z","iopub.execute_input":"2022-09-21T02:35:33.338509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}