{"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 torch\nimport torch.nn.functional as F\n\nimport os\nimport pydicom\n\nimport numpy as np\nimport pandas as pd\n\nimport nibabel as nib\n\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom joblib import Parallel, delayed\n\nimport sys","metadata":{"execution":{"iopub.status.busy":"2023-10-08T18:44:23.94001Z","iopub.execute_input":"2023-10-08T18:44:23.940546Z","iopub.status.idle":"2023-10-08T18:44:28.149749Z","shell.execute_reply.started":"2023-10-08T18:44:23.94051Z","shell.execute_reply":"2023-10-08T18:44:28.148742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Volumer():\n    \n    def __init__(self, IMAGE_ROOT):\n        self.IMAGE_ROOT = IMAGE_ROOT\n        self.is_current_flipped = None\n     \n    def dicom_to_image(self, dcm):\n    \n        pixel_array = dcm.pixel_array\n\n        if dcm.PixelRepresentation == 1:\n            bit_shift = dcm.BitsAllocated - dcm.BitsStored\n            dtype = pixel_array.dtype \n            pixel_array = (pixel_array << bit_shift).astype(dtype) >>  bit_shift\n\n        if dcm.PhotometricInterpretation == \"MONOCHROME1\":\n            pixel_array = 1 - pixel_array\n\n        intercept = dcm.RescaleIntercept\n        slope = dcm.RescaleSlope\n        pixel_array = pixel_array * slope + intercept\n\n        window_center = 50\n        window_width = 400\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        pixel_array = (pixel_array - img_min)/(img_max-img_min)\n\n        return pixel_array\n    \n    def read_dicom(self, entry):\n        path = os.path.join(self.IMAGE_ROOT, str(entry.patient_id), str(entry.series_id), str(entry.instance_id)+'.dcm')\n        dcm = pydicom.dcmread(path)\n        \n        return dcm\n    \n    def is_flipped(self, instances):\n        first = self.read_dicom(instances.iloc[0])\n        last = self.read_dicom(instances.iloc[-1])\n        \n        _, _, z0 = first.ImagePositionPatient\n        _, _, z1 = last.ImagePositionPatient\n        \n        return z1 > z0\n    \n    def read_dicom_image(self, entry):\n        dcm = self.read_dicom(entry)\n\n        return self.dicom_to_image(dcm)\n    \n    def get_volume(self, instances):\n\n        instances = instances.sort_values('instance_id')\n        self.is_current_flipped = self.is_flipped(instances)\n        if self.is_current_flipped:\n            instances = instances[::-1]\n\n        images = instances.apply(self.read_dicom_image, axis=1).values\n\n        volume = np.stack(images)\n\n        return volume\n    \n    def resize_volume(self, volume, dims, mode='nearest'):\n        \n        volume = torch.Tensor(volume)\n        volume = volume.unsqueeze(dim=0).unsqueeze(dim=0)\n        volume = F.interpolate(volume, dims, mode=mode).squeeze()\n        \n        return volume.numpy()\n    \n    def get_volume_bbox(self, volume):\n        x0, y0, x1, y1 = 10000, 10000, -1, -1\n        for i in range(volume.shape[0]):\n            cur_x0, cur_y0, cur_x1, cur_y1 = self.get_slice_bbox(volume[i])\n            x0 = min(x0, cur_x0)\n            y0 = min(y0, cur_y0)\n            x1 = max(x1, cur_x1)\n            y1 = max(y1, cur_y1)\n            \n        return x0, y0, x1, y1\n    \n    def get_slice_bbox(self, image):\n        image = (image*255).astype('uint8')\n        blur = cv2.GaussianBlur(image, (5,5), 0)\n\n        _, mask = cv2.threshold(blur, 1, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)\n        cnts, _ = cv2.findContours(mask.astype('uint8'), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n        cnt = max(cnts, key = cv2.contourArea)\n        x, y, w, h = cv2.boundingRect(cnt)\n\n        return x, y, x+w, y+h","metadata":{"execution":{"iopub.status.busy":"2023-10-08T18:44:28.151555Z","iopub.execute_input":"2023-10-08T18:44:28.15219Z","iopub.status.idle":"2023-10-08T18:44:28.169456Z","shell.execute_reply.started":"2023-10-08T18:44:28.15216Z","shell.execute_reply":"2023-10-08T18:44:28.168485Z"},"trusted":true},"execution_count":null,"outputs":[]}]}