예제 #1
0
    def detect(self, image):

        if self.model is None:
            return {}

        image = image.convert('RGB')
        width, height = image.size
        image.thumbnail((1024, 1024))

        image = img_to_array(image)
        result = self.model.detect([image])[0]

        masks = result.get('masks')
        class_ids = result.get('class_ids')

        coco_image = im.Image(width=width, height=height)

        for i in range(masks.shape[-1]):
            mask = resize(masks[..., i], (height, width))
            mask = im.Mask(mask)
            class_id = class_ids[i]
            class_name = CLASS_NAMES[class_id]
            category = im.Category(class_name)
            coco_image.add(mask, category=category)

        return coco_image.coco()
예제 #2
0
def process_image(file, image_id):
    """ Assumes that prediction and image file have similar prefix, see below"""
    prediction = cv2.imread(os.path.join(basedir, file), cv2.IMREAD_ANYDEPTH)
    # reduce noise (makes it easier to edit predictions)
    prediction = (prediction == 19).astype('int32')
    for _ in range(2):
        prediction = sp.ndimage.median_filter(prediction, size=12)
    # remove part where there is obvious street and ego-vehicle
    prediction[700:, 500:1750] = 0
    prediction[vehicle_mask != 0] = 1

    annotation = imantics.Image(width=2048, height=1024)
    for c in categories:
        annotation.add(imantics.Mask(prediction == c), category=categories[c])
    coco_dataset['images'].append({
        'id':
        image_id,
        'dataset_id':
        1,
        'path':
        "/datasets/lostandfound/{}".format(file[:-10] + 'rgb.png'),
        'width':
        2048,
        'height':
        1024,
        'file_name':
        file[:-10] + 'rgb.png'
    })
    coco_annotations = annotation.coco()['annotations']
    for coco_annotation in coco_annotations:
        coco_annotation['id'] = 0
        coco_annotation['image_id'] = image_id
        coco_annotation['dataset_id'] = 1
    return coco_annotations
예제 #3
0
def image_to_polygon(image):
	"""Given a binary image as a numpy array:
	- converts to grayscale
	- identifies polygons
	- returns properties"""

	H, W = image.shape

	polygons = imantics.Mask(image).polygons()
	polygon = polygons  # Main polygon for now

	if len(polygon.points) == 0: return np.zeros(0)

	polygons_by_area = sorted(polygon.points, key=lambda arr: PolyArea(arr), reverse=True)
	return polygons_by_area
예제 #4
0
    def imageCallback(self, img_msg, info_msg):
        try:
            img = self.bridge.imgmsg_to_cv2(img_msg, "bgr8")
            header = img_msg.header
        except CvBridgeError as err:
            rospy.logerr(err)
            return

        board_mask = np.zeros_like(img[:, :, 0])
        if (self.image_roi is None):
            board_mask[:, :] = 1
        else:
            board_mask[self.image_roi[0]:self.image_roi[1],
                       self.image_roi[2]:self.image_roi[3]] = 1
        board_size = board_mask.sum()
        all_markers = segmentImage(img, self.filter_size, self.filter_const)
        markers_masked = (all_markers + 1) * board_mask

        filtered_idxs, filtered_counts = filterMarkers(markers_masked,
                                                       board_size / 250,
                                                       board_size / 3)
        markers_masked[np.isin(markers_masked, filtered_idxs, invert=True)] = 0
        ann_img = imantics.Image(image_array=img)
        colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255),
                  (255, 0, 255), (255, 255, 0)]
        for j, idx in enumerate(filtered_idxs):
            mask = imantics.Mask((markers_masked == idx).astype(np.uint8))
            ann = imantics.Annotation(image=ann_img,
                                      category=imantics.Category(
                                          'obj_{}'.format(j),
                                          color=imantics.Color(rgb=colors[j])),
                                      mask=mask,
                                      bbox=imantics.BBox.from_mask(mask))
            ann_img.add(ann)
        display_img = ann_img.draw(thickness=1, color_by_category=True)

        try:
            display_msg = self.bridge.cv2_to_imgmsg(display_img.astype(
                np.uint8),
                                                    encoding="bgr8")
        except CvBridgeError as err:
            rospy.logerr(err)
            return

        display_msg.header = img_msg.header
        self.image_pub.publish(display_msg)
예제 #5
0
def annotations_from_mask_instance_segmentation(class_ids, masks):
    annotations = []
    for i, class_id in enumerate(class_ids):
        im_mask = imantics.Mask(masks[i])
        polygons = im_mask.polygons()
        polygons_new = []
        for poly in polygons:
            polygons_new.append(poly.tolist())

        annotation = {
            "category_id": int(class_id) + 1,
            "segmentation": polygons_new,
            "bbox": list(im_mask.bbox().bbox()),
        }

        annotations.append(annotation)

    return annotations
