{"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":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Many thanks to this [notebook](https://www.kaggle.com/code/radek1/how-to-process-dicom-images-to-pngs?scriptVersionId=113529850) for converting Dicom images to PNG!\n\nHere is the [actual dataset](https://www.kaggle.com/datasets/srinivaskumarr/rsna-spine-2024-png-images) with PNG images.","metadata":{}},{"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":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-25T08:13:00.877449Z","iopub.execute_input":"2024-05-25T08:13:00.877978Z","iopub.status.idle":"2024-05-25T08:13:00.910455Z","shell.execute_reply.started":"2024-05-25T08:13:00.877945Z","shell.execute_reply":"2024-05-25T08:13:00.909312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# List out all of the Studies we have on patients.\npart_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))\n\ndf_meta_f = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')\n\np1 = [(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 }\n\nfor 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    )\n","metadata":{"execution":{"iopub.status.busy":"2024-05-25T08:13:37.191596Z","iopub.execute_input":"2024-05-25T08:13:37.191994Z","iopub.status.idle":"2024-05-25T08:13:44.144453Z","shell.execute_reply.started":"2024-05-25T08:13:37.191963Z","shell.execute_reply":"2024-05-25T08:13:44.143015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# grabs the correspoding series descriptions\nfor 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)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-25T08:15:04.349312Z","iopub.execute_input":"2024-05-25T08:15:04.349735Z","iopub.status.idle":"2024-05-25T08:15:07.881903Z","shell.execute_reply.started":"2024-05-25T08:15:04.349702Z","shell.execute_reply":"2024-05-25T08:15:07.880800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train.fillna(\"Normal/Mild\")\n\ntrain_images = []\ntrain_labels = []\n\nfor idx in tqdm(range(len(train_df))):\n    patient = train_df.iloc[idx]\n    ptobj = meta_obj[str(patient['study_id'])]\n    \n    label_dict = {\n        \"Normal/Mild\": [1, 0, 0],\n        \"Moderate\": [0, 1, 0],\n        \"Severe\": [0, 0, 1]\n    }\n    labels = []\n    for x,y in patient.items():\n        if \"study\" in x:\n            continue\n        labels.append(label_dict[y])\n    \n    for idx, i in enumerate(ptobj['SeriesInstanceUIDs']):\n        images = glob.glob(f\"{ptobj['folder_path']}/{ptobj['SeriesInstanceUIDs'][idx]}/*.dcm\")\n        for image_path in sorted(images, key=lambda x: int(x.split('/')[-1].replace('.dcm', ''))):\n            img_name = image_path[image_path.rfind('/' , 2) + 1: image_path.find('.dcm')]\n            if img_name == \".\" or img_name == \"\":\n                continue\n            train_images.append(image_path)\n            train_labels.append(np.array(labels))\n","metadata":{"execution":{"iopub.status.busy":"2024-05-25T08:15:29.075116Z","iopub.execute_input":"2024-05-25T08:15:29.075860Z","iopub.status.idle":"2024-05-25T08:16:30.168530Z","shell.execute_reply.started":"2024-05-25T08:15:29.075825Z","shell.execute_reply":"2024-05-25T08:16:30.167328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\nfrom pathlib import Path\nimport numpy as np\nfrom PIL import Image\n\nRESIZE_TO = (512, 512)\n!rm -rf train_images_processed_{RESIZE_TO[0]}\n!mkdir train_images_processed_{RESIZE_TO[0]}\n\ncnt = 0\n\n# https://www.kaggle.com/code/tanlikesmath/brain-tumor-radiogenomic-classification-eda/notebook\ndef dicom_file_to_ary(path):\n    dicom = pydicom.read_file(path)\n    data = dicom.pixel_array\n    if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    return data\n\n#directories = list(Path('train_images').iterdir())\n\ndef process_image(image_path):\n    \n    i_pth = image_path\n    base_pth = i_pth[0:i_pth.find('train_images') - 1]\n    dir_pth = i_pth[i_pth.find('train_images') + 13: i_pth.rfind('/')]\n    img_name = i_pth[i_pth.rfind('/' , 2) + 1: i_pth.find('.dcm')]\n    \n    !mkdir -p train_images_processed_{RESIZE_TO[0]}/{dir_pth}\n    \n    processed_ary = dicom_file_to_ary(image_path)\n    im = Image.fromarray(processed_ary).resize(RESIZE_TO)\n    im.save(f'train_images_processed_{RESIZE_TO[0]}/{dir_pth}/{img_name}.png')\n        \nimport multiprocessing as mp\n\nwith mp.Pool(256) as p:\n    p.map(process_image, train_images)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!zip -r file.zip /kaggle/working\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import FileLink\nFileLink(r'file.zip')\n","metadata":{},"execution_count":null,"outputs":[]}]}