{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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":30762,"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-09-11T10:12:18.192415Z","iopub.execute_input":"2024-09-11T10:12:18.193360Z","iopub.status.idle":"2024-09-11T10:16:08.514871Z","shell.execute_reply.started":"2024-09-11T10:12:18.193312Z","shell.execute_reply":"2024-09-11T10:16:08.513426Z"},"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\n\nimport torch\nimport cv2\nimport os\nfrom sam2.build_sam import build_sam2","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:16:08.517426Z","iopub.execute_input":"2024-09-11T10:16:08.517813Z","iopub.status.idle":"2024-09-11T10:16:14.054084Z","shell.execute_reply.started":"2024-09-11T10:16:08.517774Z","shell.execute_reply":"2024-09-11T10:16:14.053238Z"},"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-09-11T10:16:14.055384Z","iopub.execute_input":"2024-09-11T10:16:14.056062Z","iopub.status.idle":"2024-09-11T10:16:14.061309Z","shell.execute_reply.started":"2024-09-11T10:16:14.055965Z","shell.execute_reply":"2024-09-11T10:16:14.060316Z"},"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(20)","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:16:14.063259Z","iopub.execute_input":"2024-09-11T10:16:14.063571Z","iopub.status.idle":"2024-09-11T10:16:14.220937Z","shell.execute_reply.started":"2024-09-11T10:16:14.063535Z","shell.execute_reply":"2024-09-11T10:16:14.220067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df = df[df[\"condition\"].str.contains(\"Spinal\")]","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:16:14.221972Z","iopub.execute_input":"2024-09-11T10:16:14.222249Z","iopub.status.idle":"2024-09-11T10:16:14.226188Z","shell.execute_reply.started":"2024-09-11T10:16:14.222219Z","shell.execute_reply":"2024-09-11T10:16:14.225230Z"},"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-09-11T10:16:14.227337Z","iopub.execute_input":"2024-09-11T10:16:14.227673Z","iopub.status.idle":"2024-09-11T10:16:14.238482Z","shell.execute_reply.started":"2024-09-11T10:16:14.227639Z","shell.execute_reply":"2024-09-11T10:16:14.237553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor = SAM2ImagePredictor.from_pretrained(\"facebook/sam2-hiera-large\")","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:16:14.239589Z","iopub.execute_input":"2024-09-11T10:16:14.239947Z","iopub.status.idle":"2024-09-11T10:16:49.967599Z","shell.execute_reply.started":"2024-09-11T10:16:14.239904Z","shell.execute_reply":"2024-09-11T10:16:49.966787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os \n\nimport albumentations as A\nscores_list = []\nscore_dict = {}\ni=0\nfor (study_id, series_id, instance_number), chunk in df.groupby(level=[0, 1, 2])[[\"x\", \"y\"]]:\n    i+=1\n    if i%100==0:\n        print(i)\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    input_points = chunk.values\n    input_labels = np.ones((input_points.shape[0], ))\n    \n    predictor.set_image(img)\n    masks, scores, logits = predictor.predict(\n        point_coords=input_points,\n        point_labels=input_labels,\n        multimask_output=False\n    )\n    if scores>0.25:\n        path = os.path.join('/kaggle/working/mask_result/',str(study_id),str(series_id))\n        if not os.path.exists(path):\n            os.makedirs(path)\n        np.save(os.path.join(path,str(instance_number)+'.npy'), masks)\n        score_dict[path] = str(scores[0])\n        scores_list.append(scores)\n#     if scores>0.25:\n#         fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 10))\n#         ax1.imshow(img)\n#         show_points(input_points, input_labels, ax1)\n#         ax1.axis(\"off\")\n\n#         ax2.imshow(masks.squeeze())\n#         ax2.axis(\"off\")\n#         scores_list.append(scores)\n#     if i>100: break\nprint(np.mean(scores_list))\nprint(len(scores_list))\n","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:47:48.902131Z","iopub.execute_input":"2024-09-11T10:47:48.902562Z","iopub.status.idle":"2024-09-11T10:47:53.704221Z","shell.execute_reply.started":"2024-09-11T10:47:48.902521Z","shell.execute_reply":"2024-09-11T10:47:53.702956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\nscore_dict = json.dumps(score_dict, indent=4)\n\n# 将 JSON 字符串写入文件\nwith open('/kaggle/working/mask_scores.json', 'w') as json_file:\n    json_file.write(score_dict)\n\nprint(\"数据已成功保存为 mask_scores.json 文件\")","metadata":{"execution":{"iopub.status.busy":"2024-09-11T10:45:58.787086Z","iopub.execute_input":"2024-09-11T10:45:58.787491Z","iopub.status.idle":"2024-09-11T10:45:58.793901Z","shell.execute_reply.started":"2024-09-11T10:45:58.787451Z","shell.execute_reply":"2024-09-11T10:45:58.793029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}