{"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":"markdown","source":"# Convert Dicom series to NumPy arrays\n\n#### 📔 [Data preparation notebook](https://www.kaggle.com/code/vmuzhichenko/rsna-22-dicom-to-numpy-3d)\n#### 📔 [Trainnig notebook](https://www.kaggle.com/code/vmuzhichenko/rsna-22-resnet-50-3d-train)\n#### 📔 [Inference notebook](https://www.kaggle.com/code/vmuzhichenko/rsna-22-resnet-50-3d-inference)","metadata":{}},{"cell_type":"code","source":"#install pydicom requirements\n\n%load_ext autoreload\n%autoreload 2\n!conda install '/kaggle/input/pydicom-conda-helper/libjpeg-turbo-2.1.0-h7f98852_0.tar.bz2' --offline -y\n!conda install '/kaggle/input/pydicom-conda-helper/libgcc-ng-9.3.0-h2828fa1_19.tar.bz2' --offline -y\n#!conda install '/kaggle/input/pydicom-conda-helper/gdcm-2.8.9-py37h500ead1_1.Truetar.bz2' --offline -y \n!cp ../input/gdcm-conda-install/gdcm.tar .\n!tar -xvzf gdcm.tar\n!conda install --offline ./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2\n!conda install '/kaggle/input/pydicom-conda-helper/conda-4.10.1-py37h89c1867_0.tar.bz2' --offline -y\n!conda install '/kaggle/input/pydicom-conda-helper/certifi-2020.12.5-py37h89c1867_1.tar.bz2' --offline -y\n!conda install '/kaggle/input/pydicom-conda-helper/openssl-1.1.1k-h7f98852_0.tar.bz2' --offline -y","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-output":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-08-19T16:35:27.766839Z","iopub.execute_input":"2022-08-19T16:35:27.76778Z","iopub.status.idle":"2022-08-19T16:36:33.342635Z","shell.execute_reply.started":"2022-08-19T16:35:27.767656Z","shell.execute_reply":"2022-08-19T16:36:33.341106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport glob\nimport gc\n\nimport numpy as np\nimport pandas as pd\n\nfrom joblib import Parallel, delayed\nfrom tqdm.notebook import tqdm\n\nimport pydicom\nimport matplotlib.pyplot as plt\nfrom matplotlib import animation, rc\nimport cv2\n\n\nimport nibabel as nib","metadata":{"execution":{"iopub.status.busy":"2022-08-19T16:36:33.345064Z","iopub.execute_input":"2022-08-19T16:36:33.345558Z","iopub.status.idle":"2022-08-19T16:36:33.95635Z","shell.execute_reply.started":"2022-08-19T16:36:33.345519Z","shell.execute_reply":"2022-08-19T16:36:33.955285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#set desired image size and depth (number of patient's images to load)\nclass Config:\n    img_size = 256\n    depth = 128\n\n\nIMG_PATH_TRAIN = '../input/rsna-2022-cervical-spine-fracture-detection/train_images/'\nIMG_PATH_TEST = '../input/rsna-2022-cervical-spine-fracture-detection/test_images/'\nTRAIN_CSV_PATH = '../input/rsna-2022-cervical-spine-fracture-detection/train.csv'\nTEST_CSV_PATH = '../input/rsna-2022-cervical-spine-fracture-detection/test.csv'\n\ntrain_images = os.listdir(IMG_PATH_TRAIN)\ntest_images = os.listdir(IMG_PATH_TEST)\n\ntrain=pd.read_csv(TRAIN_CSV_PATH)\ntest=pd.read_csv(TEST_CSV_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T16:36:33.957521Z","iopub.execute_input":"2022-08-19T16:36:33.957835Z","iopub.status.idle":"2022-08-19T16:36:34.119925Z","shell.execute_reply.started":"2022-08-19T16:36:33.957807Z","shell.execute_reply":"2022-08-19T16:36:34.119071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path):\n    dicom = pydicom.read_file(path)\n    data = dicom.pixel_array\n    data = data - np.min(data)\n    if np.max(data) != 0:\n        data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    data = cv2.resize(data, (Config.img_size,Config.img_size), interpolation = cv2.INTER_AREA)\n    return data\n     \n\ndef load_dicom_line_par(path, indices:list = None):\n    t_paths = sorted(glob.glob(os.path.join(path, \"*\")),\n       key=lambda x: int(x.split('/')[-1].split(\".\")[0]))\n    \n    if indices is not None:\n        t_paths = [t_paths[i] for i in indices]\n        \n    images = Parallel(n_jobs=-1)(delayed(load_dicom)(filename) for filename in t_paths)\n    \n    return np.array(images)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-19T16:36:34.123446Z","iopub.execute_input":"2022-08-19T16:36:34.124386Z","iopub.status.idle":"2022-08-19T16:36:34.165335Z","shell.execute_reply.started":"2022-08-19T16:36:34.124327Z","shell.execute_reply":"2022-08-19T16:36:34.163847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_output_path = './train_arrays/'\ntest_output_path = './test_arrays/'\n\nif not os.path.exists(train_output_path): os.mkdir(train_output_path)\nif not os.path.exists(test_output_path): os.mkdir(test_output_path)    \n    \ntrain_patients = train.StudyInstanceUID.to_list()\n\ndef save_3d_voxels(dicom_path, output_path):\n    \n    n_scans=len(os.listdir(dicom_path))\n    \n    #instead of zooming whole dicom series, load only part of the images\n    ind = np.quantile(list(range(n_scans)), np.linspace(0., 1., Config.depth)).round().astype(int)\n    image = load_dicom_line_par(dicom_path, indices = ind)\n    \n    if image.ndim <4:\n        image = np.expand_dims(image, -1)\n    \n    np.save(f\"{output_path}{dicom_path.split('/')[-1]}.npy\", image)\n    \n    del image\n    return None\n \n\nfor i in tqdm(range(len(train_patients))):\n    case = IMG_PATH_TRAIN + train_patients[i]\n    save_3d_voxels(case, train_output_path)\n    \ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T16:39:50.943674Z","iopub.execute_input":"2022-08-19T16:39:50.944117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rc('animation', html='jshtml')\n\ndef create_animation(array, case):\n    fig = plt.figure(figsize=(8, 8))\n    images = []\n    for image in array:\n        image_plot = plt.imshow(image, animated=True, cmap='gray')\n        plt.axis(\"off\")\n        images.append([image_plot])\n        \n    plt.title(f'Patient id: {case}', fontsize=16)    \n    ani = animation.ArtistAnimation(fig, images, interval = 5000//len(array), blit=False, repeat_delay=1000)\n    plt.close()\n    return ani","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show saved example array\n\ntrain_arrays = os.listdir(train_output_path)\narray_path = train_output_path + train_arrays[np.random.randint(len(train_arrays))]\narray = np.load(array_path)\ncase_id = array_path.split('/')[-1][:-4]\ncreate_animation(array, case_id)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}