{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 代码实现"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于Mask R-CNN代码架构过于庞大，我们将直接调用相关接口进行效果展示。我们先导入必要的包。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "! git clone https://github.com/matterport/Mask_RCNN.git\n",
    "! cd Mask_RCNN\n",
    "\n",
    "import os\n",
    "import sys\n",
    "sys.path.append('Mask_RCNN')\n",
    "os.chdir('./Mask_RCNN')\n",
    "os.getcwd()\n",
    "\n",
    "! python setup.py install\n",
    "\n",
    "from mrcnn.config import Config\n",
    "from mrcnn import model as modellib\n",
    "from mrcnn import visualize\n",
    "import cv2\n",
    "import colorsys\n",
    "import argparse\n",
    "import imutils\n",
    "import random\n",
    "import os\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着，我们导入模型。这里，模型使用MS COCO数据集进行预训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Configurations:\n",
      "BACKBONE                       resnet101\n",
      "BACKBONE_STRIDES               [4, 8, 16, 32, 64]\n",
      "BATCH_SIZE                     1\n",
      "BBOX_STD_DEV                   [0.1 0.1 0.2 0.2]\n",
      "COMPUTE_BACKBONE_SHAPE         None\n",
      "DETECTION_MAX_INSTANCES        100\n",
      "DETECTION_MIN_CONFIDENCE       0.7\n",
      "DETECTION_NMS_THRESHOLD        0.3\n",
      "FPN_CLASSIF_FC_LAYERS_SIZE     1024\n",
      "GPU_COUNT                      1\n",
      "GRADIENT_CLIP_NORM             5.0\n",
      "IMAGES_PER_GPU                 1\n",
      "IMAGE_CHANNEL_COUNT            3\n",
      "IMAGE_MAX_DIM                  1024\n",
      "IMAGE_META_SIZE                93\n",
      "IMAGE_MIN_DIM                  800\n",
      "IMAGE_MIN_SCALE                0\n",
      "IMAGE_RESIZE_MODE              square\n",
      "IMAGE_SHAPE                    [1024 1024    3]\n",
      "LEARNING_MOMENTUM              0.9\n",
      "LEARNING_RATE                  0.001\n",
      "LOSS_WEIGHTS                   {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 1.0}\n",
      "MASK_POOL_SIZE                 14\n",
      "MASK_SHAPE                     [28, 28]\n",
      "MAX_GT_INSTANCES               100\n",
      "MEAN_PIXEL                     [123.7 116.8 103.9]\n",
      "MINI_MASK_SHAPE                (56, 56)\n",
      "NAME                           coco_inference\n",
      "NUM_CLASSES                    81\n",
      "POOL_SIZE                      7\n",
      "POST_NMS_ROIS_INFERENCE        1000\n",
      "POST_NMS_ROIS_TRAINING         2000\n",
      "PRE_NMS_LIMIT                  6000\n",
      "ROI_POSITIVE_RATIO             0.33\n",
      "RPN_ANCHOR_RATIOS              [0.5, 1, 2]\n",
      "RPN_ANCHOR_SCALES              (32, 64, 128, 256, 512)\n",
      "RPN_ANCHOR_STRIDE              1\n",
      "RPN_BBOX_STD_DEV               [0.1 0.1 0.2 0.2]\n",
      "RPN_NMS_THRESHOLD              0.7\n",
      "RPN_TRAIN_ANCHORS_PER_IMAGE    256\n",
      "STEPS_PER_EPOCH                1000\n",
      "TOP_DOWN_PYRAMID_SIZE          256\n",
      "TRAIN_BN                       False\n",
      "TRAIN_ROIS_PER_IMAGE           200\n",
      "USE_MINI_MASK                  True\n",
      "USE_RPN_ROIS                   True\n",
      "VALIDATION_STEPS               50\n",
      "WEIGHT_DECAY                   0.0001\n",
      "\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2023-01-05 12:27:25.556772: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n",
      "2023-01-05 12:27:25.583159: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2300090000 Hz\n",
      "2023-01-05 12:27:25.589540: I tensorflow/compiler/xla/service/service.cc:150] XLA service 0x302a000 executing computations on platform Host. Devices:\n",
      "2023-01-05 12:27:25.589584: I tensorflow/compiler/xla/service/service.cc:158]   StreamExecutor device (0): <undefined>, <undefined>\n"
     ]
    }
   ],
   "source": [
    "class SimpleConfig(Config):\n",
    "    # 设定名称\n",
    "    NAME = \"coco_inference\"\n",
    "    # 设定GPU个数，指定每张GPU运行的图像张数\n",
    "    GPU_COUNT = 1\n",
    "    IMAGES_PER_GPU = 1\n",
    "    # MS COCO数据集的类别数\n",
    "    NUM_CLASSES = 81\n",
    "    \n",
    "    \n",
    "config = SimpleConfig()\n",
    "config.display()\n",
    "model = modellib.MaskRCNN(mode=\"inference\", config=config, model_dir=os.getcwd())\n",
    "model.load_weights(\"mask_rcnn_coco.h5\", by_name=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，便可以使用Mask R-CNN进行实例分割。先导入一张图像，并使用Mask R-CNN对其进行实例分割。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 832116 characters]",
      "text/plain": [
       "<Figure size 1600x1600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', \n",
    "               'airplane','bus', 'train', 'truck', 'boat', \n",
    "               'traffic light', 'fire hydrant', 'stop sign', \n",
    "               'parking meter', 'bench', 'bird', 'cat', 'dog', \n",
    "               'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', \n",
    "               'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',\n",
    "               'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',\n",
    "               'kite', 'baseball bat', 'baseball glove', 'skateboard',\n",
    "               'surfboard', 'tennis racket', 'bottle', 'wine glass', \n",
    "               'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', \n",
    "               'apple', 'sandwich', 'orange', 'broccoli', 'carrot', \n",
    "               'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', \n",
    "               'potted plant', 'bed', 'dining table', 'toilet', 'tv', \n",
    "               'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', \n",
    "               'microwave', 'oven', 'toaster', 'sink', 'refrigerator', \n",
    "               'book', 'clock', 'vase', 'scissors', 'teddy bear', \n",
    "               'hair drier', 'toothbrush']\n",
    "\n",
    "image = cv2.imread('1.png')\n",
    "image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n",
    "image = imutils.resize(image, width=512)\n",
    "# 进行前向传播，获得预测结果\n",
    "print(\"[INFO] making predictions with Mask R-CNN...\")\n",
    "result = model.detect([image], verbose=1)\n",
    "\n",
    "r1 = result[0]\n",
    "visualize.display_instances(image, r1['ROIs'], r1['masks'], r1['class_ids'], class_names, r1['scores'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以观察到，Mask R-CNN可以捕捉到每一个独立的物体，并使用一个掩模来描述出该物体的具体形状。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
