{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":7328562,"sourceType":"datasetVersion","datasetId":4253879},{"sourceId":7372255,"sourceType":"datasetVersion","datasetId":4283523},{"sourceId":7376566,"sourceType":"datasetVersion","datasetId":4286444},{"sourceId":7437995,"sourceType":"datasetVersion","datasetId":4329019},{"sourceId":7442286,"sourceType":"datasetVersion","datasetId":4331749},{"sourceId":7443814,"sourceType":"datasetVersion","datasetId":4332763},{"sourceId":7450404,"sourceType":"datasetVersion","datasetId":4336772},{"sourceId":7487542,"sourceType":"datasetVersion","datasetId":4359198}],"dockerImageVersionId":27938,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os \nimport sys\nimport random\nimport math\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\nimport json\nimport pydicom\nfrom imgaug import augmenters as iaa\nfrom tqdm import tqdm\nimport pandas as pd \nimport glob\nfrom sklearn.model_selection import KFold","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:04:59.242841Z","iopub.execute_input":"2024-01-29T03:04:59.243157Z","iopub.status.idle":"2024-01-29T03:05:00.817695Z","shell.execute_reply.started":"2024-01-29T03:04:59.243112Z","shell.execute_reply":"2024-01-29T03:05:00.81658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_DIR = '/kaggle/input'\n\n# Directory to save logs and trained model\nROOT_DIR = '/kaggle/working'","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:00.819534Z","iopub.execute_input":"2024-01-29T03:05:00.819822Z","iopub.status.idle":"2024-01-29T03:05:00.8239Z","shell.execute_reply.started":"2024-01-29T03:05:00.819758Z","shell.execute_reply":"2024-01-29T03:05:00.822934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://www.github.com/matterport/Mask_RCNN.git","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:00.82516Z","iopub.execute_input":"2024-01-29T03:05:00.82542Z","iopub.status.idle":"2024-01-29T03:05:10.177255Z","shell.execute_reply.started":"2024-01-29T03:05:00.825371Z","shell.execute_reply":"2024-01-29T03:05:10.176492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir('Mask_RCNN')\n","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:10.178899Z","iopub.execute_input":"2024-01-29T03:05:10.17919Z","iopub.status.idle":"2024-01-29T03:05:10.183334Z","shell.execute_reply.started":"2024-01-29T03:05:10.179137Z","shell.execute_reply":"2024-01-29T03:05:10.182488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!python setup.py -q install","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:10.186263Z","iopub.execute_input":"2024-01-29T03:05:10.186504Z","iopub.status.idle":"2024-01-29T03:05:10.193399Z","shell.execute_reply.started":"2024-01-29T03:05:10.186464Z","shell.execute_reply":"2024-01-29T03:05:10.192629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import Mask RCNN\nsys.path.append(os.path.join(ROOT_DIR, 'Mask_RCNN'))  # To find local version of the library\nfrom mrcnn.config import Config\nfrom mrcnn import utils\nimport mrcnn.model as modellib\nfrom mrcnn import visualize\nfrom mrcnn.model import log","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:10.19517Z","iopub.execute_input":"2024-01-29T03:05:10.195457Z","iopub.status.idle":"2024-01-29T03:05:11.222745Z","shell.execute_reply.started":"2024-01-29T03:05:10.195407Z","shell.execute_reply":"2024-01-29T03:05:11.221867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nimport json\nimport datetime\nimport numpy as np\nimport skimage.draw\n\nfrom mrcnn.visualize import display_instances\nfrom mrcnn.utils import extract_bboxes\n\nfrom mrcnn.utils import Dataset\nfrom matplotlib import pyplot as plt\n\nfrom mrcnn.config import Config\nfrom mrcnn.model import MaskRCNN\n\n\nfrom mrcnn import model as modellib, utils\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:11.224115Z","iopub.execute_input":"2024-01-29T03:05:11.224381Z","iopub.status.idle":"2024-01-29T03:05:11.230452Z","shell.execute_reply.started":"2024-01-29T03:05:11.224326Z","shell.execute_reply":"2024-01-29T03:05:11.229742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomDataset(utils.Dataset):\n\n    def load_custom(self, dataset_dir, subset):\n        \"\"\"Load a subset of the custom dataset.\n        dataset_dir: Root directory of the dataset.\n        subset: Subset to load: train or val\n        \"\"\"\n        # Add classes according to the numbe of classes required to detect\n        self.add_class(\"custom\", 1, \"Mercedez Logo\")\n        #self.add_class(\"custom\", 1, \"Blue_Marble\")\n        #self.add_class(\"custom\",2,\"Non_Blue_Marble\")\n\n        # Train or validation dataset?\n        assert subset in [\"train\",\"val\"]\n        dataset_dir = os.path.join(dataset_dir, subset)\n\n        # Load annotations\n        # VGG Image Annotator (up to version 1.6) saves each image in the form:\n        # { 'filename': '28503151_5b5b7ec140_b.jpg',\n        #   'regions': {\n        #       '0': {\n        #           'region_attributes': {},\n        #           'shape_attributes': {\n        #               'all_points_x': [...],\n        #               'all_points_y': [...],\n        #               'name': 'polygon'}},\n        #       ... more regions ...\n        #   },\n        #   'size': 100202\n        # }\n        # We mostly care about the x and y coordinates of each region\n        # Note: In VIA 2.0, regions was changed from a dict to a list.\n        annotations = json.load(open(os.path.join(dataset_dir, \"labels.json\")))\n        print(os.path.join(dataset_dir, \"labels.json\"))\n        annotations = list(annotations.values())  # don't need the dict keys\n\n        # The VIA tool saves images in the JSON even if they don't have any\n        # annotations. Skip unannotated images.\n        annotations = [a for a in annotations if a['regions']]\n\n        # Add images\n        for a in annotations:\n            # Get the x, y coordinaets of points of the polygons that make up\n            # the outline of each object instance. These are stores in the\n            # shape_attributes (see json format above)\n            # The if condition is needed to support VIA versions 1.x and 2.x.\n            polygons = [r['shape_attributes'] for r in a['regions']]\n            #labelling each class in the given image to a number\n\n            custom = [s['region_attributes'] for s in a['regions']]\n            \n            num_ids=[]\n            #Add the classes according to the requirement\n            for n in custom:\n                try:\n                    num_ids.append(1)\n\n                except:\n                    pass\n\n            # load_mask() needs the image size to convert polygons to masks.\n            # Unfortunately, VIA doesn't include it in JSON, so we must read\n            # the image. This is only managable since the dataset is tiny.\n            image_path = os.path.join(dataset_dir, a['filename'])\n            image = skimage.io.imread(image_path)\n            height, width = image.shape[:2]\n\n            self.add_image(\n                \"custom\",\n                image_id=a['filename'],  # use file name as a unique image id\n                path=image_path,\n                width=width, height=height,\n                polygons=polygons,\n                num_ids=num_ids)\n \n \n    def load_mask(self, image_id):\n        \"\"\"Generate instance masks for an image.\n       Returns:\n        masks: A bool array of shape [height, width, instance count] with\n            one mask per instance.\n        class_ids: a 1D array of class IDs of the instance masks.\n        \"\"\"\n        # If not a custom dataset image, delegate to parent class.\n        image_info = self.image_info[image_id]\n        if image_info[\"source\"] != \"custom\":\n            return super(self.__class__, self).load_mask(image_id)\n        num_ids = image_info['num_ids']\t\n        #print(\"Here is the numID\",num_ids)\n\n        # Convert polygons to a bitmap mask of shape\n        # [height, width, instance_count]\n        info = self.image_info[image_id]\n        mask = np.zeros([info[\"height\"], info[\"width\"], len(info[\"polygons\"])],\n                        dtype=np.uint8)\n        for i, p in enumerate(info[\"polygons\"]):\n            # Get indexes of pixels inside the polygon and set them to 1\n            rr, cc = skimage.draw.polygon(p['all_points_y'], p['all_points_x'])\n            mask[rr, cc, i] = 1\n\n        # Return mask, and array of class IDs of each instance. Since we have\n        # one class ID only, we return an array of 1s\n        num_ids = np.array(num_ids, dtype=np.int32)\t\n        return mask, num_ids#.astype(np.bool), np.ones([mask.shape[-1]], dtype=np.int32),\n    \n    \n    \n    def image_reference(self, image_id):\n        \"\"\"Return the path of the image.\"\"\"\n        info = self.image_info[image_id]\n        if info[\"source\"] == \"custom\":\n            return info[\"path\"]\n        else:\n            super(self.__class__, self).image_reference(image_id)\n            \n    def split_data(self, dataset_dir, test_size=0.2, random_state=None):\n        \"\"\"\n        Split the data into training and validation sets.\n\n        Parameters:\n        - dataset_dir: Root directory of the dataset.\n        - test_size: Fraction of the data to be used for validation (default: 0.2).\n        - random_state: Seed for reproducibility (default: None).\n\n        Returns:\n        - train_dataset: CustomDataset object for the training set.\n        - val_dataset: CustomDataset object for the validation set.\n        \"\"\"\n\n        # Load all data\n        self.load_custom(dataset_dir, \"train\")\n        self.prepare()\n\n        # Split image IDs into training and validation sets\n        train_ids, val_ids = train_test_split(self.image_ids, test_size=test_size, random_state=random_state)\n\n        # Create separate datasets for training and validation\n        train_dataset = CustomDataset()\n        val_dataset = CustomDataset()\n\n        # Copy relevant information to training dataset\n        train_dataset.add_class(\"custom\", 1, \"Mercedez Logo\")\n        train_dataset.image_info = [info for info in self.image_info if info['id'] in train_ids]\n\n        # Copy relevant information to validation dataset\n        val_dataset.add_class(\"custom\", 1, \"Mercedez Logo\")\n        val_dataset.image_info = [info for info in self.image_info if info['id'] in val_ids]\n\n        return train_dataset, val_dataset\n","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:11.231985Z","iopub.execute_input":"2024-01-29T03:05:11.232258Z","iopub.status.idle":"2024-01-29T03:05:11.260382Z","shell.execute_reply.started":"2024-01-29T03:05:11.232214Z","shell.execute_reply":"2024-01-29T03:05:11.259647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_train = CustomDataset()\ndataset_train.load_custom(r\"/kaggle/input/mercedez-logo-diverse/archive1/Annotations\", \"train\") \ndataset_train.prepare()\nprint('Train: %d' % len(dataset_train.image_ids))","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:11.261688Z","iopub.execute_input":"2024-01-29T03:05:11.261981Z","iopub.status.idle":"2024-01-29T03:05:15.759083Z","shell.execute_reply.started":"2024-01-29T03:05:11.261932Z","shell.execute_reply":"2024-01-29T03:05:15.758289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_val = CustomDataset()\ndataset_val.load_custom(r\"/kaggle/input/mercedez-logo-diverse/archive1/Annotations\", \"val\") \ndataset_val.prepare()\nprint('Val: %d' % len(dataset_val.image_ids))\n","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:15.760532Z","iopub.execute_input":"2024-01-29T03:05:15.760765Z","iopub.status.idle":"2024-01-29T03:05:16.90148Z","shell.execute_reply.started":"2024-01-29T03:05:15.760725Z","shell.execute_reply":"2024-01-29T03:05:16.900703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define image id\nimage_id = 1\n# load the image\nimage = dataset_train.load_image(image_id)\n# load the masks and the class ids\nmask, class_ids = dataset_train.load_mask(image_id)\n\n# display_instances(image, r1['rois'], r1['masks'], r1['class_ids'],\n# dataset.class_names, r1['scores'], ax=ax, title=\"Predictions1\")\n\n# extract bounding boxes from the masks\nbbox = extract_bboxes(mask)\n# display image with masks and bounding boxes\ndisplay_instances(image, bbox, mask, class_ids, dataset_train.class_names)","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:16.902866Z","iopub.execute_input":"2024-01-29T03:05:16.90312Z","iopub.status.idle":"2024-01-29T03:05:17.260077Z","shell.execute_reply.started":"2024-01-29T03:05:16.90308Z","shell.execute_reply":"2024-01-29T03:05:17.259167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define a configuration for the model\nclass MarbleConfig(Config):\n\t# define the name of the configuration\n\tNAME = \"marble_cfg\"\n\t# number of classes (background + blue marble + non-Blue marble)\n\tNUM_CLASSES = 1 + 1 \n\t# number of training steps per epoch\n\tSTEPS_PER_EPOCH = 75\n\tIMAGES_PER_GPU = 4\n\t#LEARNING_RATE = 0.01\n\tIMAGE_MAX_DIM = 512\n\tIMAGE_MIN_DIM = 512\n#\tIMAGE_SHAPE = [256,256,3]\n\t#LEARNING_MOMENTUM = 0.9\n\t#BACKBONE = 'resnet50'\n\t#WEIGHT_DECAY = 0.001\n\tRPN_NMS_THRESHOLD = 0.95\n    \n    \n\t#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' : 0.5}\n#LOSS_WEIGHTS['rcnn_mask_loss'] = 0.5\n    #DETECTION_MIN_CONFIDENCE = 0.9 # Skip detections with < 90% confidence\n    \n# prepare config\nconfig = MarbleConfig()\nconfig.display() ","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:17.261479Z","iopub.execute_input":"2024-01-29T03:05:17.261757Z","iopub.status.idle":"2024-01-29T03:05:17.272193Z","shell.execute_reply.started":"2024-01-29T03:05:17.261705Z","shell.execute_reply":"2024-01-29T03:05:17.27123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_DIR = os.path.abspath(\"./\")\n# Import Mask RCNN\nsys.path.append(ROOT_DIR)  # To find local version of the library\n# Directory to save logs and trained model\nDEFAULT_LOGS_DIR = r\"/kaggle/working/logs/\"\n# Path to trained weights file\nCOCO_WEIGHTS_PATH = os.path.join(ROOT_DIR, \"coco_weights/mask_rcnn_coco.h5\")\n\n########################\n#Weights are saved to root D: directory. need to investigate how they can be\n#saved to the directory defined... \"logs_models\"\n","metadata":{"execution":{"iopub.status.busy":"2024-01-29T03:05:17.273531Z","iopub.execute_input":"2024-01-29T03:05:17.273762Z","iopub.status.idle":"2024-01-29T03:05:17.285099Z","shell.execute_reply.started":"2024-01-29T03:05:17.273725Z","shell.execute_reply":"2024-01-29T03:05:17.284116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget --quiet https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5\n!ls -lh mask_rcnn_coco.h5\n\nCOCO_WEIGHTS_PATH = \"mask_rcnn_coco.h5\"","metadata":{"execution":{"iopub.status.busy":"2024-01-28T23:11:29.204582Z","iopub.execute_input":"2024-01-28T23:11:29.204838Z","iopub.status.idle":"2024-01-28T23:11:33.022787Z","shell.execute_reply.started":"2024-01-28T23:11:29.20479Z","shell.execute_reply":"2024-01-28T23:11:33.021764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image augmentation (light but constant)\naugmentation = iaa.Sequential([\n    iaa.OneOf([ ## geometric transform\n        iaa.Affine(\n            scale={\"x\": (0.98, 1.02), \"y\": (0.98, 1.04)},\n            translate_percent={\"x\": (-0.02, 0.02), \"y\": (-0.04, 0.04)},\n            rotate=(-2, 2),\n            shear=(-1, 1),\n        ),\n        iaa.PiecewiseAffine(scale=(0.001, 0.025)),\n    ]),\n    iaa.OneOf([ ## brightness or contrast\n        iaa.Multiply((0.9, 1.1)),\n        iaa.ContrastNormalization((0.9, 1.1)),\n    ]),\n    iaa.OneOf([ ## blur or sharpen\n        iaa.GaussianBlur(sigma=(0.0, 0.1)),\n        iaa.Sharpen(alpha=(0.0, 0.1)),\n    ]),\n])\n\n# test on the same image as above\nimggrid = augmentation.draw_grid(image[:, :, 0], cols=5, rows=2)\nplt.figure(figsize=(30, 12))\n_ = plt.imshow(imggrid[:, :, 0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-01-28T23:11:33.0244Z","iopub.execute_input":"2024-01-28T23:11:33.024649Z","iopub.status.idle":"2024-01-28T23:11:34.323601Z","shell.execute_reply.started":"2024-01-28T23:11:33.02461Z","shell.execute_reply":"2024-01-28T23:11:34.322721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# define the model\nmodel = MaskRCNN(mode='training', model_dir=os.getcwd(), config=config)\n# load weights (mscoco) and exclude the output layers\nmodel.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\",  \"mrcnn_bbox\", \"mrcnn_mask\"])\n# train weights (output layers or 'heads')\nmodel.train(dataset_train, dataset_val, learning_rate=0.001, epochs=50, layers='heads', augmentation = augmentation)\nhistory = model.keras_model.history.history\n\n############################\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T23:11:34.325058Z","iopub.execute_input":"2024-01-28T23:11:34.325454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\n# define the model\nmodel = MaskRCNN(mode='training', model_dir=DEFAULT_LOGS_DIR, config=config)\n# load weights (mscoco) and exclude the output layers\nmodel.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\",  \"mrcnn_bbox\", \"mrcnn_mask\"])\n# train weights (output layers or 'heads')\nmodel.train(dataset_train, dataset_val, learning_rate=config.LEARNING_RATE/5, epochs=30, layers='heads')\nhistory1 = model.keras_model.history.history\n\n############################\n\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd","metadata":{"execution":{"iopub.status.busy":"2024-01-29T00:26:08.649157Z","iopub.execute_input":"2024-01-29T00:26:08.649842Z","iopub.status.idle":"2024-01-29T00:26:08.656999Z","shell.execute_reply.started":"2024-01-29T00:26:08.64961Z","shell.execute_reply":"2024-01-29T00:26:08.655581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = range(1,len(next(iter(history.values())))+1)\nhist = pd.DataFrame(history, index=epochs)","metadata":{"execution":{"iopub.status.busy":"2024-01-29T00:26:08.658635Z","iopub.execute_input":"2024-01-29T00:26:08.659136Z","iopub.status.idle":"2024-01-29T00:26:08.680543Z","shell.execute_reply.started":"2024-01-29T00:26:08.659088Z","shell.execute_reply":"2024-01-29T00:26:08.67927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(17,5))\n\nplt.subplot(141)\nplt.plot(epochs, hist[\"loss\"], label=\"Train loss\")\nplt.plot(epochs, hist[\"val_loss\"], label=\"Valid loss\")\nplt.legend()\nplt.subplot(142)\nplt.plot(epochs, hist[\"mrcnn_class_loss\"], label=\"Train class ce\")\nplt.plot(epochs, hist[\"val_mrcnn_class_loss\"], label=\"Valid class ce\")\nplt.legend()\nplt.subplot(143)\nplt.plot(epochs, hist[\"mrcnn_bbox_loss\"], label=\"Train box loss\")\nplt.plot(epochs, hist[\"val_mrcnn_bbox_loss\"], label=\"Valid box loss\")\nplt.legend()\nplt.subplot(144)\nplt.plot(epochs, hist[\"mrcnn_mask_loss\"], label=\"Train mask loss\")\nplt.plot(epochs, hist[\"val_mrcnn_mask_loss\"], label=\"Valid mask loss\")\nplt.legend()\nplt.savefig('plot.png')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-29T00:26:08.684083Z","iopub.execute_input":"2024-01-29T00:26:08.684935Z","iopub.status.idle":"2024-01-29T00:26:11.322056Z","shell.execute_reply.started":"2024-01-29T00:26:08.684876Z","shell.execute_reply":"2024-01-29T00:26:11.320722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\n# define the model\nmodel = MaskRCNN(mode='training', model_dir=DEFAULT_LOGS_DIR, config=config)\n# load weights (mscoco) and exclude the output layers\nmodel.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[\"mrcnn_class_logits\", \"mrcnn_bbox_fc\",  \"mrcnn_bbox\", \"mrcnn_mask\"])\n# train weights (output layers or 'heads')\nmodel.train(dataset_train, dataset_val, learning_rate=0.00005, epochs=30, layers='heads')\nhistory2 = model.keras_model.history.history\n\n############################\n'''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction","metadata":{}},{"cell_type":"code","source":"#INFERENCE\n\n###################################################\nfrom mrcnn.model import load_image_gt\nfrom mrcnn.model import mold_image\nfrom mrcnn.utils import compute_ap\nfrom numpy import expand_dims\nfrom numpy import mean\nfrom matplotlib.patches import Rectangle\nfrom mrcnn.config import Config\nimport skimage\nimport matplotlib.pyplot as plt\nfrom mrcnn.model import MaskRCNN","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# define the prediction configuration\nclass PredictionConfig(Config):\n\t# define the name of the configuration\n\tNAME = \"marble_cfg\"\n\t# number of classes (background + Blue Marbles + Non Blue marbles)\n\tNUM_CLASSES = 1 + 1\n\t# Set batch size to 1 since we'll be running inference on\n            # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU\n\tGPU_COUNT = 1\n\tIMAGES_PER_GPU = 1\n# calculate the mAP for a model on a given dataset","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# calculate the mAP for a model on a given dataset\ndef evaluate_model(dataset, model, cfg):\n\tAPs = list()\n\tfor image_id in dataset.image_ids:\n\t\t# load image, bounding boxes and masks for the image id\n\t\timage, image_meta, gt_class_id, gt_bbox, gt_mask = load_image_gt(dataset, cfg, image_id)\n\t\t# convert pixel values (e.g. center)\n\t\tscaled_image = mold_image(image, cfg)\n\t\t# convert image into one sample\n\t\tsample = expand_dims(scaled_image, 0)\n\t\t# make prediction\n\t\tyhat = model.detect(sample, verbose=0)\n\t\t# extract results for first sample\n\t\tr = yhat[0]\n\t\t# calculate statistics, including AP\n\t\tAP, _, _, _ = compute_ap(gt_bbox, gt_class_id, gt_mask, r[\"rois\"], r[\"class_ids\"], r[\"scores\"], r['masks'])\n\t\t# store\n\t\tAPs.append(AP)\n\t# calculate the mean AP across all images\n\tmAP = mean(APs)\n\treturn mAP","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# create config\ncfg = PredictionConfig()\n# define the model\nmodel = MaskRCNN(mode='inference', model_dir='/kaggle/working/Mask_RCNN/marble_cfg20240127T1706/', config=cfg)\n# load model weights\nmodel.load_weights('/kaggle/working/Mask_RCNN/marble_cfg20240127T1706/mask_rcnn_marble_cfg_0039.h5', by_name=True)\n# evaluate model on training dataset\ntrain_mAP = evaluate_model(dataset_train, model, cfg)\nprint(\"Train mAP: %.3f\" % train_mAP)\n#evaluate model on test dataset\ntest_mAP = evaluate_model(dataset_val, model, cfg)\nprint(\"Test mAP: %.3f\" % test_mAP)\n\n#################################################","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#################################################\n#Test on a single image\nmarbles_img = skimage.io.imread(\"/kaggle/input/mercedez-annotations/Annotations/train/126.jpg\")\n\n#marbles_img = skimage.io.imread(\"/kaggle/input/mask-rcnn-logo/286-Object detection using mask RCNN - end to end/marble_dataset/train/347b.jpg\")\nplt.imshow(marbles_img)\n\ndetected = model.detect([marbles_img])\nresults = detected[0]\nclass_names = ['BG', 'Mercedez Logo']\ndisplay_instances(marbles_img, results['rois'], results['masks'], \n                  results['class_ids'], class_names, results['scores'])\n\n###############################","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"detected[0]['scores']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#Show detected objects in color and all others in B&W    \ndef color_splash(img, mask):\n    \"\"\"Apply color splash effect.\n    image: RGB image [height, width, 3]\n    mask: instance segmentation mask [height, width, instance count]\n    Returns result image.\n    \"\"\"\n    # Make a grayscale copy of the image. The grayscale copy still\n    # has 3 RGB channels, though.\n    gray = skimage.color.gray2rgb(skimage.color.rgb2gray(img)) * 255\n    # Copy color pixels from the original color image where mask is set\n    if mask.shape[-1] > 0:\n        # We're treating all instances as one, so collapse the mask into one layer\n        mask = (np.sum(mask, -1, keepdims=True) >= 1)\n        splash = np.where(mask, img, gray).astype(np.uint8)\n    else:\n        splash = gray.astype(np.uint8)\n    return splash","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# an example of plotting confusion matrix.\n# the first step consists of computing ground-truth and prediction vectors for all images.\n# using these vectors, the plot_confusion_matrix_from_data function plots the CM and computes tps fps and fns\nimport pandas as pd\nimport numpy as np\nimport os \n\n#ground-truth and predictions lists\ngt_tot = np.array([])\npred_tot = np.array([])\n#mAP list\nmAP_ = []","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = dataset_val","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#compute gt_tot, pred_tot and mAP for each image in the test dataset\nfor image_id in dataset.image_ids:\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset, config, image_id, use_mini_mask=False)\n    info = dataset.image_info[image_id]\n\n    # Run the model\n    results = model.detect([image], verbose=1)\n    r = results[0]\n    \n    #compute gt_tot and pred_tot\n    gt, pred = utils.gt_pred_lists(gt_class_id, gt_bbox, r['class_ids'], r['rois'])\n    gt_tot = np.append(gt_tot, gt)\n    pred_tot = np.append(pred_tot, pred)\n    \n    #precision_, recall_, AP_ \n    AP_, precision_, recall_, overlap_ = utils.compute_ap(gt_bbox, gt_class_id, gt_mask,\n                                          r['rois'], r['class_ids'], r['scores'], r['masks'])\n    #check if the vectors len are equal\n    print(\"the actual len of the gt vect is : \", len(gt_tot))\n    print(\"the actual len of the pred vect is : \", len(pred_tot))\n    \n    mAP_.append(AP_)\n    print(\"Average precision of this image : \",AP_)\n    print(\"The actual mean average precision for the whole images (matterport methode) \", sum(mAP_)/len(mAP_))\n    print(\"Ground truth object : \"+dataset.class_names[gt])\n    print(\"Predicted object : \"+dataset.class_names[pred])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\"\"\"\n#compute gt_tot, pred_tot and mAP for each image in the test dataset\nfor image_id in dataset.image_ids:\n    image, image_meta, gt_class_id, gt_bbox, gt_mask =\\\n        modellib.load_image_gt(dataset, config, image_id, use_mini_mask=False)\n    info = dataset.image_info[image_id]\n\n    # Run the model\n    results = model.detect([image], verbose=1)\n    r = results[0]\n    \n    #compute gt_tot and pred_tot\n    gt, pred = utils.gt_pred_lists(gt_class_id, gt_bbox, r['class_ids'], r['rois'])\n    gt_tot = np.append(gt_tot, gt)\n    pred_tot = np.append(pred_tot, pred)\n    \n    #precision_, recall_, AP_ \n    AP_, precision_, recall_, overlap_ = utils.compute_ap(gt_bbox, gt_class_id, gt_mask,\n                                          r['rois'], r['class_ids'], r['scores'], r['masks'])\n    #check if the vectors len are equal\n    print(\"the actual len of the gt vect is : \", len(gt_tot))\n    print(\"the actual len of the pred vect is : \", len(pred_tot))\n    \n    mAP_.append(AP_)\n    print(\"Average precision of this image : \",AP_)\n    print(\"The actual mean average precision for the whole images (matterport methode) \", sum(mAP_)/len(mAP_))\n    print(\"Ground truth object : \"+dataset.class_names[gt])\n    print(\"Predicted object : \"+dataset.class_names[pred])\n  \"\"\"  \ngt_tot=gt_tot.astype(int)\npred_tot=pred_tot.astype(int)\n#save the vectors of gt and pred\nsave_dir = \"output\"\ngt_pred_tot_json = {\"gt_tot\" : gt_tot, \"pred_tot\" : pred_tot}\ndf = pd.DataFrame(gt_pred_tot_json)\nif not os.path.exists(save_dir):\n    os.makedirs(save_dir)\ndf.to_json(os.path.join(save_dir,\"gt_pred_test.json\"))\n    \n#print the confusion matrix and compute true postives, false positives and false negative for each class: \n#ps : you can controle the figure size and text format by choosing the right values\n#tp, fp, fn = utils.plot_confusion_matrix_from_data(gt_tot, pred_tot, dataset.class_names, fz=18, figsize=(20,20), lw=0.5)\n\n###########################################################################################################################\n\n#since in this notebook i didnt run the loop above, here is an example of plotting using manual generated vectors :\n#let 0 be the background class\n#gt_tot=[1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,0,1,2,3,0,1,2,3,0,1,2,0]\n#pred_tot=[1,2,3,3,2,1,1,2,3,1,2,3,1,2,0,2,2,2,3,1,0,0,3,2,1,2,0]\n\n#supose we have 1 image containing the gt classes bellow :\ngt_class_id = np.array([1,2,3,1,2,3])\n#with the bbox :\ngt_bbox = np.array([np.array([10,100,20,200]),np.array([100,10,200,20]),np.array([110,15,220,25]),np.array([20,200,20,200]),\n                    np.array([90,15,220,20]),np.array([100,10,150,20])])\n#and the model detected the classes : \npred_class_id = np.array([2,3,2,3,2,3])\n#with the bbox : \npred_bbox = np.array([np.array([100,10,200,20]),np.array([110,15,220,25]),np.array([90,15,220,20]),np.array([101,20,100,21]),\n                    np.array([500,20,1,20]),np.array([100,10,150,20])])\n\n#for this image, the gt and pred lists are :    \ngt, pred = utils.gt_pred_lists(gt_class_id, gt_bbox, pred_class_id, pred_bbox)\ngt_tot = np.append(gt_tot, gt)\npred_tot = np.append(pred_tot, pred)\n\nprint(\"ground truth list : \",gt_tot)\nprint(\"predicted list : \",pred_tot)\n\n#here i didnt set the columns list, since in the code if columns is note specified \n#it generates automatically a list from \"class A\" to \"class ..\". in this example, class A should be the background\n#Note : class A is the backround in this example\ntp,fp,fn=utils.plot_confusion_matrix_from_data(gt_tot,pred_tot,fz=18, figsize=(20,20), lw=0.5)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef detect_and_color_splash(model, image_path=None, video_path=None):\n    assert image_path or video_path\n\n    # Image or video?\n    if image_path:\n        # Run model detection and generate the color splash effect\n        #print(\"Running on {}\".format(img))\n        # Read image\n        img = skimage.io.imread(image_path)\n        # Detect objects\n        r = model.detect([img], verbose=1)[0]\n        # Color splash\n        splash = color_splash(img, r['masks'])\n        # Save output\n        file_name = \"/kaggle/working/splash_{:%Y%m%dT%H%M%S}.png\".format(datetime.datetime.now())\n        skimage.io.imsave(file_name, splash)\n    elif video_path:\n        import cv2\n        # Video capture\n        vcapture = cv2.VideoCapture(video_path)\n        width = int(vcapture.get(cv2.CAP_PROP_FRAME_WIDTH))\n        height = int(vcapture.get(cv2.CAP_PROP_FRAME_HEIGHT))\n        fps = vcapture.get(cv2.CAP_PROP_FPS)\n\n        # Define codec and create video writer\n        file_name = \"/kaggle/working/splash_{:%Y%m%dT%H%M%S}.avi\".format(datetime.datetime.now())\n        vwriter = cv2.VideoWriter(file_name,\n                                  cv2.VideoWriter_fourcc(*'MJPG'),\n                                  fps, (width, height))\n\n        count = 0\n        success = True\n        while success:\n            print(\"frame: \", count)\n            # Read next image\n            success, img = vcapture.read()\n            if success:\n                # OpenCV returns images as BGR, convert to RGB\n                img = img[..., ::-1]\n                # Detect objects\n                r = model.detect([img], verbose=0)[0]\n                # Color splash\n                splash = color_splash(img, r['masks'])\n                # RGB -> BGR to save image to video\n                splash = splash[..., ::-1]\n                # Add image to video writer\n                vwriter.write(splash)\n                count += 1\n        vwriter.release()\n    print(\"Saved to \", file_name)\n\ndetect_and_color_splash(model, image_path=\"/kaggle/input/annotations-mercedez/Annotations/train/110.jpg\")\n\n######################################################\n                         \n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"arr = plt.imread(r\"/kaggle/working/splash_20240120T215957.png\")\nplt.imshow(arr)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}}]}