{"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":"markdown","source":"# Mask RCNN Implementation for Cell Segmentation","metadata":{"id":"7fC3agP0Jh-J"}},{"cell_type":"markdown","source":"The Region-Based Convolutional Neural Network, or R-CNN, is a family of convolutional neural network models designed for object detection. It is a two step process of segmentation, where the algorithm proposes regions with bounding boxes amd MaskRCNN extends this with an output model for predicting a mask for each detected object","metadata":{}},{"cell_type":"markdown","source":"We have a third party implementation of MaskRCNN instead of developing it from scratch. \nThis is the Mask R-CNN Project developed by Matterport. The project is open source released under a permissive license (i.e. MIT license)Requirements for matterport adaptation https://github.com/matterport/Mask_RCNN","metadata":{"id":"pzde-s2eJwFR"}},{"cell_type":"markdown","source":"Installing the Mask R-CNN Library\nThe library can be installed directly via pip.","metadata":{}},{"cell_type":"code","source":"!pip install keras==2.2.5\n!pip install h5py==2.10.0\n!pip install tensorflow==1.15.0\n!pip install mrcnn-colab","metadata":{"id":"32s4SoLAGXMb","execution":{"iopub.status.busy":"2022-01-24T10:03:46.691049Z","iopub.execute_input":"2022-01-24T10:03:46.691596Z","iopub.status.idle":"2022-01-24T10:05:05.935208Z","shell.execute_reply.started":"2022-01-24T10:03:46.691474Z","shell.execute_reply":"2022-01-24T10:05:05.933997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os, shutil\nimport time\nimport random\nimport collections\nimport cv2\n\nfrom mrcnn import config, utils\nimport numpy as np\nimport pandas as pd\n\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nfrom mrcnn import model as modellib\nfrom mrcnn import visualize","metadata":{"id":"5rv1Gca51SvX","execution":{"iopub.status.busy":"2022-01-24T10:05:05.937598Z","iopub.execute_input":"2022-01-24T10:05:05.937844Z","iopub.status.idle":"2022-01-24T10:05:09.551838Z","shell.execute_reply.started":"2022-01-24T10:05:05.937817Z","shell.execute_reply":"2022-01-24T10:05:09.55107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We use matterport's implementation of Mask R-CNN trained on the MS COCO object detection problem. We downloaded the weights for the Mask R-CNN trained on the MS Coco dataset.","metadata":{"id":"pk7-cRB7JYk7"}},{"cell_type":"code","source":"###coco-weights\n!wget https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5","metadata":{"id":"lFhK0shWnnks","outputId":"a7ee86ab-7334-4acd-9973-2a09683223c9","execution":{"iopub.status.busy":"2022-01-24T10:05:09.553295Z","iopub.execute_input":"2022-01-24T10:05:09.553592Z","iopub.status.idle":"2022-01-24T10:05:15.471176Z","shell.execute_reply.started":"2022-01-24T10:05:09.553548Z","shell.execute_reply":"2022-01-24T10:05:15.470361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Defining file paths","metadata":{"id":"JO2dK7mIKFWw"}},{"cell_type":"code","source":"\n\nbase_dir = '../input/sartorius-cell-instance-segmentation'\nnew_dir = '.input/split_dataset/'\nTrain_images_Dir = new_dir + 'train/'\nTest_images_Dir = new_dir + 'test/'\nVal_images_Dir = new_dir + 'val/'\ndf = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\ndf_Train = df.iloc[:, :2]\ndf_Train","metadata":{"id":"9n8_W8GRfdH1","outputId":"e9a60154-ea3f-44f0-d97d-5a2ca90bf9cb"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Splitting Train Data to train and Validate\nif not os.path.exists(Train_images_Dir):\n    os.makedirs(Train_images_Dir)\n    os.makedirs(Test_images_Dir)\n    os.makedirs(Val_images_Dir)\n    files = os.listdir(base_dir+'/train/')\n    for file_name in files:\n        shutil.copy(os.path.join(base_dir+'/train/', file_name), Train_images_Dir) \n    files = os.listdir(base_dir+'/test/')\n    for file_name in files:        \n        shutil.copy(os.path.join(base_dir+'/test/', file_name), Test_images_Dir)             \n    files = os.listdir(Train_images_Dir)\n    #Moving 20% of the files to Validate folder\n    no_of_files = int(len(files) * 0.2)\n    for file_name in random.sample(files, no_of_files):\n        shutil.move(os.path.join(Train_images_Dir, file_name), Val_images_Dir)   ","metadata":{"id":"26q0ZxrTgXqQ","execution":{"iopub.status.busy":"2022-01-24T10:05:16.138962Z","iopub.execute_input":"2022-01-24T10:05:16.139105Z","iopub.status.idle":"2022-01-24T10:05:21.231239Z","shell.execute_reply.started":"2022-01-24T10:05:16.139084Z","shell.execute_reply":"2022-01-24T10:05:21.230075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We need to first define the model by creating an instnace class of MaskRCNN. The class takes Configuration object as an argument which will define the model for training and prediction,  ","metadata":{}},{"cell_type":"code","source":"#Set Configuration\nclass MRcnnConfig(Config):\n    NAME = \"Sartorius_cfg\"\n    GPU_COUNT = 1\n    IMAGES_PER_GPU = 1\n    NUM_CLASSES = 2\n    STEPS_PER_EPOCH = 484\n    VALIDATION_STEPS = 122\n    USE_MINI_MASK = False\n    \nmodel_config = MRcnnConfig()\nmodel_config.display()","metadata":{"id":"GRWCeKVQhEyw","outputId":"51c55759-ba1d-475e-9be6-a21b0d01b4cc","execution":{"iopub.status.busy":"2022-01-24T10:05:21.232546Z","iopub.execute_input":"2022-01-24T10:05:21.232798Z","iopub.status.idle":"2022-01-24T10:05:21.247825Z","shell.execute_reply.started":"2022-01-24T10:05:21.23277Z","shell.execute_reply":"2022-01-24T10:05:21.24705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"############################################################\n#  Dataset - Defining class for Training and Validation\n############################################################\n\nclass CellSartorius(utils.Dataset):\n    def load_data(self, base_dir, which_set):\n        # Adds information (image ID, image path, and annotation file path) about each image in a dictionary.\n        self.add_class(\"dataset\", 1, \"cell\")\n        if which_set == \"Train\":\n            images_dir = Train_images_Dir \n        else:\n            images_dir = Val_images_Dir\n\n        for filename in os.listdir(images_dir):\n            image_id = filename[:-4]\n            img_path = images_dir + filename\n            self.add_image('dataset', image_id=image_id, path=img_path)\n\n    # Loads the binary masks for an image.\n    def load_mask(self, image_id):\n        info = self.image_info[image_id]\n\n        annot = df_Train[df_Train.id==info['id']].annotation.values\n\n        class_ids = []\n        masks = np.zeros([520*704, len(annot)], dtype=np.uint8)\n        for i, rle in enumerate(annot):\n            rle = np.array(rle.split(' ')).reshape(-1, 2)\n            for r in rle:\n                masks[int(r[0]):int(r[0])+int(r[1]), i] = 1\n            class_ids.append(self.class_names.index('cell'))\n        masks = masks.reshape(520, 704, len(annot))\n        return masks, asarray(class_ids, dtype='int32')\n    ","metadata":{"id":"LDGc6OiPhIKs","execution":{"iopub.status.busy":"2022-01-24T10:05:21.251064Z","iopub.execute_input":"2022-01-24T10:05:21.251325Z","iopub.status.idle":"2022-01-24T10:05:21.373658Z","shell.execute_reply.started":"2022-01-24T10:05:21.251292Z","shell.execute_reply":"2022-01-24T10:05:21.372784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"id":"GwNVFpbGnY2A"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n############################################################\n#  Training\n############################################################\nfrom numpy import zeros, asarray\n\"\"\"Train the model.\"\"\"\n# Training dataset.\ndataset_train = CellSartorius()\ndataset_train.load_data(base_dir, \"Train\")\ndataset_train.prepare()\n\n# Validation dataset\ndataset_val = CellSartorius()\ndataset_val.load_data(base_dir, \"Val\")\ndataset_val.prepare()\n\ntrain_model = modellib.MaskRCNN(mode=\"training\", config=model_config, model_dir = new_dir + 'trained_model/')\n\ninfer_model = modellib.MaskRCNN(mode=\"inference\", config=model_config, model_dir = new_dir + 'infer_model/')\n\n#load coco-weights\ntrain_model.load_weights(filepath='./mask_rcnn_coco.h5', \n                   by_name=True, \n                   exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\",  \"mrcnn_bbox\", \"mrcnn_mask\"])\n\nprint(\"Train network heads\")\ntrain_model.train(dataset_train, dataset_val,\n            learning_rate=model_config.LEARNING_RATE,\n            epochs=10,\n            layers='heads')\n\nprint(\"Train all layers\")\ninfer_model.train(dataset_train, dataset_val,\n            learning_rate=model_config.LEARNING_RATE,\n            epochs=10,\n            layers='all')\n","metadata":{"id":"D08hu9MnhV9R","outputId":"6bfce51c-68de-4666-d7e6-97c047442862","execution":{"iopub.status.busy":"2022-01-24T10:05:21.375336Z","iopub.execute_input":"2022-01-24T10:05:21.375615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}