matterport / Mask_RCNN

Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow
Other
24.7k stars 11.71k forks source link

Multi class Instance segmention on custom data #2348

Open bhomik77luthra opened 4 years ago

bhomik77luthra commented 4 years ago

Anyone able to do multi-class instance segmentation on custom dataset using transfer learning ? I am facing the following error :

ValueError: Error when checking input: expected input_image_meta to have shape (None, 19) but got array with shape (1, 18)

i have modified balloon.py to make it multiclass :

class BalloonConfig(Config): """Configuration for training on the toy dataset. Derives from the base Config class and overrides some values. """

Give the configuration a recognizable name

NAME = "onion"

# We use a GPU with 12GB memory, which can fit two images.
# Adjust down if you use a smaller GPU.
IMAGES_PER_GPU = 1

# Number of classes (including background)
NUM_CLASSES = 7  # Background + balloon

# Number of training steps per epoch
STEPS_PER_EPOCH = 100

# IMAGE_RESIZE_MODE = "crop"

# Skip detections with < 90% confidence
DETECTION_MIN_CONFIDENCE = 0.9

############################################################

Dataset

############################################################

class BalloonDataset(utils.Dataset):

def load_balloon(self, dataset_dir, subset):
    """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 one class to add.
    # self.add_class("balloon", 1, "balloon")

    self.add_class("onion", 1, "smut effected")
    self.add_class("onion", 2, "rotten")
    self.add_class("onion", 3, "half cut")
    self.add_class("onion", 4, "double onion")
    self.add_class("onion", 4, "sprouting")
    self.add_class("onion", 6, "onion")

    # Train or validation dataset?
    assert subset in ["train", "val"]
    dataset_dir = os.path.join(dataset_dir, subset)

    # print ('dataset_dir is ', dataset_dir)

    # Load annotations
    # VGG Image Annotator (up to version 1.6) saves each image in the form:
    # { 'filename': '28503151_5b5b7ec140_b.jpg',
    #   'regions': {
    #       '0': {
    #           'region_attributes': {},
    #           'shape_attributes': {
    #               'all_points_x': [...],
    #               'all_points_y': [...],
    #               'name': 'polygon'}},
    #       ... more regions ...
    #   },
    #   'size': 100202
    # }
    # We mostly care about the x and y coordinates of each region
    # Note: In VIA 2.0, regions was changed from a dict to a list.
    annotations = json.load(open(os.path.join(dataset_dir, "via_region_data.json")))
    annotations = list(annotations.values())  # don't need the dict keys

    # print (annotations)

    # 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. These are stores in the
        # shape_attributes (see json format above)
        # The if condition is needed to support VIA versions 1.x and 2.x.
        if type(a['regions']) is dict:
            polygons = [r['shape_attributes'] for r in a['regions'].values()]
            objects = [s['region_attributes']['onion'] for s in a['regions'].values()]
            # print ('dictionary')
        else:
            polygons = [r['shape_attributes'] for r in a['regions']] 
            objects = [s['region_attributes']['onion'] for s in a['regions']]
            # print ('list')

        # print ('objects : ', objects)
        name_dict = {"smut effected": 1,"rotten": 2, "half cut": 3, "double onion": 4, "sprouting": 5, "onion": 6}
        num_ids = [name_dict[a] for a in objects]
        # print ("num_ids : ", num_ids)
        # objects = [s['region_attributes']['onion'] for s in a['regions']]
        # print (type(polygons))
        # print (polygons)

        # 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'])
        # print (image_path)
        image = skimage.io.imread(image_path)
        height, width = image.shape[:2]
        # print (image.shape)
        # cv2.imshow("image",image)
        # cv2.waitKey(0)

        self.add_image(
            "onion",
            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)
kimile599 commented 4 years ago

I got a new problem that i have 3 classes to detect, a, b,c. When i run the detection, in most of the cases, a is detected and though b,c is also in the picture, but nothing to show. My guess is that NMS ratio is not proper, so only 1 class is detected and the proposal number is running out.