{"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":"code","source":"import os\nimport pickle\nimport random\nfrom tqdm.notebook import tqdm\nfrom joblib import Parallel, delayed\n\nimport torch\nimport torch.nn as nn\nimport numpy as np\nimport pandas as pd\nimport pydicom\nfrom torchvision.transforms import Resize","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-08-21T02:41:07.309225Z","iopub.execute_input":"2023-08-21T02:41:07.309535Z","iopub.status.idle":"2023-08-21T02:41:10.41059Z","shell.execute_reply.started":"2023-08-21T02:41:07.309504Z","shell.execute_reply":"2023-08-21T02:41:10.409437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_IMG_PATH = '/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images'\nROOT = 'tensor_data'","metadata":{"execution":{"iopub.status.busy":"2023-08-21T02:49:13.777696Z","iopub.execute_input":"2023-08-21T02:49:13.77804Z","iopub.status.idle":"2023-08-21T02:49:13.783685Z","shell.execute_reply.started":"2023-08-21T02:49:13.778013Z","shell.execute_reply":"2023-08-21T02:49:13.782293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def standardize_pixel_array(dicom_path):\n    \"\"\"\n    Standardizes a DICOM pixel array for image preprocessing.\n    \n    This function applies various transformations to the pixel array of a DICOM image\n    to preprocess it for further analysis or visualization.\n    \n    Args:\n        dicom_path (str): Path to the DICOM image file.\n        \n    Returns:\n        np.ndarray: The standardized pixel array of the DICOM image.\n    \"\"\"\n    dicom_image = pydicom.dcmread(dicom_path)\n    \n    pixel_array = dicom_image.pixel_array\n    \n    if dicom_image.PixelRepresentation == 1:\n        bit_shift = dicom_image.BitsAllocated - dicom_image.BitsStored\n        dtype = pixel_array.dtype \n        new_array = (pixel_array << bit_shift).astype(dtype) >>  bit_shift\n        pixel_array = pydicom.pixel_data_handlers.util.apply_modality_lut(new_array, dicom_image)\n    \n    if dicom_image.PhotometricInterpretation == \"MONOCHROME1\":\n        pixel_array = 1 - pixel_array\n    \n    # transform to hounsfield units\n    intercept = dicom_image.RescaleIntercept\n    slope = dicom_image.RescaleSlope\n    pixel_array = pixel_array * slope + intercept\n    \n    # windowing\n    window_center = int(dicom_image.WindowCenter)\n    window_width = int(dicom_image.WindowWidth)\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    pixel_array = pixel_array.copy()\n    pixel_array[pixel_array < img_min] = img_min\n    pixel_array[pixel_array > img_max] = img_max\n    \n    # normalization\n    if pixel_array.max() == pixel_array.min():\n        pixel_array = np.zeros_like(pixel_array)  # Handle case of constant array\n    else:\n        pixel_array = (pixel_array - pixel_array.min()) / (pixel_array.max() - pixel_array.min())\n    \n    return pixel_array","metadata":{"execution":{"iopub.status.busy":"2023-08-21T02:41:10.421521Z","iopub.execute_input":"2023-08-21T02:41:10.421824Z","iopub.status.idle":"2023-08-21T02:41:10.434239Z","shell.execute_reply.started":"2023-08-21T02:41:10.421797Z","shell.execute_reply":"2023-08-21T02:41:10.433205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PreProcess:\n    \n    def __init__(self):\n        \n#         with open(IMG_PATHS_FILE, 'rb') as fp:\n#             self.img_paths = pickle.load(fp)\n        self.img_paths = []\n        for patient in os.listdir(TRAIN_IMG_PATH):\n            for s in os.listdir(os.path.join(TRAIN_IMG_PATH,patient)):\n                scans = []\n                for img in os.listdir(os.path.join(TRAIN_IMG_PATH, patient, s)):\n                    path = os.path.join(TRAIN_IMG_PATH, patient, s, img)\n                    scans.append(path)\n                self.img_paths.append(scans)\n        \n        self.resize = Resize((128, 128),  antialias=True)\n        \n    def read_scan(self, scans_path):\n        \n        image_instances = []\n        root = '/'.join(scans_path[0].split('/')[:-1])\n        \n        for img in scans_path:\n            image_instances.append(int(img.split('/')[-1][:-4]))\n        \n            \n        image_instances = sorted(image_instances)\n        scans_path = [os.path.join(root, str(img) + '.dcm') for img in image_instances]\n\n        images = Parallel(n_jobs=-1)(delayed(standardize_pixel_array)(item) for item in scans_path)\n        volume = np.stack(images)\n        \n        return volume\n        \n    \n    def save_tensors(self):\n        \n        for scans_path in tqdm(self.img_paths):\n            \n            vol = self.read_scan(scans_path)\n            vol = torch.tensor(vol, dtype = torch.float)\n            vol = self.resize(vol)\n\n            patient = scans_path[0].split('/')[-3]\n            scan_id = scans_path[0].split('/')[-2]\n\n            if not os.path.exists(os.path.join(ROOT, patient)):\n                os.makedirs(os.path.join(ROOT, patient))\n\n            torch.save(vol, os.path.join(ROOT, patient, scan_id + '.pt'))\n            break","metadata":{"execution":{"iopub.status.busy":"2023-08-21T02:48:45.121871Z","iopub.execute_input":"2023-08-21T02:48:45.122268Z","iopub.status.idle":"2023-08-21T02:48:45.13432Z","shell.execute_reply.started":"2023-08-21T02:48:45.122237Z","shell.execute_reply":"2023-08-21T02:48:45.133042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preprocess = PreProcess()","metadata":{"execution":{"iopub.status.busy":"2023-08-21T02:49:18.907257Z","iopub.execute_input":"2023-08-21T02:49:18.907789Z","iopub.status.idle":"2023-08-21T02:54:51.59842Z","shell.execute_reply.started":"2023-08-21T02:49:18.90776Z","shell.execute_reply":"2023-08-21T02:54:51.597226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preprocess.save_tensors()","metadata":{"execution":{"iopub.status.busy":"2023-08-21T02:54:57.532569Z","iopub.execute_input":"2023-08-21T02:54:57.532927Z","iopub.status.idle":"2023-08-21T02:54:59.858808Z","shell.execute_reply.started":"2023-08-21T02:54:57.532899Z","shell.execute_reply":"2023-08-21T02:54:59.857277Z"},"trusted":true},"execution_count":null,"outputs":[]}]}