{"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":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport plotly.express as px\nfrom plotly.offline import init_notebook_mode, iplot, plot\nfrom tqdm.notebook import tqdm\nfrom pathlib import Path\nfrom collections import Counter\nimport pydicom\nimport nibabel as nib\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\ntqdm.pandas()\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:41:04.639928Z","iopub.execute_input":"2022-11-26T18:41:04.640597Z","iopub.status.idle":"2022-11-26T18:41:04.648582Z","shell.execute_reply.started":"2022-11-26T18:41:04.640553Z","shell.execute_reply":"2022-11-26T18:41:04.647839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"paths = {\n    'train_df': Path('../input/rsna-2022-cervical-spine-fracture-detection/train.csv'),\n    'train_bbox': Path('../input/rsna-2022-cervical-spine-fracture-detection/train_bounding_boxes.csv'),\n    'train_images': Path('../input/rsna-2022-cervical-spine-fracture-detection/train_images'),\n    'train_nifti_segments': Path('../input/rsna-2022-cervical-spine-fracture-detection/segmentations'),\n    'test_df': Path('../input/rsna-2022-cervical-spine-fracture-detection/test.csv'),\n    'test_images': Path('../input/rsna-2022-cervical-spine-fracture-detection/test_images')\n}","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:41:07.52036Z","iopub.execute_input":"2022-11-26T18:41:07.520747Z","iopub.status.idle":"2022-11-26T18:41:07.527089Z","shell.execute_reply.started":"2022-11-26T18:41:07.520717Z","shell.execute_reply":"2022-11-26T18:41:07.52582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def num_slices(path):\n    slices = list(path.glob('*'))\n    return len(slices)","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:41:09.161912Z","iopub.execute_input":"2022-11-26T18:41:09.16264Z","iopub.status.idle":"2022-11-26T18:41:09.167854Z","shell.execute_reply.started":"2022-11-26T18:41:09.162605Z","shell.execute_reply":"2022-11-26T18:41:09.166249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dcm_images(path):\n    paths = list(path.glob('*'))\n    paths.sort(key=lambda x:int(x.stem)) # sort based on slice index which is the filename: index.dcm\n    data = [pydicom.dcmread(f) for f in paths]\n    images = [apply_voi_lut(dcm.pixel_array, dcm) for dcm in data]\n    return images\n\ndef get_nii_segments(path):\n    f = nib.load(path)\n    segmentations = f.get_fdata()[:, ::-1, ::-1].transpose(2, 1, 0)\n    return segmentations","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:41:11.849753Z","iopub.execute_input":"2022-11-26T18:41:11.850173Z","iopub.status.idle":"2022-11-26T18:41:11.857645Z","shell.execute_reply.started":"2022-11-26T18:41:11.850139Z","shell.execute_reply":"2022-11-26T18:41:11.856513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(paths['train_df'])\ntest_df = pd.read_csv(paths['test_df'])\ntrain_df.drop(index=1135, inplace=True)\ntrain_df.reset_index(drop=True, inplace=True)\ntrain_df['total_fractures'] = train_df.loc[:,[f\"C{i}\" for i in range(1,8)]].sum(axis=1)\ntrain_df['segment_path'] = train_df['StudyInstanceUID'].map(lambda x: paths['train_images']/x)\ntrain_df['num_slices'] = train_df['segment_path'].progress_map(num_slices)\ntrain_df['num_slices'] = train_df['num_slices'].astype('int')\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:41:13.943866Z","iopub.execute_input":"2022-11-26T18:41:13.944262Z","iopub.status.idle":"2022-11-26T18:45:17.713697Z","shell.execute_reply.started":"2022-11-26T18:41:13.944232Z","shell.execute_reply":"2022-11-26T18:45:17.712745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def add_nii_segment_path(uid):\n    base_path = paths['train_nifti_segments']\n    # path if exists else None\n    path = base_path/(uid+'.nii')\n    if path.exists():\n        return path\n    return None\n\ntrain_df['nii_segments_path'] = train_df['StudyInstanceUID'].map(add_nii_segment_path)\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:47:14.450497Z","iopub.execute_input":"2022-11-26T18:47:14.450938Z","iopub.status.idle":"2022-11-26T18:47:15.680611Z","shell.execute_reply.started":"2022-11-26T18:47:14.450903Z","shell.execute_reply":"2022-11-26T18:47:15.679478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_reverse_required(path):\n    paths = list(path.glob('*'))\n    paths.sort(key=lambda x:int(x.stem))\n    z_first = pydicom.dcmread(paths[0]).get(\"ImagePositionPatient\")[-1]\n    z_last = pydicom.dcmread(paths[-1]).get(\"ImagePositionPatient\")[-1]\n    if z_last < z_first:\n        return False\n    return True\nchecks = train_df['segment_path'].progress_map(check_reverse_required)\ntrain_df['reverse_required'] = checks","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:47:17.330322Z","iopub.execute_input":"2022-11-26T18:47:17.330709Z","iopub.status.idle":"2022-11-26T18:48:09.935723Z","shell.execute_reply.started":"2022-11-26T18:47:17.330678Z","shell.execute_reply":"2022-11-26T18:48:09.934657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_index = train_df.iloc[99,:]\ndcm_images = get_dcm_images(sample_index['segment_path'])\nif sample_index['reverse_required'] == True:\n    dcm_images.sort(reverse=True)\nsegments = get_nii_segments(sample_index['nii_segments_path'])","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:48:32.433138Z","iopub.execute_input":"2022-11-26T18:48:32.433539Z","iopub.status.idle":"2022-11-26T18:48:38.51716Z","shell.execute_reply.started":"2022-11-26T18:48:32.433504Z","shell.execute_reply":"2022-11-26T18:48:38.515859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(sample_index['StudyInstanceUID'])\nDATA_DIR = \"../input/rsna-2022-cervical-spine-fracture-detection\"\nTRAIN_DIR = os.path.join(DATA_DIR, \"train_images\")\nSEGM_DIR = os.path.join(DATA_DIR, \"segmentations\")\ndef rescale_img_to_hu(dcm_ds):\n    \"\"\"Rescales the image to Hounsfield unit.\n    \"\"\"\n    return dcm_ds.pixel_array * dcm_ds.RescaleSlope + dcm_ds.RescaleIntercept","metadata":{"execution":{"iopub.status.busy":"2022-11-26T18:48:40.498463Z","iopub.execute_input":"2022-11-26T18:48:40.498909Z","iopub.status.idle":"2022-11-26T18:48:40.506783Z","shell.execute_reply.started":"2022-11-26T18:48:40.498875Z","shell.execute_reply":"2022-11-26T18:48:40.505595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.patches as patches\nimport cv2\npatient_id = sample_index['StudyInstanceUID']\nstep = 8\nnum_slices = train_df.loc[train_df[\"StudyInstanceUID\"] == patient_id, \"num_slices\"].values[0]\nprint(f\"Number of slices for patient: {num_slices}\")    \nprint(f\"Fracture information for patient: \")\nprint(f\"{train_df[train_df['StudyInstanceUID'] == patient_id].iloc[:, 1:-1]}\")\npatient_dir = os.path.join(TRAIN_DIR, patient_id)\n    \nsegm_path = os.path.join(SEGM_DIR, f\"{patient_id}.nii\")\n# source: https://www.kaggle.com/code/kretes/segmentations-fracture-zoom-in\nsegm_mask = nib.load(segm_path).get_fdata()\n        \n# flip in z axis\nsegm_mask = np.flip(segm_mask, axis=-1)\n# rotate 90 degrees in xy\nsegm_mask = np.rot90(segm_mask, axes=(0, 1))\n        \n#fig, axs = plt.subplots(1,1)\n#ax1 = ax1.flatten()\ncolors = ['red', 'orangered', 'yellow', 'green', 'cyan', 'blue', 'magenta']\n\ncount = 0\nidx = 0\ncolorgraph = []\nwhile count < 33:\n    if segm_mask[:, :, idx].max() > 0:\n        # dicom filenames start from 1\n        ds = pydicom.dcmread(os.path.join(patient_dir, f\"{idx+1}.dcm\"))\n        plt.imshow(rescale_img_to_hu(ds), cmap=\"bone\")\n        plt.axis(\"off\")\n        \n        mask = segm_mask[:, :, idx]\n        vert = np.unique(mask)\n        vert = vert[(vert >= 1) & (vert <= 7)]\n        for c in vert:\n            v = np.where(mask == c)\n            plt.scatter(v[1], v[0], c=colors[int(c)-1], s=0.05)\n        segm_im = plt.imshow(segm_mask[:, :, idx], alpha=0.4)\n        #segm_max = segm_mask[:, :, idx].max()\n        #segm_labels = np.unique(segm_mask[:, :, idx][segm_mask[:, :, idx].nonzero()])\n        #print(segm_labels)\n        #segm_colors = [segm_im.cmap(label/segm_max) for label in segm_labels]\n        #ptch = [patches.Patch(color=segm_colors[i], label=f\"C{int(segm_labels[i])}\") for i in range(len(segm_labels))]\n        #plt.legend(handles=ptch)\n        figure = plt.gcf()\n        figure.set_dpi(100)\n        figure.canvas.draw()\n        img = np.array(figure.canvas.buffer_rgba())\n        #plt.savefig('./test%s.png'%str(count), dpi = 100)\n        cv2.imwrite('./test%s.png'%str(count),img)\n        plt.show()\n        #plt.clf()\n        #colorgraph.append(fig)\n        count += 1\n    idx += step","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:20:06.593966Z","iopub.execute_input":"2022-11-26T19:20:06.596235Z","iopub.status.idle":"2022-11-26T19:20:17.056102Z","shell.execute_reply.started":"2022-11-26T19:20:06.596169Z","shell.execute_reply":"2022-11-26T19:20:17.055244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(segm_mask[:, :, 27], alpha=0.3)\nplt.show()\nprint(np.unique(segm_mask[:, :, 27]))","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:02:38.329882Z","iopub.execute_input":"2022-11-26T19:02:38.330247Z","iopub.status.idle":"2022-11-26T19:02:38.560336Z","shell.execute_reply.started":"2022-11-26T19:02:38.330218Z","shell.execute_reply":"2022-11-26T19:02:38.559097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = cv2.imread('./test10.png')\nprint(np.shape(fig))\nplt.imshow(fig)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:20:32.628492Z","iopub.execute_input":"2022-11-26T19:20:32.628953Z","iopub.status.idle":"2022-11-26T19:20:32.812939Z","shell.execute_reply.started":"2022-11-26T19:20:32.628909Z","shell.execute_reply":"2022-11-26T19:20:32.811845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2 \ncolorgraph = []\nfor i in range(1,33):\n    img = cv2.imread('./test%s.png'%str(i))\n    cropped = img[50:350, 157:457]\n    res = cv2.resize(cropped, (512, 512))\n    colorgraph.append(res)\nprint(np.shape(colorgraph[1]))","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:16:48.259082Z","iopub.execute_input":"2022-11-26T19:16:48.259488Z","iopub.status.idle":"2022-11-26T19:16:48.475572Z","shell.execute_reply.started":"2022-11-26T19:16:48.259452Z","shell.execute_reply":"2022-11-26T19:16:48.474788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import animation, rc\nrc('animation', html='jshtml')\n\nfig, [ax1,ax2,ax3] = plt.subplots(1,3)\nax1.axis('off')\nax2.axis('off')\nax3.axis('off')\nimages = []\ncount = 0\nfor i in range(0,len(dcm_images),9):\n    im1 = ax1.imshow(dcm_images[i], animated=True, cmap='bone')\n    im2 = ax2.imshow(segments[i,:,:], animated=True, cmap='bone')\n    im3 = ax3.imshow(colorgraph[count], animated=True, cmap='bone')\n    if i==0:\n        ax1.imshow(dcm_images[i], cmap='bone')\n        ax2.imshow(segments[i,:,:], cmap='bone')\n        ax3.imshow(colorgraph[count], cmap='bone')\n    images.append([im1,im2,im3])\n    count+=1\n        \n\nani = animation.ArtistAnimation(fig, images, interval=150, blit=True,\n                                repeat_delay=1000)\nplt.close()\nani","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:16:50.458809Z","iopub.execute_input":"2022-11-26T19:16:50.459201Z","iopub.status.idle":"2022-11-26T19:16:57.893059Z","shell.execute_reply.started":"2022-11-26T19:16:50.459167Z","shell.execute_reply":"2022-11-26T19:16:57.891891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ani.save('output.gif',dpi = 500)","metadata":{"execution":{"iopub.status.busy":"2022-11-26T19:17:15.179971Z","iopub.execute_input":"2022-11-26T19:17:15.181112Z","iopub.status.idle":"2022-11-26T19:17:34.194086Z","shell.execute_reply.started":"2022-11-26T19:17:15.181069Z","shell.execute_reply":"2022-11-26T19:17:34.192828Z"},"trusted":true},"execution_count":null,"outputs":[]}]}