{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30732,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport pydicom\nimport numpy as np\nimport os\nimport glob\nfrom tqdm import tqdm\nimport warnings","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-21T15:46:38.511121Z","iopub.execute_input":"2024-06-21T15:46:38.511646Z","iopub.status.idle":"2024-06-21T15:46:39.373305Z","shell.execute_reply.started":"2024-06-21T15:46:38.511603Z","shell.execute_reply":"2024-06-21T15:46:39.372217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading diagnosis information","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:39.375518Z","iopub.execute_input":"2024-06-21T15:46:39.376447Z","iopub.status.idle":"2024-06-21T15:46:39.409507Z","shell.execute_reply.started":"2024-06-21T15:46:39.376405Z","shell.execute_reply":"2024-06-21T15:46:39.408247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"Total cases:\", len(train)","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:39.410946Z","iopub.execute_input":"2024-06-21T15:46:39.411405Z","iopub.status.idle":"2024-06-21T15:46:39.420202Z","shell.execute_reply.started":"2024-06-21T15:46:39.411366Z","shell.execute_reply":"2024-06-21T15:46:39.418994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.columns","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:39.423422Z","iopub.execute_input":"2024-06-21T15:46:39.423835Z","iopub.status.idle":"2024-06-21T15:46:39.434466Z","shell.execute_reply.started":"2024-06-21T15:46:39.423798Z","shell.execute_reply":"2024-06-21T15:46:39.433254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"figure, axis = plt.subplots(1,3, figsize=(20,5)) \nfor idx, d in enumerate(['foraminal', 'subarticular', 'canal']):\n    diagnosis = list(filter(lambda x: x.find(d) > -1, train.columns))\n    dff = train[diagnosis]\n    with warnings.catch_warnings():\n        warnings.simplefilter(action='ignore', category=FutureWarning)\n        value_counts = dff.apply(pd.value_counts).fillna(0).T\n    value_counts.plot(kind='bar', stacked=True, ax=axis[idx])\n    axis[idx].set_title(f'{d} distribution')\n    axis[idx].legend(loc='lower right')","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:39.435982Z","iopub.execute_input":"2024-06-21T15:46:39.436502Z","iopub.status.idle":"2024-06-21T15:46:40.670170Z","shell.execute_reply.started":"2024-06-21T15:46:39.436387Z","shell.execute_reply":"2024-06-21T15:46:40.668978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Grab metadata for each scan","metadata":{}},{"cell_type":"code","source":"part_1 = os.listdir('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images')\npart_1 = list(filter(lambda x: x.find('.DS') == -1, part_1))","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:40.671710Z","iopub.execute_input":"2024-06-21T15:46:40.672114Z","iopub.status.idle":"2024-06-21T15:46:40.773015Z","shell.execute_reply.started":"2024-06-21T15:46:40.672080Z","shell.execute_reply":"2024-06-21T15:46:40.771813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_meta_f = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:40.774413Z","iopub.execute_input":"2024-06-21T15:46:40.774750Z","iopub.status.idle":"2024-06-21T15:46:40.792818Z","shell.execute_reply.started":"2024-06-21T15:46:40.774722Z","shell.execute_reply":"2024-06-21T15:46:40.791614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"p1 = [(x, f\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images/{x}\") for x in part_1]\nmeta_obj = {p[0]: {'folder_path': p[1],\n                   'SeriesInstanceUIDs': []\n                  }\n           for p in p1}","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:40.793985Z","iopub.execute_input":"2024-06-21T15:46:40.794304Z","iopub.status.idle":"2024-06-21T15:46:40.803398Z","shell.execute_reply.started":"2024-06-21T15:46:40.794276Z","shell.execute_reply":"2024-06-21T15:46:40.802160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for m in meta_obj:\n    meta_obj[m]['SeriesInstanceUIDs'] = list(\n        filter(lambda x: x.find('.DS') == -1,\n               os.listdir(meta_obj[m]['folder_path'])\n              )\n    )","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:40.804749Z","iopub.execute_input":"2024-06-21T15:46:40.805216Z","iopub.status.idle":"2024-06-21T15:46:45.618037Z","shell.execute_reply.started":"2024-06-21T15:46:40.805183Z","shell.execute_reply":"2024-06-21T15:46:45.617030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for k in tqdm(meta_obj):\n    for s in meta_obj[k]['SeriesInstanceUIDs']:\n        if 'SeriesDescriptions' not in meta_obj[k]:\n            meta_obj[k]['SeriesDescriptions'] = []\n        try:\n            meta_obj[k]['SeriesDescriptions'].append(\n                df_meta_f[(df_meta_f['study_id'] == int(k)) & \n                (df_meta_f['series_id'] == int(s))]['series_description'].iloc[0])\n        except:\n            print('Failed on', s, k)","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:45.621240Z","iopub.execute_input":"2024-06-21T15:46:45.621579Z","iopub.status.idle":"2024-06-21T15:46:49.218776Z","shell.execute_reply.started":"2024-06-21T15:46:45.621549Z","shell.execute_reply":"2024-06-21T15:46:49.217753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_obj[list(meta_obj.keys())[1]]","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.220349Z","iopub.execute_input":"2024-06-21T15:46:49.220788Z","iopub.status.idle":"2024-06-21T15:46:49.228773Z","shell.execute_reply.started":"2024-06-21T15:46:49.220748Z","shell.execute_reply":"2024-06-21T15:46:49.227538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Pull up images for one patient","metadata":{}},{"cell_type":"code","source":"patient = train.iloc[1]","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.230293Z","iopub.execute_input":"2024-06-21T15:46:49.230704Z","iopub.status.idle":"2024-06-21T15:46:49.258415Z","shell.execute_reply.started":"2024-06-21T15:46:49.230668Z","shell.execute_reply":"2024-06-21T15:46:49.256931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ptobj = meta_obj[str(patient['study_id'])]\nptobj","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.260162Z","iopub.execute_input":"2024-06-21T15:46:49.260498Z","iopub.status.idle":"2024-06-21T15:46:49.270910Z","shell.execute_reply.started":"2024-06-21T15:46:49.260470Z","shell.execute_reply":"2024-06-21T15:46:49.269750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im_list_dcm = {}\nfor idx, i in enumerate(ptobj['SeriesInstanceUIDs']):\n    im_list_dcm[i] = {'images': [],\n                      'description': ptobj['SeriesDescriptions'][idx]}\n    images = glob.glob(f\"{ptobj['folder_path']}/{ptobj['SeriesInstanceUIDs'][idx]}/*.dcm\")\n    for j in sorted(images, key=lambda x: int(x.split('/')[-1].replace('.dcm', ''))):\n        im_list_dcm[i]['images'].append({\n            'SOPInstanceUID': j.split('/')[-1].replace('.dcm', ''),\n            'dicom': pydicom.dcmread(j)\n        })","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.272326Z","iopub.execute_input":"2024-06-21T15:46:49.272734Z","iopub.status.idle":"2024-06-21T15:46:49.863203Z","shell.execute_reply.started":"2024-06-21T15:46:49.272696Z","shell.execute_reply":"2024-06-21T15:46:49.862278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to display images\ndef display_images(images, title, max_images_per_row=4):\n    num_images = len(images)\n    num_rows = (num_images + max_images_per_row - 1) // max_images_per_row\n    \n    fig, axes = plt.subplots(num_rows, max_images_per_row, figsize=(5, 1.5 * num_rows))\n    \n    if num_rows > 1:\n        axes = axes.flatten()\n    else:\n        axes = [axes]\n        \n    for idx, image in enumerate(images):\n        ax = axes[idx]\n        ax.imshow(image, cmap='gray')\n        ax.axis('off')\n        \n    for idx in range(num_images, len(axes)):\n        axes[idx].axis('off')\n    \n    fig.suptitle(title, fontsize=16)\n    \n    plt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.864442Z","iopub.execute_input":"2024-06-21T15:46:49.864745Z","iopub.status.idle":"2024-06-21T15:46:49.872609Z","shell.execute_reply.started":"2024-06-21T15:46:49.864720Z","shell.execute_reply":"2024-06-21T15:46:49.871370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in im_list_dcm:\n    display_images([x['dicom'].pixel_array for x in im_list_dcm[i]['images']],\n                  im_list_dcm[i]['description'])","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:49.873781Z","iopub.execute_input":"2024-06-21T15:46:49.874150Z","iopub.status.idle":"2024-06-21T15:46:55.671649Z","shell.execute_reply.started":"2024-06-21T15:46:49.874120Z","shell.execute_reply":"2024-06-21T15:46:55.670482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Coordinates of pathologies","metadata":{}},{"cell_type":"code","source":"df_coor = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_label_coordinates.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:55.672912Z","iopub.execute_input":"2024-06-21T15:46:55.673281Z","iopub.status.idle":"2024-06-21T15:46:55.787536Z","shell.execute_reply.started":"2024-06-21T15:46:55.673250Z","shell.execute_reply":"2024-06-21T15:46:55.786209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_coor.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:55.789132Z","iopub.execute_input":"2024-06-21T15:46:55.789491Z","iopub.status.idle":"2024-06-21T15:46:55.806059Z","shell.execute_reply.started":"2024-06-21T15:46:55.789461Z","shell.execute_reply":"2024-06-21T15:46:55.805027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_coor_on_img(c, i, title):\n    center_coordinates = (int(c['x']), int(c['y']))\n    radius = 10\n    color = (255, 0, 0)  \n    thickness = 2\n    IMG = i['dicom'].pixel_array\n    IMG_normalized = cv2.normalize(IMG, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)\n    \n    IMG_with_circle = cv2.circle(IMG_normalized.copy(), center_coordinates, radius, color, thickness)\n    \n    IMG_with_circle = cv2.cvtColor(IMG_with_circle, cv2.COLOR_BGR2RGB)\n    \n    plt.imshow(IMG_with_circle)\n    plt.axis('off')\n    plt.title(title)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:55.807245Z","iopub.execute_input":"2024-06-21T15:46:55.807552Z","iopub.status.idle":"2024-06-21T15:46:55.815732Z","shell.execute_reply.started":"2024-06-21T15:46:55.807526Z","shell.execute_reply":"2024-06-21T15:46:55.814621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coor_entries = df_coor[df_coor['study_id'] == int(patient['study_id'])]","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:55.817199Z","iopub.execute_input":"2024-06-21T15:46:55.817546Z","iopub.status.idle":"2024-06-21T15:46:55.830162Z","shell.execute_reply.started":"2024-06-21T15:46:55.817517Z","shell.execute_reply":"2024-06-21T15:46:55.829185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Only showing severe cases for this patient\")\nfor idc, c in coor_entries.iterrows():\n    for i in im_list_dcm[str(c['series_id'])]['images']:\n        if int(i['SOPInstanceUID']) == int(c['instance_number']):\n            try:\n                patient_severity = patient[\n                    f\"{c['condition'].lower().replace(' ', '_')}_{c['level'].lower().replace('/', '_')}\"\n                ]\n            except Exception as e:\n                patient_severity = \"unknown severity\"\n            title = f\"{i['SOPInstanceUID']} \\n{c['level']}, {c['condition']}: {patient_severity} \\n{c['x']}, {c['y']}\"\n            if patient_severity == 'Severe':\n                display_coor_on_img(c, i, title)","metadata":{"execution":{"iopub.status.busy":"2024-06-21T15:46:55.831535Z","iopub.execute_input":"2024-06-21T15:46:55.831882Z","iopub.status.idle":"2024-06-21T15:46:56.294049Z","shell.execute_reply.started":"2024-06-21T15:46:55.831852Z","shell.execute_reply":"2024-06-21T15:46:56.292908Z"},"trusted":true},"execution_count":null,"outputs":[]}]}