{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":36363,"databundleVersionId":4050810,"sourceType":"competition"}],"dockerImageVersionId":30260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 1. Import libraries","metadata":{}},{"cell_type":"code","source":"# Import libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport seaborn as sns\nimport os\nimport re\nimport gc\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom pprint import pprint\nimport nibabel as nib\nfrom glob import glob","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:45.267324Z","iopub.execute_input":"2025-06-05T09:55:45.267857Z","iopub.status.idle":"2025-06-05T09:55:46.381561Z","shell.execute_reply.started":"2025-06-05T09:55:45.267727Z","shell.execute_reply":"2025-06-05T09:55:46.379978Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2. Load the CSV files in the dataset:","metadata":{}},{"cell_type":"code","source":"# Load csv files\ntrain_df = pd.read_csv('../input/rsna-2022-cervical-spine-fracture-detection/train.csv')\ntrain_bbox = pd.read_csv('../input/rsna-2022-cervical-spine-fracture-detection/train_bounding_boxes.csv')","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.384693Z","iopub.execute_input":"2025-06-05T09:55:46.385094Z","iopub.status.idle":"2025-06-05T09:55:46.452253Z","shell.execute_reply.started":"2025-06-05T09:55:46.38506Z","shell.execute_reply":"2025-06-05T09:55:46.451075Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.453591Z","iopub.execute_input":"2025-06-05T09:55:46.453927Z","iopub.status.idle":"2025-06-05T09:55:46.4769Z","shell.execute_reply.started":"2025-06-05T09:55:46.453897Z","shell.execute_reply":"2025-06-05T09:55:46.475698Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_bbox.head()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.47862Z","iopub.execute_input":"2025-06-05T09:55:46.479146Z","iopub.status.idle":"2025-06-05T09:55:46.495318Z","shell.execute_reply.started":"2025-06-05T09:55:46.479101Z","shell.execute_reply":"2025-06-05T09:55:46.493935Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Get the list of verterbraes\nverterbraes = list(train_df.columns[-7:])\nverterbraes","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.496943Z","iopub.execute_input":"2025-06-05T09:55:46.497378Z","iopub.status.idle":"2025-06-05T09:55:46.514483Z","shell.execute_reply.started":"2025-06-05T09:55:46.497334Z","shell.execute_reply":"2025-06-05T09:55:46.513285Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Number of patients in the training dataset:', len(train_df.StudyInstanceUID.unique()))","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.516251Z","iopub.execute_input":"2025-06-05T09:55:46.517191Z","iopub.status.idle":"2025-06-05T09:55:46.535868Z","shell.execute_reply.started":"2025-06-05T09:55:46.517154Z","shell.execute_reply":"2025-06-05T09:55:46.534667Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.describe()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.541253Z","iopub.execute_input":"2025-06-05T09:55:46.542811Z","iopub.status.idle":"2025-06-05T09:55:46.591421Z","shell.execute_reply.started":"2025-06-05T09:55:46.542747Z","shell.execute_reply":"2025-06-05T09:55:46.590098Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"This dataset's statistics depicts some following information:\n\nThis dataset is nearly balanced (as nearly 50% of patients have fractures).\nFractures in C3 have the lowest percentage (about 3.6%), and fractures in C7 have the highest one (nearly 19.5%).","metadata":{}},{"cell_type":"markdown","source":"# 3. EDA for training dataset:","metadata":{}},{"cell_type":"markdown","source":"#a. Overview analysis of training dataset:","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nax1 = sns.countplot(x='patient_overall', data=train_df)\nfor container in ax1.containers:\n    ax1.bar_label(container)\nplt.title('Fractures distribution by patient')\nplt.ylim([0, 1200])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.592969Z","iopub.execute_input":"2025-06-05T09:55:46.593443Z","iopub.status.idle":"2025-06-05T09:55:46.810573Z","shell.execute_reply.started":"2025-06-05T09:55:46.593375Z","shell.execute_reply":"2025-06-05T09:55:46.80914Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"train_melt = pd.melt(train_df, id_vars=['StudyInstanceUID', 'patient_overall'],\n                     value_vars=verterbraes, var_name='verterbrae', value_name='fractured')\ntrain_melt.head(10)","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.81203Z","iopub.execute_input":"2025-06-05T09:55:46.812362Z","iopub.status.idle":"2025-06-05T09:55:46.833853Z","shell.execute_reply.started":"2025-06-05T09:55:46.812334Z","shell.execute_reply":"2025-06-05T09:55:46.832689Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nax2 = sns.countplot(x='verterbrae', hue='fractured', data=train_melt)\nfor container in ax2.containers:\n    ax2.bar_label(container)\nplt.title('Fractures distribution by verterbrae')\nplt.ylim([0, 2250])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:46.835286Z","iopub.execute_input":"2025-06-05T09:55:46.835672Z","iopub.status.idle":"2025-06-05T09:55:47.144299Z","shell.execute_reply.started":"2025-06-05T09:55:46.835635Z","shell.execute_reply":"2025-06-05T09:55:47.143096Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nax3 = sns.countplot(x=train_df[verterbraes].sum(axis=1))\nfor container in ax3.containers:\n    ax3.bar_label(container)\nplt.title('Number of fractures by patient')\nplt.ylim([0, 1200])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.14564Z","iopub.execute_input":"2025-06-05T09:55:47.145978Z","iopub.status.idle":"2025-06-05T09:55:47.362691Z","shell.execute_reply.started":"2025-06-05T09:55:47.145947Z","shell.execute_reply":"2025-06-05T09:55:47.361498Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Most of fractured patients have only fractures on 1 verterbrae.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(6, 5))\nsns.heatmap(train_df[verterbraes].corr(), cmap='coolwarm', vmin=-1, vmax=1)\nplt.title('Correlations')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.364005Z","iopub.execute_input":"2025-06-05T09:55:47.364305Z","iopub.status.idle":"2025-06-05T09:55:47.601997Z","shell.execute_reply.started":"2025-06-05T09:55:47.364278Z","shell.execute_reply":"2025-06-05T09:55:47.600526Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"This correlation indicates that patients, who has fracture in an any verterbrae, may have another fracture in an adjacent verterbrae.","metadata":{}},{"cell_type":"markdown","source":"# b. Visualization of several image samples:","metadata":{}},{"cell_type":"code","source":"# Load some sample images in the dataset\nsample_path = '../input/rsna-2022-cervical-spine-fracture-detection/train_images/1.2.826.0.1.3680043.10921/15.dcm'\nsample_dcm = pydicom.dcmread(sample_path)\nsample_dcm","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.603548Z","iopub.execute_input":"2025-06-05T09:55:47.603957Z","iopub.status.idle":"2025-06-05T09:55:47.642168Z","shell.execute_reply.started":"2025-06-05T09:55:47.60392Z","shell.execute_reply":"2025-06-05T09:55:47.641091Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Extract image from sample DCM metadata\nimage = apply_voi_lut(sample_dcm.pixel_array, sample_dcm)","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.643882Z","iopub.execute_input":"2025-06-05T09:55:47.644364Z","iopub.status.idle":"2025-06-05T09:55:47.659397Z","shell.execute_reply.started":"2025-06-05T09:55:47.644318Z","shell.execute_reply":"2025-06-05T09:55:47.658104Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualize the sample image\nplt.figure(figsize=(5, 5))\nplt.imshow(image, cmap='bone')\nplt.title('ID: 1.2.826.0.1.3680043.10921, Slice: 15', weight='bold', size=12, y=1.05)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.661032Z","iopub.execute_input":"2025-06-05T09:55:47.661383Z","iopub.status.idle":"2025-06-05T09:55:47.866315Z","shell.execute_reply.started":"2025-06-05T09:55:47.661352Z","shell.execute_reply":"2025-06-05T09:55:47.864435Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualize 15 images of a case\ndef visualize_15_images(instance_uid):\n    dcm_paths = [f'../input/rsna-2022-cervical-spine-fracture-detection/train_images/{instance_uid}/{i+100}.dcm' for i in range(15)]\n    dcm_files = [pydicom.dcmread(path) for path in dcm_paths]\n    images = [apply_voi_lut(file.pixel_array, file) for file in dcm_files]\n    fig, ax = plt.subplots(3, 5, figsize=(20, 12))\n    fig.suptitle(f'ID: {instance_uid}', weight='bold', size=20)\n    for i in range(15):\n        image = images[i]\n        row = i // 5\n        col = i % 5\n        ax[row, col].imshow(image, cmap='bone')\n        ax[row, col].set_title(f'Slice no: {i+100}', size=14)\n        ax[row, col].axis('off')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.867884Z","iopub.execute_input":"2025-06-05T09:55:47.868361Z","iopub.status.idle":"2025-06-05T09:55:47.879838Z","shell.execute_reply.started":"2025-06-05T09:55:47.868312Z","shell.execute_reply":"2025-06-05T09:55:47.878633Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_15_images('1.2.826.0.1.3680043.10921')","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:47.88109Z","iopub.execute_input":"2025-06-05T09:55:47.881755Z","iopub.status.idle":"2025-06-05T09:55:49.831498Z","shell.execute_reply.started":"2025-06-05T09:55:47.881682Z","shell.execute_reply":"2025-06-05T09:55:49.829828Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# c. Visualization of several segmented masks:","metadata":{}},{"cell_type":"code","source":"# Load some segmented masks\nsample_mask_path = '../input/rsna-2022-cervical-spine-fracture-detection/segmentations/1.2.826.0.1.3680043.10921.nii'\nsample_nii = nib.load(sample_mask_path)\nsample_nii","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:49.832969Z","iopub.execute_input":"2025-06-05T09:55:49.833324Z","iopub.status.idle":"2025-06-05T09:55:49.871105Z","shell.execute_reply.started":"2025-06-05T09:55:49.833289Z","shell.execute_reply":"2025-06-05T09:55:49.869987Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_seg = sample_nii.get_fdata()[:, ::-1, ::-1].transpose([2, 1, 0])\nsample_seg.shape","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:49.872446Z","iopub.execute_input":"2025-06-05T09:55:49.872809Z","iopub.status.idle":"2025-06-05T09:55:51.912909Z","shell.execute_reply.started":"2025-06-05T09:55:49.872778Z","shell.execute_reply":"2025-06-05T09:55:51.911724Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualize 15 masks of an instance (patient)\ndef visualize_15_masks(instance_uid):\n    mask_path = f'../input/rsna-2022-cervical-spine-fracture-detection/segmentations/{instance_uid}.nii'\n    nii_data = nib.load(mask_path)\n    seg_masks = nii_data.get_fdata()[:, ::-1, ::-1].transpose([2, 1, 0])\n    fig, ax = plt.subplots(3, 5, figsize=(20, 12))\n    fig.suptitle(f'ID: {instance_uid}', weight='bold', size=20)\n    for i in range(15):\n        row = i // 5\n        col = i % 5\n        mask = seg_masks[i+100]\n        ax[row, col].imshow(mask, cmap='inferno')\n        ax[row, col].set_title(f'Slice: {i+100}', size=14)\n        ax[row, col].axis('off')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:51.914154Z","iopub.execute_input":"2025-06-05T09:55:51.914532Z","iopub.status.idle":"2025-06-05T09:55:51.923082Z","shell.execute_reply.started":"2025-06-05T09:55:51.9145Z","shell.execute_reply":"2025-06-05T09:55:51.921819Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_15_masks('1.2.826.0.1.3680043.10921')","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:51.924615Z","iopub.execute_input":"2025-06-05T09:55:51.925009Z","iopub.status.idle":"2025-06-05T09:55:53.289476Z","shell.execute_reply.started":"2025-06-05T09:55:51.924975Z","shell.execute_reply":"2025-06-05T09:55:53.288211Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Number of cases that have segmentations:', len(glob('../input/rsna-2022-cervical-spine-fracture-detection/segmentations/*')))","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.294229Z","iopub.execute_input":"2025-06-05T09:55:53.294668Z","iopub.status.idle":"2025-06-05T09:55:53.34376Z","shell.execute_reply.started":"2025-06-05T09:55:53.294631Z","shell.execute_reply":"2025-06-05T09:55:53.34267Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Number of cases that have segmentations: 87","metadata":{}},{"cell_type":"markdown","source":"# 4. EDA for training set with bounding boxes:","metadata":{}},{"cell_type":"markdown","source":"a. Overview analysis of training set with bounding boxes:","metadata":{}},{"cell_type":"code","source":"# Get training with bounding boxes data\ntrain_bbox.head()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.345168Z","iopub.execute_input":"2025-06-05T09:55:53.345524Z","iopub.status.idle":"2025-06-05T09:55:53.359112Z","shell.execute_reply.started":"2025-06-05T09:55:53.345492Z","shell.execute_reply":"2025-06-05T09:55:53.357941Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Number of cases with bounding boxes:', len(train_bbox.StudyInstanceUID.unique()))","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.360382Z","iopub.execute_input":"2025-06-05T09:55:53.361465Z","iopub.status.idle":"2025-06-05T09:55:53.369465Z","shell.execute_reply.started":"2025-06-05T09:55:53.361421Z","shell.execute_reply":"2025-06-05T09:55:53.368148Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Only 235 cases (out of 2019 cases), equivalent to 11.64% of all cases, have bounding boxes on their CT images.","metadata":{}},{"cell_type":"code","source":"train_df_bbox = train_df[train_df.StudyInstanceUID.isin(train_bbox.StudyInstanceUID)]\ntrain_df_bbox.head()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.370857Z","iopub.execute_input":"2025-06-05T09:55:53.371211Z","iopub.status.idle":"2025-06-05T09:55:53.388624Z","shell.execute_reply.started":"2025-06-05T09:55:53.37118Z","shell.execute_reply":"2025-06-05T09:55:53.387287Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df_bbox.describe()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.389964Z","iopub.execute_input":"2025-06-05T09:55:53.390293Z","iopub.status.idle":"2025-06-05T09:55:53.431064Z","shell.execute_reply.started":"2025-06-05T09:55:53.390263Z","shell.execute_reply":"2025-06-05T09:55:53.429994Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"All of cases which have bounding boxes are fractured.\nC1-typed fractures have the lowest bounding box rate (only 19.57%), and C6-typed ones have the highest bounding box rate (just over 37%).","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(7, 5))\nax4 = sns.countplot(x='patient_overall', data=train_df_bbox)\nfor container in ax4.containers:\n    ax4.bar_label(container)\nplt.title('Fractures overall (patients with bounding boxes)')\nplt.ylim([0, 270])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.432164Z","iopub.execute_input":"2025-06-05T09:55:53.432483Z","iopub.status.idle":"2025-06-05T09:55:53.594932Z","shell.execute_reply.started":"2025-06-05T09:55:53.432455Z","shell.execute_reply":"2025-06-05T09:55:53.593748Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df_bbox_melt = pd.melt(train_df_bbox, id_vars=['StudyInstanceUID', 'patient_overall'],\n                             var_name='cervical_verterbrae', value_name='fractured')\ntrain_df_bbox_melt.head(10)","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.596734Z","iopub.execute_input":"2025-06-05T09:55:53.597153Z","iopub.status.idle":"2025-06-05T09:55:53.617703Z","shell.execute_reply.started":"2025-06-05T09:55:53.597117Z","shell.execute_reply":"2025-06-05T09:55:53.616284Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nax5 = sns.countplot(x='cervical_verterbrae', hue='fractured', data=train_df_bbox_melt)\nfor container in ax5.containers:\n    ax5.bar_label(container)\nplt.title('Fractures by verterbrae (patients with bounding boxes)')\nplt.ylim([0, 220])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.619501Z","iopub.execute_input":"2025-06-05T09:55:53.619942Z","iopub.status.idle":"2025-06-05T09:55:53.933254Z","shell.execute_reply.started":"2025-06-05T09:55:53.619905Z","shell.execute_reply":"2025-06-05T09:55:53.931897Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nsns.histplot(train_bbox.StudyInstanceUID.value_counts().values, kde=True, bins=50)\nplt.title('Number of slices with bounding boxes per patient')\nplt.xlabel('No. of bounding boxes')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:53.934702Z","iopub.execute_input":"2025-06-05T09:55:53.935093Z","iopub.status.idle":"2025-06-05T09:55:54.245887Z","shell.execute_reply.started":"2025-06-05T09:55:53.935058Z","shell.execute_reply":"2025-06-05T09:55:54.244204Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Most of the cases, which have bounding box measurement, have 10 - 35 image slices which contain bounding boxes.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\nsns.histplot(train_bbox[['StudyInstanceUID', 'slice_number']].value_counts().values, bins=10)\nplt.title('Number of bounding boxes per slice')\nplt.xlabel('No. of bounding boxes')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2025-06-05T09:55:54.247384Z","iopub.execute_input":"2025-06-05T09:55:54.247973Z","iopub.status.idle":"2025-06-05T09:55:54.429613Z","shell.execute_reply.started":"2025-06-05T09:55:54.247931Z","shell.execute_reply":"2025-06-05T09:55:54.428337Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"There is only 1 bounding box for every slice which have bounding box measurements.","metadata":{}}]}