{"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":"#### I found an order of segmentation is reversed.","metadata":{}},{"cell_type":"code","source":"!conda install '../input/rsna2022-pydicom-conda-helper/libjpeg-turbo-2.1.0-h7f98852_0.tar.bz2' -c conda-forge -y\n!conda install '../input/rsna2022-pydicom-conda-helper/libgcc-ng-9.3.0-h2828fa1_19.tar.bz2' -c conda-forge -y\n!conda install '../input/rsna2022-pydicom-conda-helper/gdcm-2.8.9-py37h500ead1_1.tar.bz2' -c conda-forge -y\n!conda install '../input/rsna2022-pydicom-conda-helper/conda-4.10.1-py37h89c1867_0.tar.bz2' -c conda-forge -y\n!conda install '../input/rsna2022-pydicom-conda-helper/certifi-2020.12.5-py37h89c1867_1.tar.bz2' -c conda-forge -y\n!conda install '../input/rsna2022-pydicm-conda-helper/openssl-1.1.1k-h7f98852_0.tar.bz2' -c conda-forge -y","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:17:19.565857Z","iopub.execute_input":"2022-08-29T12:17:19.566406Z","iopub.status.idle":"2022-08-29T12:18:26.066369Z","shell.execute_reply.started":"2022-08-29T12:17:19.56629Z","shell.execute_reply":"2022-08-29T12:18:26.064775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LOAD LIBRARIES\nimport numpy as np, pandas as pd, os\nimport matplotlib.pyplot as plt, cv2\nimport glob\nimport nibabel as nib\nimport pydicom as dicom\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:18:26.070067Z","iopub.execute_input":"2022-08-29T12:18:26.070667Z","iopub.status.idle":"2022-08-29T12:18:26.72435Z","shell.execute_reply.started":"2022-08-29T12:18:26.070608Z","shell.execute_reply":"2022-08-29T12:18:26.723268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\nfrom matplotlib import animation, rc; rc('animation', html='jshtml')\nimport re\nimport gc\nfrom glob import glob\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:18:26.725925Z","iopub.execute_input":"2022-08-29T12:18:26.726588Z","iopub.status.idle":"2022-08-29T12:18:26.7387Z","shell.execute_reply.started":"2022-08-29T12:18:26.726548Z","shell.execute_reply":"2022-08-29T12:18:26.737712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 512 ","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:18:26.743137Z","iopub.execute_input":"2022-08-29T12:18:26.744433Z","iopub.status.idle":"2022-08-29T12:18:26.77909Z","shell.execute_reply.started":"2022-08-29T12:18:26.744377Z","shell.execute_reply":"2022-08-29T12:18:26.777783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_nii(path, size=IMG_SIZE):\n    ex = nib.load(path)\n    ex = ex.get_fdata()  # convert to numpy array\n    ex = ex[:, ::-1, ::-1].transpose(2, 1, 0)  # align orientation with train image\n    ex = np.where(ex>0, 255, 0).astype(np.uint8)\n    return ex","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:22.358329Z","iopub.execute_input":"2022-08-29T12:25:22.359202Z","iopub.status.idle":"2022-08-29T12:25:22.367641Z","shell.execute_reply.started":"2022-08-29T12:25:22.35916Z","shell.execute_reply":"2022-08-29T12:25:22.366237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path, size = IMG_SIZE):\n    try:\n        img = dicom.dcmread(path)\n        img.PhotometricInterpretation = 'YBR_FULL'\n        data = img.pixel_array\n        \n        data = cv2.resize(data, (IMG_SIZE, IMG_SIZE))\n        return data\n    except:        \n        print(f'{path} is not exist')\n        return np.zeros((IMG_SIZE, IMG_SIZE))","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:22.370404Z","iopub.execute_input":"2022-08-29T12:25:22.371644Z","iopub.status.idle":"2022-08-29T12:25:22.383019Z","shell.execute_reply.started":"2022-08-29T12:25:22.371588Z","shell.execute_reply":"2022-08-29T12:25:22.381687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_animation(patient_id, drc='train_images', save_dir=\"./\", seg_rev=False, save=True, fps=10):\n    # Get paths\n    base_path = \"../input/rsna-2022-cervical-spine-fracture-detection\"\n    dcm_paths = glob(f\"{base_path}/train_images/{patient_id}/*\")\n    nii_path = f\"{base_path}/segmentations/{patient_id}.nii\"\n    def atoi(text):\n        return int(text) if text.isdigit() else text\n    def natural_keys(text):\n        return [atoi(c) for c in re.split(r'(\\d+)', text)]\n    dcm_paths.sort(key=natural_keys)\n    \n    # Get images\n    images = np.stack([load_dicom(path) for path in dcm_paths],axis=0)\n    images = (images-np.min(images))/(np.max(images)-np.min(images)+1e-6)\n    images = (images*255).astype(np.uint8)\n    segs = load_nii(nii_path)\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\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    plt.title(f\"{patient_id}\", fontweight=\"bold\")\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    # Save\n    if save:\n        os.makedirs(save_dir, exist_ok=True)\n        if seg_rev:\n            patient_id += '_rev'\n        anim.save(os.path.join(save_dir, f\"patient_{patient_id}.gif\"), fps=30, writer='imagemagick')\n        \n    return anim","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:23.003742Z","iopub.execute_input":"2022-08-29T12:25:23.004242Z","iopub.status.idle":"2022-08-29T12:25:23.021959Z","shell.execute_reply.started":"2022-08-29T12:25:23.004174Z","shell.execute_reply":"2022-08-29T12:25:23.0206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### correct segmentation","metadata":{}},{"cell_type":"code","source":"ordered_example = '1.2.826.0.1.3680043.25704'\ncreate_animation(ordered_example, fps=30)","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:23.023886Z","iopub.execute_input":"2022-08-29T12:25:23.024338Z","iopub.status.idle":"2022-08-29T12:27:54.149771Z","shell.execute_reply.started":"2022-08-29T12:25:23.024278Z","shell.execute_reply":"2022-08-29T12:27:54.148488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### wrong segmentation","metadata":{}},{"cell_type":"code","source":"reversed_example = '1.2.826.0.1.3680043.1363'\ncreate_animation(reversed_example, fps=30)","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:27:54.152524Z","iopub.execute_input":"2022-08-29T12:27:54.153247Z","iopub.status.idle":"2022-08-29T12:29:57.380358Z","shell.execute_reply.started":"2022-08-29T12:27:54.153202Z","shell.execute_reply":"2022-08-29T12:29:57.376265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### fixed(reversed) segmentation","metadata":{}},{"cell_type":"code","source":"create_animation(reversed_example, seg_rev=True, fps=30)","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:29:57.384818Z","iopub.execute_input":"2022-08-29T12:29:57.385794Z","iopub.status.idle":"2022-08-29T12:31:57.885901Z","shell.execute_reply.started":"2022-08-29T12:29:57.385745Z","shell.execute_reply":"2022-08-29T12:31:57.879412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:01.667215Z","iopub.execute_input":"2022-08-29T12:25:01.667753Z","iopub.status.idle":"2022-08-29T12:25:01.677428Z","shell.execute_reply.started":"2022-08-29T12:25:01.66771Z","shell.execute_reply":"2022-08-29T12:25:01.676176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-08-29T12:25:01.679538Z","iopub.execute_input":"2022-08-29T12:25:01.679979Z","iopub.status.idle":"2022-08-29T12:25:01.689831Z","shell.execute_reply.started":"2022-08-29T12:25:01.679941Z","shell.execute_reply":"2022-08-29T12:25:01.688803Z"},"trusted":true},"execution_count":null,"outputs":[]}]}