예제 #6
0
def save_non_overlapping_annotations_json(json_path, save_json_path):
    coco = COCO(json_path)
    with open(json_path) as json_file:
        coco_json = json.load(json_file)

    coco_json_new = {}
    coco_json_new["categories"] = coco_json["categories"]
    coco_json_new["images"] = coco_json["images"]

    new_annotations = []
    for img_count, img_id in enumerate(coco.imgs.keys()):

        annotations = coco.loadAnns(coco.getAnnIds(img_id))
        mask = get_mask_handle_occlusion(annotations, width=640, height=480)

        for i, class_id in enumerate(mask[1]):
            im_mask = imantics.Mask(mask[0][:, :, i])
            polygons = im_mask.polygons()
            polygons_new = []
            for poly in polygons:
                polygons_new.append(poly.tolist())

            new_annotation = {
                "id": len(new_annotations),
                "image_id": img_id,
                "category_id": int(class_id),
                "segmentation": polygons_new,
                "bbox": list(im_mask.bbox().bbox()),
                'iscrowd': False,
                'isbbox': False
            }
            new_annotations.append(new_annotation)

            sys.stdout.write('\rremoved overlapping for ' +
                             str(img_count + 1) + ' / ' +
                             str(len(coco.imgs.keys())) + ' images')
            sys.stdout.flush()

    print("")

    coco_json_new["annotations"] = new_annotations
    with open(save_json_path, 'w') as outfile:
        json.dump(coco_json_new, outfile)
예제 #7
0
def annotations_from_mask_semantic_segmentation(mask):
    annotations = []
    for class_id in np.unique(mask):
        if class_id == 0:
            continue
        class_mask = (mask == class_id)
        im_mask = imantics.Mask(class_mask)
        polygons = im_mask.polygons()
        polygons_new = []
        for poly in polygons:
            polygons_new.append(poly.tolist())

        annotation = {
            "category_id": int(class_id),
            "segmentation": polygons_new,
            "bbox": list(im_mask.bbox().bbox()),
        }
        annotations.append(annotation)

    return annotations
예제 #8
0
def transform_instance_annotations(annotation,
                                   transforms,
                                   image_size,
                                   *,
                                   keypoint_hflip_indices=None,
                                   image_id=None):
    """
    Apply transforms to box, segmentation and keypoints of annotations of a single instance.

    It will use `transforms.apply_box` for the box, and
    `transforms.apply_coords` for segmentation polygons & keypoints.
    If you need anything more specially designed for each data structure,
    you'll need to implement your own version of this function or the transforms.

    Args:
        annotation (dict): dict of instance annotations for a single instance.
        transforms (TransformList):
        image_size (tuple): the height, width of the transformed image
        keypoint_hflip_indices (ndarray[int]): see `create_keypoint_hflip_indices`.
        image_id: Only used for debugging.
    Returns:
        dict:
            the same input dict with fields "bbox", "segmentation", "keypoints"
            transformed according to `transforms`.
            The "bbox_mode" field will be set to XYXY_ABS.
    """
    bbox = BoxMode.convert(annotation["bbox"], annotation["bbox_mode"],
                           BoxMode.XYXY_ABS)
    # Note that bbox is 1d (per-instance bounding box)
    annotation["bbox"] = transforms.apply_box([bbox])[0]
    annotation["bbox_mode"] = BoxMode.XYXY_ABS

    # Old version
    # # each instance contains 1 or more polygons
    # polygons = [np.asarray(p).reshape(-1, 2) for p in annotation["segmentation"]]
    # annotation["segmentation"] = [p.reshape(-1) for p in transforms.apply_polygons(polygons)]

    # Copied from updated version of detectron2
    if "segmentation" in annotation:
        # each instance contains 1 or more polygons
        segm = annotation["segmentation"]
        if isinstance(segm, list):
            # polygons
            polygons = [np.asarray(p).reshape(-1, 2) for p in segm]
            annotation["segmentation"] = [
                p.reshape(-1) for p in transforms.apply_polygons(polygons)
            ]

        elif isinstance(segm, dict):
            # RLE
            im_sz = segm['size']
            H, W = im_sz
            bitmask = mask_util.decode(segm)
            # Convert to polygons
            polygons_transf = imantics.Mask(bitmask).polygons().points

            segms = [
                p.reshape(-1)
                for p in transforms.apply_polygons(polygons_transf)
            ]

            good_polygons = []
            bad_polygons = []
            # Get rid of 'bad' polygons that detectron2/COCO format won't accept.
            for poly_i, polygon in enumerate(segms):
                if not (len(polygon) % 2 == 0 and len(polygon) >= 6):
                    bad_polygons.append(polygon)
                    continue
                if len(
                        polygon
                ) == 8:  # old version of pycocoutils is dumb about 'bounding box'-looking things
                    new_polygon = np.ndarray((10, ), dtype=polygon.dtype)
                    new_polygon[:8] = polygon
                    new_polygon[8:] = polygon[:2]
                    good_polygons.append(new_polygon)
                else:
                    good_polygons.append(polygon)
            segms = good_polygons

            if len(bad_polygons) > 0:
                logger = logging.getLogger(__name__)
                logger.warning(f"Dropped a tiny polygon from {image_id}")

                # Debug only (should never happen after we weeded out the bad ones)
                for poly_i, polygon in enumerate(segms):
                    assert len(polygon.shape) == 1
                    if not (len(polygon) % 2 == 0 and len(polygon) >= 6):
                        raise Exception

            annotation["segmentation"] = segms
        else:
            raise ValueError(
                "Cannot transform segmentation of type '{}'!"
                "Supported types are: polygons as list[list[float] or ndarray],"
                " COCO-style RLE as a dict.".format(type(segm)))

    if "keypoints" in annotation:
        keypoints = transform_keypoint_annotations(annotation["keypoints"],
                                                   transforms, image_size,
                                                   keypoint_hflip_indices)
        annotation["keypoints"] = keypoints

    return annotation