{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-27T14:06:15.024386Z","iopub.execute_input":"2023-04-27T14:06:15.024972Z","iopub.status.idle":"2023-04-27T14:06:15.058777Z","shell.execute_reply.started":"2023-04-27T14:06:15.024929Z","shell.execute_reply":"2023-04-27T14:06:15.057889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from zipfile import ZipFile\nfrom tqdm import tqdm\nimport cv2\nimport os\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:15.067295Z","iopub.execute_input":"2023-04-27T14:06:15.067572Z","iopub.status.idle":"2023-04-27T14:06:15.21896Z","shell.execute_reply.started":"2023-04-27T14:06:15.067545Z","shell.execute_reply":"2023-04-27T14:06:15.217863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with ZipFile(\"../input/data-science-bowl-2018/stage1_train.zip\",\"r\") as zip_ref:\n    zip_ref.extractall(\"./stage1_train\")","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:15.221142Z","iopub.execute_input":"2023-04-27T14:06:15.221514Z","iopub.status.idle":"2023-04-27T14:06:22.474901Z","shell.execute_reply.started":"2023-04-27T14:06:15.221471Z","shell.execute_reply":"2023-04-27T14:06:22.473894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_PATH = './stage1_train/'\ntrain_ids = next(os.walk(TRAIN_PATH))[1]\nimgs= []\nlabels = []\nfor file_name in tqdm(train_ids):\n    path = os.path.join(TRAIN_PATH,file_name)\n    img = cv2.imread(path + '/images/' + file_name + '.png')\n    imgs.append(img)\n    mask = None\n    for mask_file in next(os.walk(path + '/masks/'))[2]:\n        mask_ = cv2.imread(path + '/masks/' + mask_file,-1)\n        if mask is None:\n            mask = mask_\n        else:\n            mask = np.maximum(mask, mask_)  \n    labels.append(mask)\n# train_ids[:5]\n\n\n# file_name = train_ids[0]\n# path = os.path.join(TRAIN_PATH,file_name)\n# img = cv2.imread(path + '/images/' + file_name + '.png')\n\n# plt.imshow(img[...,::-1])\n# plt.imshow(mask,cmap='gray')\n","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:22.478998Z","iopub.execute_input":"2023-04-27T14:06:22.479295Z","iopub.status.idle":"2023-04-27T14:06:48.313271Z","shell.execute_reply.started":"2023-04-27T14:06:22.479267Z","shell.execute_reply":"2023-04-27T14:06:48.312147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(labels)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:48.315572Z","iopub.execute_input":"2023-04-27T14:06:48.316046Z","iopub.status.idle":"2023-04-27T14:06:48.326706Z","shell.execute_reply.started":"2023-04-27T14:06:48.316007Z","shell.execute_reply":"2023-04-27T14:06:48.325754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(imgs)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:48.328036Z","iopub.execute_input":"2023-04-27T14:06:48.328282Z","iopub.status.idle":"2023-04-27T14:06:48.338128Z","shell.execute_reply.started":"2023-04-27T14:06:48.328258Z","shell.execute_reply":"2023-04-27T14:06:48.337093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(imgs[1])\nplt.show()\nplt.imshow(labels[1],cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:06:48.339179Z","iopub.execute_input":"2023-04-27T14:06:48.339419Z","iopub.status.idle":"2023-04-27T14:06:48.820897Z","shell.execute_reply.started":"2023-04-27T14:06:48.339395Z","shell.execute_reply":"2023-04-27T14:06:48.819805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# SAM","metadata":{}},{"cell_type":"code","source":"pip install git+https://github.com/facebookresearch/segment-anything.git","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:02.93816Z","iopub.execute_input":"2023-04-27T14:08:02.939364Z","iopub.status.idle":"2023-04-27T14:08:17.275916Z","shell.execute_reply.started":"2023-04-27T14:08:02.939316Z","shell.execute_reply":"2023-04-27T14:08:17.274526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:17.2782Z","iopub.execute_input":"2023-04-27T14:08:17.278905Z","iopub.status.idle":"2023-04-27T14:08:30.815579Z","shell.execute_reply.started":"2023-04-27T14:08:17.278857Z","shell.execute_reply":"2023-04-27T14:08:30.814217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Preprocessing","metadata":{}},{"cell_type":"code","source":"img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #BGR2RGB","metadata":{"execution":{"iopub.status.busy":"2023-04-27T02:55:10.187028Z","iopub.execute_input":"2023-04-27T02:55:10.188008Z","iopub.status.idle":"2023-04-27T02:55:10.200413Z","shell.execute_reply.started":"2023-04-27T02:55:10.187961Z","shell.execute_reply":"2023-04-27T02:55:10.199406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_mask(mask, ax, random_color=False):\n    if random_color:\n        color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)\n    else:\n        color = np.array([30/255, 144/255, 255/255, 0.6])\n    h, w = mask.shape[-2:]\n    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)\n    ax.imshow(mask_image)\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)   \n    \ndef show_box(box, ax):\n    x0, y0 = box[0], box[1]\n    w, h = box[2] - box[0], box[3] - box[1]\n    ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0,0,0,0), lw=2))    ","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:36.525871Z","iopub.execute_input":"2023-04-27T14:08:36.526366Z","iopub.status.idle":"2023-04-27T14:08:36.543808Z","shell.execute_reply.started":"2023-04-27T14:08:36.526314Z","shell.execute_reply":"2023-04-27T14:08:36.542899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Initial SAM","metadata":{}},{"cell_type":"code","source":"from segment_anything import sam_model_registry, SamPredictor\n\nsam_checkpoint = \"./sam_vit_h_4b8939.pth\"\nmodel_type = \"vit_h\"\n\ndevice = \"cuda\"\n\nsam = sam_model_registry[model_type](checkpoint=sam_checkpoint) # 一个网络结构\nsam=sam.to(device=device)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:38.124843Z","iopub.execute_input":"2023-04-27T14:08:38.125777Z","iopub.status.idle":"2023-04-27T14:08:52.451442Z","shell.execute_reply.started":"2023-04-27T14:08:38.125726Z","shell.execute_reply":"2023-04-27T14:08:52.450376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Test One Image","metadata":{}},{"cell_type":"code","source":"predictor = SamPredictor(sam) ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor.set_image(imgs[1])","metadata":{"execution":{"iopub.status.busy":"2023-04-27T03:51:27.199101Z","iopub.execute_input":"2023-04-27T03:51:27.199802Z","iopub.status.idle":"2023-04-27T03:51:28.19764Z","shell.execute_reply.started":"2023-04-27T03:51:27.199763Z","shell.execute_reply":"2023-04-27T03:51:28.196564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks, scores, logits = predictor.predict()","metadata":{"execution":{"iopub.status.busy":"2023-04-27T03:51:29.148801Z","iopub.execute_input":"2023-04-27T03:51:29.149854Z","iopub.status.idle":"2023-04-27T03:51:29.165599Z","shell.execute_reply.started":"2023-04-27T03:51:29.149795Z","shell.execute_reply":"2023-04-27T03:51:29.164624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-27T03:51:29.512756Z","iopub.execute_input":"2023-04-27T03:51:29.513131Z","iopub.status.idle":"2023-04-27T03:51:29.520004Z","shell.execute_reply.started":"2023-04-27T03:51:29.513099Z","shell.execute_reply":"2023-04-27T03:51:29.518722Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, (mask, score) in enumerate(zip(masks, scores)):\n    plt.figure(figsize=(10,10))\n    plt.imshow(imgs[1])\n    show_mask(mask, plt.gca())\n    plt.title(f\"Mask {i+1}, Score: {score:.3f}\", fontsize=18)\n    plt.axis('off')\n    plt.show()  ","metadata":{"execution":{"iopub.status.busy":"2023-04-27T03:51:51.804885Z","iopub.execute_input":"2023-04-27T03:51:51.805814Z","iopub.status.idle":"2023-04-27T03:51:52.502248Z","shell.execute_reply.started":"2023-04-27T03:51:51.805762Z","shell.execute_reply":"2023-04-27T03:51:52.501286Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test as a Batch","metadata":{}},{"cell_type":"code","source":"import torch.utils.data as data\nimport torch\nfrom segment_anything.utils.transforms import ResizeLongestSide\nresize_transform = ResizeLongestSide(sam.image_encoder.img_size)\nclass Dataset(data.Dataset):\n    def __init__(self, X,Y):\n        self.X = X\n        self.Y = Y\n        self.nF = len(self.X)\n    def __len__(self):\n        return self.nF\n    def __getitem__(self, index):\n        image = self.X[index]\n        image = resize_transform.apply_image(image)\n        image = torch.as_tensor(image)\n        return image.permute(2, 0, 1).contiguous(),self.Y[index],self.X[index].shape\ndef collate_fn(batch):\n    imgs,masks,shape = zip(*batch) \n    return imgs,masks,shape \ntest_dataset = Dataset(imgs,labels)\ntest_loader = torch.utils.data.DataLoader(\n        test_dataset,\n        batch_size=2,\n        num_workers=2,\n        shuffle=True,\n        pin_memory=True,\n        drop_last=True,\n        collate_fn=collate_fn\n    )","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:57.505803Z","iopub.execute_input":"2023-04-27T14:08:57.506683Z","iopub.status.idle":"2023-04-27T14:08:57.515711Z","shell.execute_reply.started":"2023-04-27T14:08:57.506645Z","shell.execute_reply":"2023-04-27T14:08:57.514371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_output = []\ntargets = []\nfor data in tqdm(test_loader):\n    input_imgs,target,origin_shapes = data\n    batched_input = []\n    for batch_id in range(len(input_imgs)):\n        img = input_imgs[batch_id].to(device)\n        input = {\n            'image': img,\n            'original_size':origin_shapes[batch_id][:2]\n        }\n        batched_input.append(input)\n    batched_output = sam(batched_input, multimask_output=False)\n    # batch_output[b_id][\"masks\"] (N,1,origin_shape) N is category_nums\n    for output in batched_output:\n        mask_output.append(output['masks'].cpu().numpy())\n    targets.extend(target)","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:08:58.704434Z","iopub.execute_input":"2023-04-27T14:08:58.704786Z","iopub.status.idle":"2023-04-27T14:19:53.844389Z","shell.execute_reply.started":"2023-04-27T14:08:58.704753Z","shell.execute_reply":"2023-04-27T14:19:53.843164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_mask(mask_output[0][0], plt.gca(), random_color=True)\nplt.show()\nshow_mask(targets[0][None]//255, plt.gca(), random_color=True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:20:45.75792Z","iopub.execute_input":"2023-04-27T14:20:45.758956Z","iopub.status.idle":"2023-04-27T14:20:46.380792Z","shell.execute_reply.started":"2023-04-27T14:20:45.758916Z","shell.execute_reply":"2023-04-27T14:20:46.379806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### MIoU","metadata":{}},{"cell_type":"code","source":"def calculate_iou(y_true, y_pred):\n    '''Calculate Intersection over Union (IOU) for a given class'''\n    intersection = np.logical_and(y_true, y_pred)\n    union = np.logical_or(y_true, y_pred)\n    iou_score = np.sum(intersection) / np.sum(union)\n#     show_mask(intersection, plt.gca(), random_color=True)\n#     plt.show()\n#     show_mask(union, plt.gca(), random_color=True)\n#     plt.show()\n    return iou_score\n\ndef dice_score(y_true, y_pred):\n    '''Calculate Dice score for a given class'''\n    intersection = np.sum(y_true * y_pred)\n    dice_score = (2. * intersection) / (np.sum(y_true) + np.sum(y_pred))\n    return dice_score\n\ndef mean_iou_and_dice(y_true,y_pred): #[category_nums,1,w,h]\n    num_classes = y_true.shape[0]\n    iou_scores = []\n    dice_scores = []\n    for class_idx in range(num_classes):\n        y_true_class = y_true[class_idx]\n        y_pred_class = y_pred[class_idx]\n        if np.sum(y_true_class) == 0:\n            if np.sum(y_pred_class) == 0:\n                iou_scores.append(1.0)\n                dice_scores.append(1.0)\n            else:\n                iou_scores.append(0.0)\n                dice_scores.append(0.0)\n        else:\n            iou_scores.append(calculate_iou(y_true_class, y_pred_class))\n            dice_scores.append(dice_score(y_true_class, y_pred_class))\n    mean_iou_score = np.mean(iou_scores)\n    ean_dice_score = np.mean(dice_scores)\n    return mean_iou_score,ean_dice_score\n    ","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:20:17.622987Z","iopub.execute_input":"2023-04-27T14:20:17.623352Z","iopub.status.idle":"2023-04-27T14:20:17.635185Z","shell.execute_reply.started":"2023-04-27T14:20:17.62332Z","shell.execute_reply":"2023-04-27T14:20:17.634152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mIoU = []\ndice = []\nfor id in range(len(targets)):\n    _mIoU,_dice = mean_iou_and_dice(targets[id][None][None].astype(bool),~mask_output[id]) # bowl-2018 no points should do ~ operation\n    mIoU.append(_mIoU)\n    dice.append(_dice)\nprint(\"mIoU: \",round(sum(mIoU)/len(mIoU),3))\nprint(\"Dice: \",round(sum(dice)/len(dice),3))","metadata":{"execution":{"iopub.status.busy":"2023-04-27T14:21:08.94609Z","iopub.execute_input":"2023-04-27T14:21:08.946903Z","iopub.status.idle":"2023-04-27T14:21:09.759269Z","shell.execute_reply.started":"2023-04-27T14:21:08.946862Z","shell.execute_reply":"2023-04-27T14:21:09.758273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"targets[0][None][None].shape","metadata":{"execution":{"iopub.status.busy":"2023-04-27T13:08:19.317362Z","iopub.execute_input":"2023-04-27T13:08:19.317864Z","iopub.status.idle":"2023-04-27T13:08:19.330808Z","shell.execute_reply.started":"2023-04-27T13:08:19.317828Z","shell.execute_reply":"2023-04-27T13:08:19.328788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 释放显存","metadata":{}},{"cell_type":"code","source":"import IPython\nimport os\n\ndef memory_footprint():\n    '''Return memory footprint in GB.'''\n    mem_bytes = os.popen('nvidia-smi --query-gpu=memory.used --format=csv,nounits,noheader').read()\n    mem_usage = [int(x) for x in mem_bytes.strip().split('\\n')]\n    return sum(mem_usage) / 1024**2\n\ndef release_gpu_memory():\n    IPython.display.clear_output(wait=True)\n    print(f'GPU memory footprint: {memory_footprint():.3f} GB')\n    os.system('nvidia-smi --gpu-reset')\n    IPython.display.clear_output(wait=True)\n    print(f'GPU memory released: {memory_footprint():.3f} GB')\n","metadata":{"execution":{"iopub.status.busy":"2023-04-27T13:56:04.202399Z","iopub.execute_input":"2023-04-27T13:56:04.20285Z","iopub.status.idle":"2023-04-27T13:56:04.379728Z","shell.execute_reply.started":"2023-04-27T13:56:04.202804Z","shell.execute_reply":"2023-04-27T13:56:04.377834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}