{"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":"gpu","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30747,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install --quiet git+https://github.com/facebookresearch/segment-anything-2/","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-08-17T13:53:24.046454Z","iopub.execute_input":"2024-08-17T13:53:24.047242Z","iopub.status.idle":"2024-08-17T13:58:52.627667Z","shell.execute_reply.started":"2024-08-17T13:53:24.047207Z","shell.execute_reply":"2024-08-17T13:58:52.626599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pathlib import Path\n\nimport numpy as np\nfrom PIL import Image\nimport pandas as pd\nimport pydicom\nimport matplotlib.pyplot as plt\n\nfrom sam2.sam2_image_predictor import SAM2ImagePredictor","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:14:30.388098Z","iopub.execute_input":"2024-08-17T14:14:30.389005Z","iopub.status.idle":"2024-08-17T14:14:30.393531Z","shell.execute_reply.started":"2024-08-17T14:14:30.388968Z","shell.execute_reply":"2024-08-17T14:14:30.392678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_DIR = Path(\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification\")\nIMG_DIR = DATA_DIR / \"train_images\"\nCOOR_PATH = DATA_DIR / \"train_label_coordinates.csv\"","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:36.074613Z","iopub.execute_input":"2024-08-17T14:20:36.075359Z","iopub.status.idle":"2024-08-17T14:20:36.079749Z","shell.execute_reply.started":"2024-08-17T14:20:36.075326Z","shell.execute_reply":"2024-08-17T14:20:36.078910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(COOR_PATH)\ndf = df.set_index([\"study_id\", \"series_id\", \"instance_number\"])[[\"x\", \"y\", \"condition\"]]\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:36.909165Z","iopub.execute_input":"2024-08-17T14:20:36.909907Z","iopub.status.idle":"2024-08-17T14:20:36.988976Z","shell.execute_reply.started":"2024-08-17T14:20:36.909875Z","shell.execute_reply":"2024-08-17T14:20:36.988078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df[df[\"condition\"].str.contains(\"Spinal\")]","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:37.821338Z","iopub.execute_input":"2024-08-17T14:20:37.821949Z","iopub.status.idle":"2024-08-17T14:20:37.851808Z","shell.execute_reply.started":"2024-08-17T14:20:37.821917Z","shell.execute_reply":"2024-08-17T14:20:37.850754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_img_path(study_id, series_id, instance_number):\n    img_path = IMG_DIR / str(study_id) / str(series_id) / f\"{instance_number}.dcm\"\n    return img_path\n\n\ndef load_dcm_img(path: Path) -> np.ndarray:\n    dicom = pydicom.read_file(path)\n    img: np.ndarray = dicom.pixel_array\n    img = img.clip(np.percentile(img, 1), np.percentile(img, 99))\n    img = img - np.min(img)\n    img = img / np.max(img)\n    img = (img * 255).astype(np.uint8)\n    return img\n\n\n# https://github.com/facebookresearch/segment-anything-2/blob/main/notebooks/image_predictor_example.ipynb\ndef show_mask(mask, ax):\n    color = np.array([30/255, 144/255, 255/255, 0.6])\n    h, w = mask.shape[-2:]\n    mask = mask.astype(np.uint8)\n    mask_image =  mask.reshape(h, w, 1) * color.reshape(1, 1, -1)\n    ax.imshow(mask_image)\n\n    \ndef show_points(coords, labels, ax, marker_size=375):\n    pos_points = coords[labels==1]\n    neg_points = coords[labels==0]\n    ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white', linewidth=1.25)\n    ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white', linewidth=1.25)   ","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:40.974534Z","iopub.execute_input":"2024-08-17T14:20:40.974903Z","iopub.status.idle":"2024-08-17T14:20:40.987315Z","shell.execute_reply.started":"2024-08-17T14:20:40.974873Z","shell.execute_reply":"2024-08-17T14:20:40.986346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor = SAM2ImagePredictor.from_pretrained(\"facebook/sam2-hiera-large\")","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:41.984894Z","iopub.execute_input":"2024-08-17T14:20:41.985249Z","iopub.status.idle":"2024-08-17T14:20:45.162734Z","shell.execute_reply.started":"2024-08-17T14:20:41.985221Z","shell.execute_reply":"2024-08-17T14:20:45.161645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for (study_id, series_id, instance_number), chunk in df.groupby(level=[0, 1, 2])[[\"x\", \"y\"]]:\n    \n    img_path = get_img_path(study_id, series_id, instance_number)\n    img = load_dcm_img(img_path)\n    img = img[..., None].repeat(3, -1)\n    \n    input_points = chunk.values\n    input_labels = np.ones((input_points.shape[0], ))\n    \n    predictor.set_image(img)\n    \n    masks, scores, logits = predictor.predict(\n        point_coords=input_points,\n        point_labels=input_labels,\n        multimask_output=False,\n    )\n    \n    # you can try more images in this loop\n    break","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:49.479485Z","iopub.execute_input":"2024-08-17T14:20:49.479950Z","iopub.status.idle":"2024-08-17T14:20:49.949522Z","shell.execute_reply.started":"2024-08-17T14:20:49.479918Z","shell.execute_reply":"2024-08-17T14:20:49.948770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 10))\n\nax1.imshow(img)\nshow_points(input_points, input_labels, ax1)\nax1.axis(\"off\")\n\nax2.imshow(img)\nshow_mask(masks,ax2)\nax2.axis(\"off\")\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-08-17T14:20:50.850676Z","iopub.execute_input":"2024-08-17T14:20:50.851510Z","iopub.status.idle":"2024-08-17T14:20:51.232770Z","shell.execute_reply.started":"2024-08-17T14:20:50.851476Z","shell.execute_reply":"2024-08-17T14:20:51.231874Z"},"trusted":true},"execution_count":null,"outputs":[]}]}