{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":39272,"databundleVersionId":4629629},{"sourceType":"datasetVersion","sourceId":4421846,"datasetId":2590074,"databundleVersionId":4481059},{"sourceType":"datasetVersion","sourceId":4998596,"datasetId":2891303,"databundleVersionId":5067508},{"sourceType":"datasetVersion","sourceId":5877069,"datasetId":2998419,"databundleVersionId":5954283},{"sourceType":"datasetVersion","sourceId":4804745,"datasetId":2779893,"databundleVersionId":4868214}],"dockerImageVersionId":30381,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install nvidia-tensorrt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T15:16:59.530426Z","iopub.execute_input":"2026-05-07T15:16:59.53123Z","iopub.status.idle":"2026-05-07T15:18:42.291809Z","shell.execute_reply.started":"2026-05-07T15:16:59.531194Z","shell.execute_reply":"2026-05-07T15:18:42.290828Z"}},"outputs":[{"name":"stdout","text":"\u001b[33mWARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7bd7a9d07890>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/nvidia-tensorrt/\u001b[0m\u001b[33m\n\u001b[0m\u001b[33mWARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7bd7a9aa6850>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/nvidia-tensorrt/\u001b[0m\u001b[33m\n\u001b[0m\u001b[33mWARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7bd7a9aa6990>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/nvidia-tensorrt/\u001b[0m\u001b[33m\n\u001b[0m^C\n","output_type":"stream"}],"execution_count":3},{"cell_type":"code","source":"!find /kaggle/input -name \"*tensorrt*\" -type d\n#!ls /kaggle/input/rsna-breast-cancer-detection-best-ckpts/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T15:21:13.700474Z","iopub.execute_input":"2026-05-07T15:21:13.701449Z","iopub.status.idle":"2026-05-07T15:25:41.158413Z","shell.execute_reply.started":"2026-05-07T15:21:13.701407Z","shell.execute_reply":"2026-05-07T15:25:41.157314Z"}},"outputs":[{"name":"stdout","text":"/kaggle/input/torch-tensorrt-pkg\n","output_type":"stream"}],"execution_count":5},{"cell_type":"code","source":"!pip install /kaggle/input/kaggle-rsna-pkgs/tensorrt-8.x.x-cp37-none-linux_x86_64.whl","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T15:18:45.989837Z","iopub.execute_input":"2026-05-07T15:18:45.990744Z","iopub.status.idle":"2026-05-07T15:18:54.154902Z","shell.execute_reply.started":"2026-05-07T15:18:45.990698Z","shell.execute_reply":"2026-05-07T15:18:54.153846Z"}},"outputs":[{"name":"stdout","text":"\u001b[33mWARNING: Requirement '/kaggle/input/your-dataset-name/tensorrt-8.x.x-cp37-none-linux_x86_64.whl' looks like a filename, but the file does not exist\u001b[0m\u001b[33m\n\u001b[0mProcessing /kaggle/input/your-dataset-name/tensorrt-8.x.x-cp37-none-linux_x86_64.whl\n\u001b[31mERROR: Could not install packages due to an OSError: [Errno 2] No such file or directory: '/kaggle/input/your-dataset-name/tensorrt-8.x.x-cp37-none-linux_x86_64.whl'\n\u001b[0m\u001b[31m\n\u001b[0m^C\n","output_type":"stream"}],"execution_count":4},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport os\nimport gc\nimport time\nimport pydicom\n\ntry:\n    import dicomsdl\nexcept:\n    !pip install /kaggle/input/kaggle-rsna-pkgs/pylibjpeg-1.4.0-py3-none-any.whl\n    !pip install /kaggle/input/kaggle-rsna-pkgs/python_gdcm-3.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n    !pip install /kaggle/input/kaggle-rsna-pkgs/dicomsdl-0.109.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl\n\n\nos.environ['CUDA_MODULE_LOADING'] = 'LAZY'\nimport sys\nimport cv2\nimport numpy as np\nimport torch\nimport torchvision\nsys.path.append('/kaggle/tmp/libs/')\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\n\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\nfrom torch2trt import TRTModule","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T15:15:57.610913Z","iopub.execute_input":"2026-05-07T15:15:57.611716Z","iopub.status.idle":"2026-05-07T15:15:57.677587Z","shell.execute_reply.started":"2026-05-07T15:15:57.611679Z","shell.execute_reply":"2026-05-07T15:15:57.676372Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_30/4249506644.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     27\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/input/kaggle-rsna-pkgs/torch2trt'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     28\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 29\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTRTModule\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;32m/kaggle/input/kaggle-rsna-pkgs/torch2trt/torch2trt/__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mconverters\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtensorrt\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtrt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mload_plugins\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/input/kaggle-rsna-pkgs/torch2trt/torch2trt/torch2trt.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mtensorrt\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtrt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mio\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'tensorrt'"],"ename":"ModuleNotFoundError","evalue":"No module named 'tensorrt'","output_type":"error"}],"execution_count":2},{"cell_type":"code","source":"!pip install nvidia-tensorrt\n\n# %%writefile roi_extract.py\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport os\nimport gc\nimport time\nimport pydicom\n\ntry:\n    import dicomsdl\nexcept:\n    !pip install /kaggle/input/kaggle-rsna-pkgs/pylibjpeg-1.4.0-py3-none-any.whl\n    !pip install /kaggle/input/kaggle-rsna-pkgs/python_gdcm-3.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n    !pip install /kaggle/input/kaggle-rsna-pkgs/dicomsdl-0.109.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl\n\n\nos.environ['CUDA_MODULE_LOADING'] = 'LAZY'\nimport sys\nimport cv2\nimport numpy as np\nimport torch\nimport torchvision\nsys.path.append('/kaggle/tmp/libs/')\nfrom torch2trt import TRTModule\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\n\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\nfrom torch2trt import TRTModule\n\n\n_TORCH_VER = [int(x) for x in torch.__version__.split(\".\")[:2]]\n_TORCH11X = (_TORCH_VER >= [1, 10])\n\n\ndef meshgrid(*tensors):\n    if _TORCH11X:\n        return torch.meshgrid(*tensors, indexing=\"ij\")\n    else:\n        return torch.meshgrid(*tensors)\n\n\ndef extract_roi_otsu(img, gkernel=(5, 5)):\n    \"\"\"WARNING: this function modify input image inplace.\"\"\"\n    ori_h, ori_w = img.shape[:2]\n    # clip percentile: implant, white lines\n    upper = np.percentile(img, 95)\n    img[img > upper] = np.min(img)\n    # Gaussian filtering to reduce noise (optional)\n    if gkernel is not None:\n        img = cv2.GaussianBlur(img, gkernel, 0)\n    _, img_bin = cv2.threshold(img, 0, 255,\n                               cv2.THRESH_BINARY + cv2.THRESH_OTSU)\n    # dilation to improve contours connectivity\n    element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3), (-1, -1))\n    img_bin = cv2.dilate(img_bin, element)\n    cnts, _ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL,\n                               cv2.CHAIN_APPROX_SIMPLE)\n    if len(cnts) == 0:\n        return None, None, None\n    areas = np.array([cv2.contourArea(cnt) for cnt in cnts])\n    select_idx = np.argmax(areas)\n    cnt = cnts[select_idx]\n    area_pct = areas[select_idx] / (img.shape[0] * img.shape[1])\n    x0, y0, w, h = cv2.boundingRect(cnt)\n    # min-max for safety only\n    # x0, y0, x1, y1\n    x1 = min(max(int(x0 + w), 0), ori_w)\n    y1 = min(max(int(y0 + h), 0), ori_h)\n    x0 = min(max(int(x0), 0), ori_w)\n    y0 = min(max(int(y0), 0), ori_h)\n    return [x0, y0, x1, y1], area_pct, None\n\n\nclass RoiExtractor:\n\n    def __init__(self,\n                 engine_path,\n                 input_size,\n                 num_classes,\n                 conf_thres=0.5,\n                 nms_thres=0.9,\n                 class_agnostic=False,\n                 area_pct_thres=0.04,\n                 hw=None,\n                 strides=None,\n                 exp=None):\n        self.input_size = input_size\n        self.input_h, self.input_w = input_size\n        self.num_classes = num_classes\n        self.conf_thres = conf_thres\n        self.nms_thres = nms_thres\n        self.class_agnostic = class_agnostic\n        self.area_pct_thres = area_pct_thres\n\n        model = TRTModule()\n        model.load_state_dict(torch.load(engine_path))\n        self.model = model\n        if hw is None or strides is None:\n            assert exp is not None\n            self._set_meta(exp)\n        else:\n            self.hw = hw\n            self.strides = strides\n\n    def _set_meta(self, exp):\n        assert exp is not None\n        print(\"Start probing model metadata..\")\n        # dummy infer\n        torch_model = exp.get_model().cuda().eval()\n        _dummy = torch.ones(1, 3, exp.test_size[0], exp.test_size[1]).cuda()\n        torch_model(_dummy)\n        # set attributes\n        self.hw = torch_model.head.hw\n        self.strides = torch_model.head.strides\n        # cleanup\n        del torch_model, _dummy\n        import gc\n        gc.collect()\n        torch.cuda.empty_cache()\n        print('Done probbing model metadata..')\n\n    def decode_outputs(self, outputs):\n        dtype = outputs.type()\n        grids = []\n        strides = []\n        for (hsize, wsize), stride in zip(self.hw, self.strides):\n            yv, xv = meshgrid([torch.arange(hsize), torch.arange(wsize)])\n            grid = torch.stack((xv, yv), 2).view(1, -1, 2)\n            grids.append(grid)\n            shape = grid.shape[:2]\n            strides.append(torch.full((*shape, 1), stride))\n\n        grids = torch.cat(grids, dim=1).type(dtype)\n        strides = torch.cat(strides, dim=1).type(dtype)\n\n        outputs = torch.cat(\n            [(outputs[..., 0:2] + grids) * strides,\n             torch.exp(outputs[..., 2:4]) * strides, outputs[..., 4:]],\n            dim=-1)\n        return outputs\n\n    def post_process(self,\n                     pred,\n                     conf_thres=0.5,\n                     nms_thres=0.9,\n                     class_agnostic=False):\n        box_corner = pred.new(pred.shape)\n        box_corner[:, :, 0] = pred[:, :, 0] - pred[:, :, 2] / 2\n        box_corner[:, :, 1] = pred[:, :, 1] - pred[:, :, 3] / 2\n        box_corner[:, :, 2] = pred[:, :, 0] + pred[:, :, 2] / 2\n        box_corner[:, :, 3] = pred[:, :, 1] + pred[:, :, 3] / 2\n        pred[:, :, :4] = box_corner[:, :, :4]\n\n        output = [None for _ in range(len(pred))]\n        for i, image_pred in enumerate(pred):\n\n            # If none are remaining => process next image\n            if not image_pred.size(0):\n                continue\n            # Get score and class with highest confidence\n            class_conf, class_pred = torch.max(image_pred[:, 5:5 +\n                                                          self.num_classes],\n                                               1,\n                                               keepdim=True)\n\n            conf_mask = (image_pred[:, 4] * class_conf.squeeze() >=\n                         conf_thres).squeeze()\n            # Detections ordered as (x1, y1, x2, y2, obj_conf, class_conf, class_pred)\n            detections = torch.cat(\n                (image_pred[:, :5], class_conf, class_pred.float()), 1)\n            detections = detections[conf_mask]\n            if not detections.size(0):\n                continue\n\n            if class_agnostic:\n                nms_out_index = torchvision.ops.nms(\n                    detections[:, :4],\n                    detections[:, 4] * detections[:, 5],\n                    nms_thres,\n                )\n            else:\n                nms_out_index = torchvision.ops.batched_nms(\n                    detections[:, :4],\n                    detections[:, 4] * detections[:, 5],\n                    detections[:, 6],\n                    nms_thres,\n                )\n            detections = detections[nms_out_index]\n            if output[i] is None:\n                output[i] = detections\n            else:\n                output[i] = torch.cat((output[i], detections))\n        return output\n\n    def preprocess_single(self, img: torch.Tensor):\n        ori_h = img.size(0)\n        ori_w = img.size(1)\n        ratio = min(self.input_h / ori_h, self.input_w / ori_w)\n        # resize\n        resized_img = F.interpolate(img.view(1, 1, ori_h, ori_w),\n                                    mode=\"bilinear\",\n                                    scale_factor=ratio,\n                                    recompute_scale_factor=True)[0, 0]\n        # padding\n        padded_img = torch.full((self.input_h, self.input_w),\n                                114,\n                                dtype=resized_img.dtype,\n                                device='cuda')\n        padded_img[:resized_img.size(0), :resized_img.size(1)] = resized_img\n        # 1 channel --> 3 channels\n        padded_img = padded_img.unsqueeze(-1).expand(-1, -1, 3)\n        # HWC --> CHW\n        padded_img = padded_img.permute(2, 0, 1)\n        padded_img = padded_img.float()\n        return padded_img, resized_img, ratio, ori_h, ori_w\n\n    def detect_single(self, img):\n        padded_img, resized_img, ratio, ori_h, ori_w = self.preprocess_single(\n            img)\n        padded_img = padded_img.unsqueeze(0)\n        output = self.model(padded_img)\n        output = self.decode_outputs(output)\n        # x0, y0, x1, y1, box_conf, cls_conf, cls_id\n        output = self.post_process(output, self.conf_thres, self.nms_thres)[0]\n        if output is not None:\n            output[:, :4] = output[:, :4] / ratio\n            # re-compute: conf = box_conf * cls_conf\n            output[:, 4] = output[:, 4] * output[:, 5]\n            # select box with highest confident\n            output = output[output[:, 4].argmax()]\n            x0 = min(max(int(output[0]), 0), ori_w)\n            y0 = min(max(int(output[1]), 0), ori_h)\n            x1 = min(max(int(output[2]), 0), ori_w)\n            y1 = min(max(int(output[3]), 0), ori_h)\n            area_pct = (x1 - x0) * (y1 - y0) / (ori_h * ori_w)\n            if area_pct >= self.area_pct_thres:\n                # xyxy, area_pct, conf\n                return [x0, y0, x1, y1], area_pct, output[4]\n\n        # if YOLOX fail, try Otsu thresholding + find contours\n        xyxy, area_pct, _ = extract_roi_otsu(\n            resized_img.to(torch.uint8).cpu().numpy())\n        # if both fail, use full frame\n        if xyxy is not None:\n            if area_pct >= self.area_pct_thres:\n                print('ROI detection: using Otsu.')\n                x0, y0, x1, y1 = xyxy\n                x0 = min(max(int(x0 / ratio), 0), ori_w)\n                y0 = min(max(int(y0 / ratio), 0), ori_h)\n                x1 = min(max(int(x1 / ratio), 0), ori_w)\n                y1 = min(max(int(y1 / ratio), 0), ori_h)\n                return [x0, y0, x1, y1], area_pct, None\n        print('ROI detection: both fail.')\n        return None, area_pct, None","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import roi_extract\nimportlib.reload(roi_extract)\nimport roi_extract\n\n# global vars\nJ2K_SUID = '1.2.840.10008.1.2.4.90'\nJ2K_HEADER = b\"\\x00\\x00\\x00\\x0C\"\nJLL_SUID = '1.2.840.10008.1.2.4.70'\nJLL_HEADER = b\"\\xff\\xd8\\xff\\xe0\"\nSUID2HEADER = {J2K_SUID: J2K_HEADER, JLL_SUID: JLL_HEADER}\nVOILUT_FUNCS_MAP = {'LINEAR': 0, 'LINEAR_EXACT': 1, 'SIGMOID': 2}\nVOILUT_FUNCS_INV_MAP = {v: k for k, v in VOILUT_FUNCS_MAP.items()}","metadata":{"execution":{"iopub.status.busy":"2026-05-07T13:01:23.613171Z","iopub.execute_input":"2026-05-07T13:01:23.613553Z","iopub.status.idle":"2026-05-07T13:01:23.62296Z","shell.execute_reply.started":"2026-05-07T13:01:23.613525Z","shell.execute_reply":"2026-05-07T13:01:23.6215Z"},"trusted":true},"outputs":[{"traceback":["Traceback \u001b[0;36m(most recent call last)\u001b[0m:\n","  File \u001b[1;32m\"/opt/conda/lib/python3.7/site-packages/IPython/core/interactiveshell.py\"\u001b[0m, line \u001b[1;32m3552\u001b[0m, in \u001b[1;35mrun_code\u001b[0m\n    exec(code_obj, self.user_global_ns, self.user_ns)\n","\u001b[0;36m  File \u001b[0;32m\"/tmp/ipykernel_30/58544378.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0;36m, in \u001b[0;35m<module>\u001b[0;36m\u001b[0m\n\u001b[0;31m    import roi_extract\u001b[0m\n","\u001b[0;36m  File \u001b[0;32m\"/kaggle/working/roi_extract.py\"\u001b[0;36m, line \u001b[0;32m13\u001b[0m\n\u001b[0;31m    !pip install /kaggle/input/kaggle-rsna-pkgs/pylibjpeg-1.4.0-py3-none-any.whl\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"],"ename":"SyntaxError","evalue":"invalid syntax (roi_extract.py, line 13)","output_type":"error"}],"execution_count":35},{"cell_type":"code","source":"BATCH_SIZE = 2\n# binarization threshold for classification\nTHRES = 0.31\nAUTO_THRES = False\nAUTO_THRES_PERCENTILE = 0.97935\n\n# classification model\nUSE_TRT = True\n\n\n# roi detection\nROI_YOLOX_INPUT_SIZE = [416, 416]\nROI_YOLOX_CONF_THRES = 0.5\nROI_YOLOX_NMS_THRES = 0.9\nROI_YOLOX_HW = [(52, 52), (26, 26), (13, 13)]\nROI_YOLOX_STRIDES = [8, 16, 32]\nROI_AREA_PCT_THRES = 0.04\n\n# model\nMODEL_INPUT_SIZE = [2048, 1024]\n\nMODE = 'KAGGLE-TEST'\nassert MODE in ['LOCAL-VAL', 'KAGGLE-VAL', 'KAGGLE-TEST']\n\n# settings corresponding to each mode\nif MODE == 'KAGGLE-VAL':\n    TRT_MODEL_PATH = '/kaggle/input/rsna-breast-cancer-detection-best-ckpts/best_convnext_ensemble_batch2_fp32_torch2trt.engine'\n    TORCH_MODEL_CKPT_PATHS = [\n        f'/kaggle/input/rsna-breast-cancer-detection-best-ckpts/best_convnext_fold_{i}.pth.tar'\n        for i in range(4)\n    ]\n    ROI_YOLOX_ENGINE_PATH = '/kaggle/input/rsna-breast-cancer-detection-best-ckpts/yolox_nano_416_roi_trt_p100.pth'\n    CSV_PATH = '/kaggle/input/rsna-breast-cancer-detection-best-ckpts/_val_fold_0.csv'\n    DCM_ROOT_DIR = '/kaggle/input/rsna-breast-cancer-detection/train_images'\n    SAVE_IMG_ROOT_DIR = '/kaggle/tmp/pngs'\n    N_CHUNKS = 2\n    N_CPUS = 2\n    RM_DONE_CHUNK = False\nelif MODE == 'KAGGLE-TEST':\n    TRT_MODEL_PATH = '/kaggle/input/rsna-breast-cancer-detection-best-ckpts/best_convnext_ensemble_batch2_fp32_torch2trt.engine'\n    TORCH_MODEL_CKPT_PATHS = [\n        f'/kaggle/input/rsna-breast-cancer-detection-best-ckpts/best_convnext_fold_{i}.pth.tar'\n        for i in range(4)\n    ]\n    ROI_YOLOX_ENGINE_PATH = '/kaggle/input/rsna-breast-cancer-detection-best-ckpts/yolox_nano_416_roi_trt_p100.pth'\n    CSV_PATH = '/kaggle/input/rsna-breast-cancer-detection/test.csv'\n    DCM_ROOT_DIR = '/kaggle/input/rsna-breast-cancer-detection/test_images'\n    SAVE_IMG_ROOT_DIR = '/kaggle/tmp/pngs'\n    N_CHUNKS = 2\n    N_CPUS = 2\n    RM_DONE_CHUNK = True\nelif MODE == 'LOCAL-VAL':\n    TRT_MODEL_PATH = './assets/best_convnext_ensemble_batch2_fp32_torch2trt.engine'\n    TORCH_MODEL_CKPT_PATHS = [\n        f'./assets/best_convnext_fold_{i}.pth.tar'\n        for i in range(4)\n    ]\n    ROI_YOLOX_ENGINE_PATH = '../roi_det/YOLOX/YOLOX_outputs/yolox_nano_bre_416/model_trt.pth'\n    CSV_PATH = '../../datasets/cv/v1/val_fold_0.csv'\n    DCM_ROOT_DIR = '../../datasets/train_images/'\n    SAVE_IMG_ROOT_DIR = './temp_save'\n    N_CHUNKS = 2\n    N_CPUS = 2\n    RM_DONE_CHUNK = False","metadata":{"execution":{"iopub.status.busy":"2026-05-07T11:59:27.828413Z","iopub.execute_input":"2026-05-07T11:59:27.829477Z","iopub.status.idle":"2026-05-07T11:59:27.840042Z","shell.execute_reply.started":"2026-05-07T11:59:27.829436Z","shell.execute_reply":"2026-05-07T11:59:27.838912Z"},"trusted":true},"outputs":[],"execution_count":8},{"cell_type":"code","source":"class PydicomMetadata:\n\n    def __init__(self, ds):\n        if \"WindowWidth\" not in ds or \"WindowCenter\" not in ds:\n            self.window_widths = []\n            self.window_centers = []\n        else:\n            ww = ds['WindowWidth']\n            wc = ds['WindowCenter']\n            self.window_widths = [float(e) for e in ww\n                                  ] if ww.VM > 1 else [float(ww.value)]\n\n            self.window_centers = [float(e) for e in wc\n                                   ] if wc.VM > 1 else [float(wc.value)]\n\n        # if nan --> LINEAR\n        self.voilut_func = str(ds.get('VOILUTFunction', 'LINEAR')).upper()\n        self.invert = (ds.PhotometricInterpretation == 'MONOCHROME1')\n        assert len(self.window_widths) == len(self.window_centers)\n\n\nclass DicomsdlMetadata:\n\n    def __init__(self, ds):\n        self.window_widths = ds.WindowWidth\n        self.window_centers = ds.WindowCenter\n        if self.window_widths is None or self.window_centers is None:\n            self.window_widths = []\n            self.window_centers = []\n        else:\n            try:\n                if not isinstance(self.window_widths, list):\n                    self.window_widths = [self.window_widths]\n                self.window_widths = [float(e) for e in self.window_widths]\n                if not isinstance(self.window_centers, list):\n                    self.window_centers = [self.window_centers]\n                self.window_centers = [float(e) for e in self.window_centers]\n            except:\n                self.window_widths = []\n                self.window_centers = []\n\n        # if nan --> LINEAR\n        self.voilut_func = ds.VOILUTFunction\n        if self.voilut_func is None:\n            self.voilut_func = 'LINEAR'\n        else:\n            self.voilut_func = str(self.voilut_func).upper()\n        self.invert = (ds.PhotometricInterpretation == 'MONOCHROME1')\n        assert len(self.window_widths) == len(self.window_centers)","metadata":{"execution":{"iopub.status.busy":"2026-05-07T11:59:32.076543Z","iopub.execute_input":"2026-05-07T11:59:32.077071Z","iopub.status.idle":"2026-05-07T11:59:32.088343Z","shell.execute_reply.started":"2026-05-07T11:59:32.077034Z","shell.execute_reply":"2026-05-07T11:59:32.087113Z"},"trusted":true},"outputs":[],"execution_count":9},{"cell_type":"code","source":"# slow\n# from pydicom's source\ndef _apply_windowing_np_v1(arr,\n                           window_width=None,\n                           window_center=None,\n                           voi_func='LINEAR',\n                           y_min=0,\n                           y_max=255):\n    assert window_width > 0\n    y_range = y_max - y_min\n    # float64 needed (default) or just float32 ?\n    # arr = arr.astype(np.float64)\n    arr = arr.astype(np.float32)\n\n    if voi_func in ['LINEAR', 'LINEAR_EXACT']:\n        # PS3.3 C.11.2.1.2.1 and C.11.2.1.3.2\n        if voi_func == 'LINEAR':\n            if window_width < 1:\n                raise ValueError(\n                    \"The (0028,1051) Window Width must be greater than or \"\n                    \"equal to 1 for a 'LINEAR' windowing operation\")\n            window_center -= 0.5\n            window_width -= 1\n        below = arr <= (window_center - window_width / 2)\n        above = arr > (window_center + window_width / 2)\n        between = np.logical_and(~below, ~above)\n\n        arr[below] = y_min\n        arr[above] = y_max\n        if between.any():\n            arr[between] = ((\n                (arr[between] - window_center) / window_width + 0.5) * y_range\n                            + y_min)\n    elif voi_func == 'SIGMOID':\n        arr = y_range / (1 +\n                         np.exp(-4 *\n                                (arr - window_center) / window_width)) + y_min\n    else:\n        raise ValueError(\n            f\"Unsupported (0028,1056) VOI LUT Function value '{voi_func}'\")\n    return arr\n\n\ndef _apply_windowing_np_v2(arr,\n                           window_width=None,\n                           window_center=None,\n                           voi_func='LINEAR',\n                           y_min=0,\n                           y_max=255):\n    assert window_width > 0\n    y_range = y_max - y_min\n    # float64 needed (default) or just float32 ?\n    # arr = arr.astype(np.float64)\n    arr = arr.astype(np.float32)\n\n    if voi_func == 'LINEAR' or voi_func == 'LINEAR_EXACT':\n        # PS3.3 C.11.2.1.2.1 and C.11.2.1.3.2\n        if voi_func == 'LINEAR':\n            if window_width < 1:\n                raise ValueError(\n                    \"The (0028,1051) Window Width must be greater than or \"\n                    \"equal to 1 for a 'LINEAR' windowing operation\")\n            window_center -= 0.5\n            window_width -= 1\n\n        # simple trick to improve speed\n        s = y_range / window_width\n        b = (-window_center / window_width + 0.5) * y_range + y_min\n        arr = arr * s + b\n        arr = np.clip(arr, y_min, y_max)\n\n    elif voi_func == 'SIGMOID':\n        # simple trick to improve speed\n        s = -4 / window_width\n        arr = y_range / (1 + np.exp((arr - window_center) * s)) + y_min\n    else:\n        raise ValueError(\n            f\"Unsupported (0028,1056) VOI LUT Function value '{voi_func}'\")\n    return arr\n\n\ndef _apply_windowing_torch(arr,\n                           window_width=None,\n                           window_center=None,\n                           voi_func='LINEAR',\n                           y_min=0,\n                           y_max=255):\n    assert window_width > 0\n    y_range = y_max - y_min\n    # float64 needed (default) or just float32 ?\n    # arr = arr.double()\n    arr = arr.float()\n\n    if voi_func == 'LINEAR' or voi_func == 'LINEAR_EXACT':\n        # PS3.3 C.11.2.1.2.1 and C.11.2.1.3.2\n        if voi_func == 'LINEAR':\n            if window_width < 1:\n                raise ValueError(\n                    \"The (0028,1051) Window Width must be greater than or \"\n                    \"equal to 1 for a 'LINEAR' windowing operation\")\n            window_center -= 0.5\n            window_width -= 1\n\n        # simple trick to improve speed\n        s = y_range / window_width\n        b = (-window_center / window_width + 0.5) * y_range + y_min\n        arr = arr * s + b\n        arr = torch.clamp(arr, y_min, y_max)\n\n    elif voi_func == 'SIGMOID':\n        # simple trick to improve speed\n        s = -4 / window_width\n        arr = y_range / (1 + torch.exp((arr - window_center) * s)) + y_min\n    else:\n        raise ValueError(\n            f\"Unsupported (0028,1056) VOI LUT Function value '{voi_func}'\")\n    return arr\n\n\ndef apply_windowing(arr,\n                    window_width=None,\n                    window_center=None,\n                    voi_func='LINEAR',\n                    y_min=0,\n                    y_max=255,\n                    backend='np_v2'):\n    if backend == 'torch':\n        if isinstance(arr, torch.Tensor):\n            pass\n        elif isinstance(arr, np.ndarray):\n            if arr.dtype == np.uint16:\n                arr = torch.from_numpy(arr, torch.int16)\n            else:\n                arr = torch.from_numpy(arr)\n\n    if backend == 'np_v1':\n        windowing_func = _apply_windowing_np_v1\n    elif backend == 'np_v2':\n        windowing_func = _apply_windowing_np_v2\n    elif backend == 'torch':\n        windowing_func = _apply_windowing_torch\n    else:\n        raise ValueError(\n            f'Invalid backend {backend}, must be one of [\"np\", \"np_v2\", \"torch\"]'\n        )\n\n    arr = windowing_func(arr,\n                         window_width=window_width,\n                         window_center=window_center,\n                         voi_func=voi_func,\n                         y_min=y_min,\n                         y_max=y_max)\n    return arr","metadata":{"execution":{"iopub.status.busy":"2026-05-07T12:34:06.548548Z","iopub.execute_input":"2026-05-07T12:34:06.549465Z","iopub.status.idle":"2026-05-07T12:34:06.571656Z","shell.execute_reply.started":"2026-05-07T12:34:06.549427Z","shell.execute_reply":"2026-05-07T12:34:06.570251Z"},"trusted":true},"outputs":[],"execution_count":17},{"cell_type":"code","source":"def min_max_scale(img):\n    maxv = img.max()\n    minv = img.min()\n    if maxv > minv:\n        return (img - minv) / (maxv - minv)\n    else:\n        return img - minv  # ==0\n\n\n# this version is not correctly implemented, but used in the winning submission\ndef percentile_min_max_scale(img, pct=99):\n    if isinstance(img, np.ndarray):\n        maxv = np.percentile(img, pct) - 1\n        minv = img.min()\n        assert maxv >= minv\n        if maxv > minv:\n            ret = (img - minv) / (maxv - minv)\n        else:\n            ret = img - minv  # ==0\n        ret = np.clip(ret, 0, 1)\n    elif isinstance(img, torch.Tensor):\n        maxv = torch.quantile(img, pct / 100) - 1\n        minv = img.min()\n        assert maxv >= minv\n        if maxv > minv:\n            ret = (img - minv) / (maxv - minv)\n        else:\n            ret = img - minv  # ==0\n        ret = torch.clamp(ret, 0, 1)\n    else:\n        raise ValueError(\n            'Invalid img type, should be numpy array or torch.Tensor')\n    return ret","metadata":{"execution":{"iopub.status.busy":"2026-05-07T12:01:16.961001Z","iopub.execute_input":"2026-05-07T12:01:16.96199Z","iopub.status.idle":"2026-05-07T12:01:16.971374Z","shell.execute_reply.started":"2026-05-07T12:01:16.961951Z","shell.execute_reply":"2026-05-07T12:01:16.97022Z"},"trusted":true},"outputs":[],"execution_count":11},{"cell_type":"code","source":"# MAIN - Test YOLOX + Otsu + Visualize\nglobal_df = pd.read_csv(CSV_PATH)[:10]  \n\ndf = global_df.copy()\ndcm_paths = []\nsave_paths = []\n\nfor i in range(len(df)):\n    patient_id = df.at[i, 'patient_id']\n    image_id = df.at[i, 'image_id']\n    dcm_path = os.path.join(DCM_ROOT_DIR, str(patient_id), f'{image_id}.dcm')\n    save_path = os.path.join(SAVE_IMG_ROOT_DIR, f'{patient_id}@{image_id}.png')\n    dcm_paths.append(dcm_path)\n    save_paths.append(save_path)\n\nprint(f\"Total images: {len(dcm_paths)}\")\nos.makedirs(SAVE_IMG_ROOT_DIR, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2026-05-07T12:32:24.821911Z","iopub.execute_input":"2026-05-07T12:32:24.822905Z","iopub.status.idle":"2026-05-07T12:32:24.84098Z","shell.execute_reply.started":"2026-05-07T12:32:24.82286Z","shell.execute_reply":"2026-05-07T12:32:24.83993Z"},"trusted":true},"outputs":[{"name":"stdout","text":"Total images: 4\n","output_type":"stream"}],"execution_count":14},{"cell_type":"code","source":"import sys\n\n# مسیرهای احتمالی torch2trt\nsys.path.append('/kaggle/input/rsna-breast-cancer-detection-best-ckpts')\nsys.path.append('/kaggle/tmp/libs/')\n\n# حالا import کن\nimport roi_extract\nimport importlib\nimportlib.reload(roi_extract)\n\nprint(\"✅ roi_extract loaded!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:47:21.34121Z","iopub.execute_input":"2026-05-07T12:47:21.34197Z","iopub.status.idle":"2026-05-07T12:47:21.370626Z","shell.execute_reply.started":"2026-05-07T12:47:21.341927Z","shell.execute_reply":"2026-05-07T12:47:21.369499Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_30/2443146742.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;31m# حالا import کن\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mroi_extract\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroi_extract\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/working/roi_extract.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     24\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/tmp/libs/'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTRTModule\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     26\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfunctional\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'torch2trt'"],"ename":"ModuleNotFoundError","evalue":"No module named 'torch2trt'","output_type":"error"}],"execution_count":26},{"cell_type":"code","source":"!find /kaggle/input -name \"*torch2trt*\" -type d\n!ls /kaggle/input/rsna-breast-cancer-detection-best-ckpts/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:54:26.220405Z","iopub.execute_input":"2026-05-07T12:54:26.220661Z","iopub.status.idle":"2026-05-07T12:54:50.81084Z","shell.execute_reply.started":"2026-05-07T12:54:26.220628Z","shell.execute_reply":"2026-05-07T12:54:50.809414Z"}},"outputs":[{"name":"stdout","text":"/kaggle/input/kaggle-rsna-pkgs/torch2trt\n/kaggle/input/kaggle-rsna-pkgs/torch2trt/torch2trt\n_val_fold_0.csv\nbest_convnext_ensemble_batch2_fp32_torch2trt.engine\nbest_convnext_fold_0.pth.tar\nbest_convnext_fold_1.pth.tar\nbest_convnext_fold_2.pth.tar\nbest_convnext_fold_3.pth.tar\nyolox_nano_416_roi_torch.pth\nyolox_nano_416_roi_trt_a100.pth\nyolox_nano_416_roi_trt_p100.pth\n","output_type":"stream"}],"execution_count":32},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\n%%writefile roi_extract.py\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport os, gc, pydicom\ntry:\n    import dicomsdl\nexcept:\n    os.system(\"pip install /kaggle/input/kaggle-rsna-pkgs/*dicomsdl*.whl --no-deps -q\")\n\nimport sys\nimport cv2\nimport numpy as np\nimport torch\nfrom torch.nn import functional as F\nfrom tqdm import tqdm\n\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\nfrom torch2trt import TRTModule  \n\nprint(\"roi_extract.py rewritten\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:56:43.777636Z","iopub.execute_input":"2026-05-07T12:56:43.778477Z","iopub.status.idle":"2026-05-07T12:56:43.787164Z","shell.execute_reply.started":"2026-05-07T12:56:43.77842Z","shell.execute_reply":"2026-05-07T12:56:43.785815Z"}},"outputs":[{"name":"stderr","text":"UsageError: Line magic function `%%writefile` not found.\n","output_type":"stream"}],"execution_count":33},{"cell_type":"code","source":"%%writefile roi_extract.py\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport os, gc, pydicom\ntry:\n    import dicomsdl\nexcept:\n    os.system(\"pip install /kaggle/input/kaggle-rsna-pkgs/*dicomsdl*.whl --no-deps -q\")\n\nimport sys\nimport cv2\nimport numpy as np\nimport torch\nfrom torch.nn import functional as F\n\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\nfrom torch2trt import TRTModule\n\n# بقیه کد اصلی roi_extract (از def meshgrid تا آخر) رو اینجا paste کن","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import sys\n\n# اضافه کردن مسیر درست torch2trt\nsys.path.append('/kaggle/input/kaggle-rsna-pkgs/torch2trt')\n\nimport roi_extract\nimport importlib\nimportlib.reload(roi_extract)\n\nprint(\"✅ roi_extract loaded successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:48:18.711477Z","iopub.execute_input":"2026-05-07T12:48:18.711877Z","iopub.status.idle":"2026-05-07T12:48:18.742245Z","shell.execute_reply.started":"2026-05-07T12:48:18.711846Z","shell.execute_reply":"2026-05-07T12:48:18.74107Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_30/882100104.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/input/kaggle-rsna-pkgs/torch2trt'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mroi_extract\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroi_extract\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/working/roi_extract.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     24\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/tmp/libs/'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTRTModule\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     26\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfunctional\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/input/kaggle-rsna-pkgs/torch2trt/torch2trt/__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mconverters\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtensorrt\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtrt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mload_plugins\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/input/kaggle-rsna-pkgs/torch2trt/torch2trt/torch2trt.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mtensorrt\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtrt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      3\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mio\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'tensorrt'"],"ename":"ModuleNotFoundError","evalue":"No module named 'tensorrt'","output_type":"error"}],"execution_count":29},{"cell_type":"code","source":"import sys\n# sys.path.append('/kaggle/input/rsna-breast-cancer-detection-best-ckpts/torch2trt_p100')\n# یا این مسیر رو امتحان کن\nsys.path.append('/kaggle/tmp/libs/')\n\nimport roi_extract\nimport importlib\nimportlib.reload(roi_extract)\n\nprint(\"roi_extract loaded successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:43:54.359617Z","iopub.execute_input":"2026-05-07T12:43:54.360595Z","iopub.status.idle":"2026-05-07T12:43:54.381949Z","shell.execute_reply.started":"2026-05-07T12:43:54.360552Z","shell.execute_reply":"2026-05-07T12:43:54.380539Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_30/3349420969.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/tmp/libs/'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mroi_extract\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroi_extract\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/working/roi_extract.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     24\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/tmp/libs/'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTRTModule\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     26\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfunctional\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'torch2trt'"],"ename":"ModuleNotFoundError","evalue":"No module named 'torch2trt'","output_type":"error"}],"execution_count":23},{"cell_type":"code","source":"import roi_extract\nimportlib.reload(roi_extract) \n\nroi_extractor = roi_extract.RoiExtractor(\n    engine_path=ROI_YOLOX_ENGINE_PATH,\n    input_size=ROI_YOLOX_INPUT_SIZE,\n    num_classes=1,\n    conf_thres=ROI_YOLOX_CONF_THRES,\n    nms_thres=ROI_YOLOX_NMS_THRES,\n    area_pct_thres=ROI_AREA_PCT_THRES,\n    hw=ROI_YOLOX_HW,\n    strides=ROI_YOLOX_STRIDES\n)\n\nimport matplotlib.pyplot as plt\n\nroi_extractor = roi_extract.RoiExtractor(\n    engine_path=ROI_YOLOX_ENGINE_PATH,\n    input_size=ROI_YOLOX_INPUT_SIZE,\n    num_classes=1,\n    conf_thres=ROI_YOLOX_CONF_THRES,\n    nms_thres=ROI_YOLOX_NMS_THRES,\n    area_pct_thres=ROI_AREA_PCT_THRES,\n    hw=ROI_YOLOX_HW,\n    strides=ROI_YOLOX_STRIDES\n)\n\n# تست روی ۴ تصویر\nfor dcm_path in dcm_paths[:4]:\n    dcm = dicomsdl.open(dcm_path)\n    info = dcm.getPixelDataInfo()\n    img = np.empty([info['Rows'], info['Cols']], dtype=info['dtype'])\n    dcm.copyFrameData(0, img)\n    \n    img_t = torch.from_numpy(img.astype(np.int16)).cuda()\n    img_yolox = min_max_scale(img_t) * 255\n    if dcm.PhotometricInterpretation == 'MONOCHROME1':\n        img_yolox = 255 - img_yolox\n    \n    xyxy, area_pct, conf = roi_extractor.detect_single(img_yolox)\n    \n    # visualize\n    plt.figure(figsize=(8,8))\n    plt.imshow(img, cmap='gray')\n    if xyxy is not None:\n        x0,y0,x1,y1 = xyxy\n        plt.gca().add_patch(plt.Rectangle((x0,y0), x1-x0, y1-y0, \n                                        fill=False, edgecolor='red', lw=3))\n        plt.title(f'Otsu/YOLOX - Area: {area_pct:.3f}')\n    else:\n        plt.title('Full image (no ROI)')\n    plt.axis('off')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-07T12:42:48.374615Z","iopub.execute_input":"2026-05-07T12:42:48.37561Z","iopub.status.idle":"2026-05-07T12:42:48.608072Z","shell.execute_reply.started":"2026-05-07T12:42:48.375571Z","shell.execute_reply":"2026-05-07T12:42:48.60686Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_30/4278956693.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mroi_extract\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0mimportlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreload\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroi_extract\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m roi_extractor = roi_extract.RoiExtractor(\n\u001b[1;32m      5\u001b[0m     \u001b[0mengine_path\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mROI_YOLOX_ENGINE_PATH\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/working/roi_extract.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     24\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/tmp/libs/'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 25\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch2trt\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mTRTModule\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     26\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mfunctional\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'torch2trt'"],"ename":"ModuleNotFoundError","evalue":"No module named 'torch2trt'","output_type":"error"}],"execution_count":21}]}