{"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"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Taken from: https://www.kaggle.com/code/itsuki9180/rsna2024-lsdc-making-dataset/notebook","metadata":{}},{"cell_type":"markdown","source":"# **Imports**","metadata":{}},{"cell_type":"code","source":"import pydicom\nimport glob, os\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport cv2\nfrom tqdm import tqdm\nimport re","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-26T21:37:24.095970Z","iopub.execute_input":"2024-07-26T21:37:24.100167Z","iopub.status.idle":"2024-07-26T21:37:24.124705Z","shell.execute_reply.started":"2024-07-26T21:37:24.100009Z","shell.execute_reply":"2024-07-26T21:37:24.118876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Observe first few entries of dataset**","metadata":{}},{"cell_type":"code","source":"input_directory = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification'\n\ndf_coordinates  = pd.read_csv(f'{input_directory}/train_label_coordinates.csv')\ndf_descriptions = pd.read_csv(f'{input_directory}/train_series_descriptions.csv')","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.127766Z","iopub.execute_input":"2024-07-26T21:37:24.128654Z","iopub.status.idle":"2024-07-26T21:37:24.296243Z","shell.execute_reply.started":"2024-07-26T21:37:24.128610Z","shell.execute_reply":"2024-07-26T21:37:24.295199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_descriptions.head()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.298093Z","iopub.execute_input":"2024-07-26T21:37:24.298457Z","iopub.status.idle":"2024-07-26T21:37:24.326374Z","shell.execute_reply.started":"2024-07-26T21:37:24.298429Z","shell.execute_reply":"2024-07-26T21:37:24.325280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"For each study_id, there are 3-6 series_ids.","metadata":{}},{"cell_type":"code","source":"df_coordinates.head()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.328762Z","iopub.execute_input":"2024-07-26T21:37:24.329141Z","iopub.status.idle":"2024-07-26T21:37:24.344896Z","shell.execute_reply.started":"2024-07-26T21:37:24.329111Z","shell.execute_reply":"2024-07-26T21:37:24.343645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_descriptions['series_description'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.346595Z","iopub.execute_input":"2024-07-26T21:37:24.346979Z","iopub.status.idle":"2024-07-26T21:37:24.363763Z","shell.execute_reply.started":"2024-07-26T21:37:24.346948Z","shell.execute_reply":"2024-07-26T21:37:24.362290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_descriptions[df_descriptions['study_id']==4096820034]","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.365463Z","iopub.execute_input":"2024-07-26T21:37:24.365983Z","iopub.status.idle":"2024-07-26T21:37:24.388255Z","shell.execute_reply.started":"2024-07-26T21:37:24.365943Z","shell.execute_reply":"2024-07-26T21:37:24.386921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Study_ids with 4+ series_ids have 2+ Axial T2s.","metadata":{}},{"cell_type":"code","source":"df_coordinates[df_coordinates['study_id']==4096820034]","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.389750Z","iopub.execute_input":"2024-07-26T21:37:24.390158Z","iopub.status.idle":"2024-07-26T21:37:24.410986Z","shell.execute_reply.started":"2024-07-26T21:37:24.390130Z","shell.execute_reply":"2024-07-26T21:37:24.409930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Export png from dcm**\ndcm images vary in pixel values and image size. Each dcm image's pixel values will be adjusted to fall within a certain range. Each image will be resized to 512px.","metadata":{}},{"cell_type":"code","source":"def imread_and_imwirte(src_path, dst_path):\n    dicom_data = pydicom.dcmread(src_path)\n    image = dicom_data.pixel_array\n    image = (image - image.min()) / (image.max() - image.min() +1e-6) * 255\n    img = cv2.resize(image, (512, 512),interpolation=cv2.INTER_CUBIC)\n    assert img.shape==(512,512)\n    cv2.imwrite(dst_path, img)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.412303Z","iopub.execute_input":"2024-07-26T21:37:24.412972Z","iopub.status.idle":"2024-07-26T21:37:24.419198Z","shell.execute_reply.started":"2024-07-26T21:37:24.412939Z","shell.execute_reply":"2024-07-26T21:37:24.417949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"st_ids = df_descriptions['study_id'].unique()\nst_ids[:3], len(st_ids)","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.420668Z","iopub.execute_input":"2024-07-26T21:37:24.421011Z","iopub.status.idle":"2024-07-26T21:37:24.436072Z","shell.execute_reply.started":"2024-07-26T21:37:24.420976Z","shell.execute_reply":"2024-07-26T21:37:24.434786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique_descriptions = list(df_descriptions['series_description'].unique())\nunique_descriptions","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.439106Z","iopub.execute_input":"2024-07-26T21:37:24.439488Z","iopub.status.idle":"2024-07-26T21:37:24.449719Z","shell.execute_reply.started":"2024-07-26T21:37:24.439458Z","shell.execute_reply":"2024-07-26T21:37:24.448634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Helper functions\ndef atoi(text):\n    return int(text) if text.isdigit() else text\n\ndef natural_keys(text):\n    return [ atoi(c) for c in re.split(r'(\\d+)', text) ]","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.451340Z","iopub.execute_input":"2024-07-26T21:37:24.451675Z","iopub.status.idle":"2024-07-26T21:37:24.460433Z","shell.execute_reply.started":"2024-07-26T21:37:24.451647Z","shell.execute_reply":"2024-07-26T21:37:24.459209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for idx, si in enumerate(tqdm(st_ids, total=len(st_ids))):\n    pdf = df_descriptions[df_descriptions['study_id']==si]\n    for ds in unique_descriptions:\n        ds_ = ds.replace('/', '_')\n        pdf_ = pdf[pdf['series_description']==ds]\n        os.makedirs(f'cvt_png/{si}/{ds_}', exist_ok=True)\n        allimgs = []\n        for i, row in pdf_.iterrows():\n            pimgs = glob.glob(f'{input_directory}/train_images/{row[\"study_id\"]}/{row[\"series_id\"]}/*.dcm')\n            pimgs = sorted(pimgs, key=natural_keys)\n            allimgs.extend(pimgs)\n            \n        if len(allimgs)==0:\n            print(si, ds, 'has no images')\n            continue\n\n        if ds == 'Axial T2':\n            for j, impath in enumerate(allimgs):\n                dst = f'cvt_png/{si}/{ds}/{j:03d}.png'\n                imread_and_imwirte(impath, dst)\n                \n        elif ds == 'Sagittal T2/STIR':\n            \n            step = len(allimgs) / 10.0\n            st = len(allimgs)/2.0 - 4.0*step\n            end = len(allimgs)+0.0001\n            for j, i in enumerate(np.arange(st, end, step)):\n                dst = f'cvt_png/{si}/{ds_}/{j:03d}.png'\n                ind2 = max(0, int((i-0.5001).round()))\n                imread_and_imwirte(allimgs[ind2], dst)\n                \n            assert len(glob.glob(f'cvt_png/{si}/{ds_}/*.png'))==10\n                \n        elif ds == 'Sagittal T1':\n            step = len(allimgs) / 10.0\n            st = len(allimgs)/2.0 - 4.0*step\n            end = len(allimgs)+0.0001\n            for j, i in enumerate(np.arange(st, end, step)):\n                dst = f'cvt_png/{si}/{ds}/{j:03d}.png'\n                ind2 = max(0, int((i-0.5001).round()))\n                imread_and_imwirte(allimgs[ind2], dst)\n                \n            assert len(glob.glob(f'cvt_png/{si}/{ds}/*.png'))==10","metadata":{"execution":{"iopub.status.busy":"2024-07-26T21:37:24.461728Z","iopub.execute_input":"2024-07-26T21:37:24.462201Z","iopub.status.idle":"2024-07-26T22:28:32.866563Z","shell.execute_reply.started":"2024-07-26T21:37:24.462159Z","shell.execute_reply":"2024-07-26T22:28:32.865253Z"},"trusted":true},"execution_count":null,"outputs":[]}]}