text: import os
  import sys
  import json
  import datetime
  import numpy as np
  import skimage.draw
  
  # Root directory of the project
  ROOT_DIR = os.path.abspath("../../")
  
  # Import Mask RCNN
  sys.path.append(ROOT_DIR)  # To find local version of the library
  from mrcnn.config import Config
  from mrcnn import model as modellib, utils
  
  # Path to trained weights file
  COCO_WEIGHTS_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
  
  # Directory to save logs and model checkpoints, if not provided
  # through the command line argument --logs
  DEFAULT_LOGS_DIR = os.path.join(ROOT_DIR, "logs")
  
  ############################################################
  #  Dataset
  ############################################################
  
  class IDVDataset(utils.Dataset):
  
      def load_idv(self, dataset_dir):
          """Load a subset of the Balloon dataset.
          dataset_dir: Root directory of the dataset.
          subset: Subset to load: train or val
          """
          # Add classes. We have only three class to add.
          self.add_class("idv", 1, "bottle")
          self.add_class("idv", 2, "mobile")
          self.add_class("idv", 2, "laptop")
  
          # Train or validation dataset?
          assert subset in ["train", "val"]
          dataset_dir = os.path.join(dataset_dir, subset)
  
          annotations = json.load(open(os.path.join(dataset_dir, ".../train/via_region_data.json")))
          annotations = list(annotations.values())  # don't need the dict keys
  
          # The VIA tool saves images in the JSON even if they don't have any
          # annotations. Skip unannotated images.
          annotations = [a for a in annotations if a['regions']]
  
          # Add images
          for a in annotations:
              # Get the x, y coordinaets of points of the polygons that make up
              # the outline of each object instance. There are stores in the
              # shape_attributes (see json format above)
              # for b in a['regions'].values():
              #    polygons = [{**b['shape_attributes'], **b['region_attributes']}]
              # print("string=", polygons)
              # for r in a['regions'].values():
              #    polygons = [r['shape_attributes']]
              #    # print("polygons=", polygons)
              #    multi_numbers = [r['region_attributes']]
                  # print("multi_numbers=", multi_numbers)
              polygons = [r['shape_attributes'] for r in a['regions'].values()]
              objects = [s['region_attributes'] for s in a['regions'].values()]
              # print("multi_numbers=", multi_numbers)
              # num_ids = [n for n in multi_numbers['number'].values()]
              # for n in multi_numbers:
              num_ids = [int(n['object']) for n in objects]
              # print("num_ids=", num_ids)
              # print("num_ids_new=", num_ids_new)
              # categories = [s['region_attributes'] for s in a['regions'].values()]
              # load_mask() needs the image size to convert polygons to masks.
              # Unfortunately, VIA doesn't include it in JSON, so we must read
              # the image. This is only managable since the dataset is tiny.
              image_path = os.path.join(dataset_dir, a['filename'])
              image = skimage.io.imread(image_path)
              height, width = image.shape[:2]
  
              self.add_image(
                  "object",
                  image_id=a['filename'],  # use file name as a unique image id
                  path=image_path,
                  width=width, height=height,
                  polygons=polygons,
                  num_ids=num_ids)
  
  
      def load_mask(self, image_id):
          """Generate instance masks for an image.
         Returns:
          masks: A bool array of shape [height, width, instance count] with
              one mask per instance.
          class_ids: a 1D array of class IDs of the instance masks.
          """
          # If not a number dataset image, delegate to parent class.
          info = self.image_info[image_id]
          if info["source"] != "object":
              return super(self.__class__, self).load_mask(image_id)
          num_ids = info['num_ids']
          # Convert polygons to a bitmap mask of shape
          # [height, width, instance_count]
          mask = np.zeros([info["height"], info["width"], len(info["polygons"])],
                          dtype=np.uint8)
  
          for i, p in enumerate(info["polygons"]):
              # Get indexes of pixels inside the polygon and set them to 1
              rr, cc = skimage.draw.polygon(p['all_points_y'], p['all_points_x'])
              mask[rr, cc, i] = 1
          # print("info['num_ids']=", info['num_ids'])
          # Map class names to class IDs.
          num_ids = np.array(num_ids, dtype=np.int32)
          return mask, num_ids
  
      def image_reference(self, image_id):
          """Return the path of the image."""
          info = self.image_info[image_id]
          if info["source"] == "object":
              return info["path"]
          else:
              super(self.__class__, self).image_reference(image_id)