예제 #1
0
def crop_image_mask_and_save(image, outputs, result_images_dir, vis):

    masks = np.asarray(outputs["instances"].pred_masks)
    masks = [
        GenericMask(x, vis.output.height, vis.output.width) for x in masks
    ]

    areas = np.asarray([x.area() for x in masks])

    sorted_idxs = np.argsort(-areas).tolist()
    masks = [masks[idx] for idx in sorted_idxs]
    boxes = [outputs["instances"].pred_boxes[idx] for idx in sorted_idxs]

    for i, box in zip(range(len(masks)), boxes):
        background = np.ones(image.shape, dtype=np.uint8)
        background.fill(255)

        for j, segment in enumerate(masks[i].polygons):
            item_mask = np.array([segment.reshape(-1, 2)], dtype=np.int32)
            cv2.fillPoly(background, item_mask, 0)

        masked_image = cv2.bitwise_or(image, background)
        x1, y1, x2, y2 = [round(cord) for cord in box.tensor.tolist()[0]]
        crop_img = masked_image[y1:y2, x1:x2]

        cropped_image_path = Path(result_images_dir,
                                  f"{uuid.uuid4()}.jpg").as_posix()
        cv2.imwrite(cropped_image_path, crop_img)
예제 #2
0
    def format_results(self, class_names):
        """
        Format results so they can be used by overlay_instances function
        """
        predictions = self.outputs['instances']
        boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None
        scores = predictions.scores if predictions.has("scores") else None
        classes = predictions.pred_classes if predictions.has("pred_classes") else None

        labels = None 
        if classes is not None and class_names is not None and len(class_names) > 1:
            labels = [class_names[i] for i in classes]
        if scores is not None:
            if labels is None:
                labels = ["{:.0f}%".format(s * 100) for s in scores]
            else:
                labels = ["{} {:.0f}%".format(l, s * 100) for l, s in zip(labels, scores)]

        masks = predictions.pred_masks.cpu().numpy()
        masks = [GenericMask(x, v.output.height, v.output.width) for x in masks]

        boxes_list = boxes.tensor.tolist()
        scores_list = scores.tolist()
        class_list = classes.tolist()

        for i in range(len(scores_list)):
            boxes_list[i].append(scores_list[i])
            boxes_list[i].append(class_list[i])
        

        boxes_list = np.array(boxes_list)

        return (masks, boxes, boxes_list, labels, scores_list, class_list, classes)
예제 #3
0
	def return_attributes(self, path):
		im = cv2.imread(path)
		output = self.predictor(im)
		print('STATUS: Detectron2 job done.')

		self.SCORE_THRESHOLD = 0.7
		AREA_FRACTION_THRESHOLD = 0.1

		# storing attributes
		predictions = output["instances"].to("cpu")
		scores = predictions.scores if predictions.has("scores") else None
		classes = predictions.pred_classes if predictions.has("pred_classes") else None

		if predictions.has("pred_masks"):
				masks = [GenericMask(x, im.shape[0], im.shape[1]) for x in np.asarray(predictions.pred_masks)]
		else:
			masks = None

		humans = (classes==0).nonzero().reshape(-1).numpy()
		if(humans.shape[0]==0):
			return None
		temp = []
		for i in range(len(humans)):
			if(scores[humans[i]]>self.SCORE_THRESHOLD and masks[i].area()/(im.shape[0] * im.shape[1])>self.AREA_FRACTION_THRESHOLD):
			# if(True):
				temp.append(humans[i])

		humans = temp
		human_masks = []

		for i in range(len(masks)):
			if(i in humans):
				human_masks.append(masks[i])

		return im, human_masks
예제 #4
0
    def draw_instance_predictions(self, predictions):
        """
        Draw instance-level prediction results on an image.
        Args:
            predictions (Instances): the output of an instance detection/segmentation
                model. Following fields will be used to draw:
                "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle").
        Returns:
            output (VisImage): image object with visualizations.
        """
        boxes = predictions.pred_boxes if predictions.has(
            "pred_boxes") else None
        scores = predictions.scores if predictions.has("scores") else None
        classes = predictions.pred_classes if predictions.has(
            "pred_classes") else None
        contacts = predictions.pred_cats if predictions.has(
            "pred_cats") else None
        scores = contacts * scores.reshape(-1, 1)

        labels, dis_colors = _create_custom_text_labels(
            classes, scores, "hand", self.scores_thresh)
        keypoints = predictions.pred_keypoints if predictions.has(
            "pred_keypoints") else None

        if predictions.has("pred_masks"):
            masks = np.asarray(predictions.pred_masks)
            masks = [
                GenericMask(x, self.output.height, self.output.width)
                for x in masks
            ]
        else:
            masks = None

        if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get(
                "thing_colors"):
            colors = [
                self._jitter([x / 255 for x in self.metadata.thing_colors[c]])
                for c in classes
            ]
            alpha = 0.8
        else:
            colors = None
            alpha = 0.5

        if self._instance_mode == ColorMode.IMAGE_BW:
            self.output.img = self._create_grayscale_image((
                predictions.pred_masks.any(dim=0) > 0
            ).numpy() if predictions.has("pred_masks") else None)
            alpha = 0.3

        self.overlay_instances(
            masks=masks,
            boxes=None,
            labels=labels,
            keypoints=keypoints,
            assigned_colors=dis_colors,
            alpha=alpha,
        )
        return self.output
예제 #5
0
    def draw_instance_predictions(self, predictions):
        """
        Draw instance-level prediction results on an image.
        Args:
            predictions (Instances): the output of an instance detection/segmentation
                model. Following fields will be used to draw:
                "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle").
        Returns:
            output (VisImage): image object with visualizations.
        """
        #boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None
        boxes = None
        scores = predictions.scores if predictions.has("scores") else None
        classes = predictions.pred_classes if predictions.has(
            "pred_classes") else None
        #labels = _create_text_labels(classes, scores, self.metadata.get("thing_classes", None))
        labels = None
        keypoints = predictions.pred_keypoints if predictions.has(
            "pred_keypoints") else None

        if predictions.has("pred_masks"):
            masks = np.asarray(predictions.pred_masks)
            masks = [
                GenericMask(x, self.output.height, self.output.width)
                for x in masks
            ]
        else:
            masks = None

        colors = []
        alpha = 0.8
        for c in classes:
            color = (0, 1, 1, 1)  #Green
            if c == 0:
                color = (1, 1, 0, 1)  #Yellow Line
            if c == 1:
                color = (0.8, 0.8, 1, 1)  #White Line
            if c == 4:
                color = (1, 0, 0, 1)  #Red line
            if c == 2:
                color = (0, 1, 0, 1)  #Obstacle
            colors.append(color)

        if self._instance_mode == ColorMode.IMAGE_BW:
            self.output.img = self._create_grayscale_image((
                predictions.pred_masks.any(dim=0) > 0
            ).numpy() if predictions.has("pred_masks") else None)
            alpha = 0.3

        self.overlay_instances(
            masks=masks,
            boxes=boxes,
            labels=labels,
            keypoints=keypoints,
            assigned_colors=colors,
            alpha=alpha,
        )
        return self.output
예제 #6
0
def predict_image(im):
    cfg = get_cfg()

    # add project-specific config (e.g., TensorMask) here if you're not
    #   running a model in detectron2's core library
    cfg.merge_from_file(
        model_zoo.get_config_file(
            "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5  # set threshold for this model

    # Find a model from detectron2's model zoo. You can
    #   use the https://dl.fbaipublicfiles... url as well
    cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(
        "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
    predictor = DefaultPredictor(cfg)
    outputs = predictor(im)
    '''
    look at the outputs. See
    https://detectron2.readthedocs.io/tutorials/models.html#model-output-format
    for specification
    '''
    print(outputs["instances"].pred_classes)
    print(outputs["instances"].pred_boxes)

    # We can use `Visualizer` to draw the predictions on the image.
    '''
    v = Visualizer(im[:, :, ::-1], MetadataCatalog.get(cfg.DATASETS.TRAIN[0]),
                   scale=1.2)
    '''
    v = Visualizer(np.zeros_like(im),
                   MetadataCatalog.get(cfg.DATASETS.TRAIN[0]),
                   scale=1.0)
    im_mask = np.zeros_like(im, np.uint8)

    if outputs["instances"].has("pred_masks"):
        masks = np.asarray(outputs["instances"].to("cpu").pred_masks)
        value_statis(masks, 'massk1')
        print('masks1: {}'.format(type(masks)))

        for idx_i in range(masks.shape[0]):
            im_mask[masks[idx_i, :, :]] = idx_i * 2 + 10

        masks = [
            GenericMask(x, v.output.height, v.output.width) for x in masks
        ]

        print('masks2: {}'.format(type(masks)))
        num_instance = len(v._convert_masks(masks))
        print('  -> num_instances: {}'.format(num_instance))
        out = v.overlay_instances(masks=masks)
    else:
        out = v.draw_instance_predictions(outputs["instances"].to("cpu"))

    value_statis(out.get_image(), 'out.get_image()')
    value_statis(im_mask, 'im_mask')

    # return out.get_image()
    return im_mask
예제 #7
0
    def draw_instance_predictions(self, predictions, track_ids):
        """
        Draw instance-level prediction results on an image.

        Args:
            predictions (Instances): the output of an instance detection/segmentation
                model. Following fields will be used to draw:
                "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle").

        Returns:
            output (VisImage): image object with visualizations.
        """
        boxes = predictions.pred_boxes if predictions.has(
            "pred_boxes") else None
        scores = predictions.scores if predictions.has("scores") else None
        classes = predictions.pred_classes if predictions.has(
            "pred_classes") else None
        labels = _create_text_labels(classes, scores,
                                     self.metadata.get("thing_classes", None))
        keypoints = predictions.pred_keypoints if predictions.has(
            "pred_keypoints") else None

        if predictions.has("pred_masks"):
            masks = np.asarray(predictions.pred_masks)
            masks = [
                GenericMask(x, self.output.height, self.output.width)
                for x in masks
            ]
        else:
            masks = None

        # set the color according to the track ids
        colors = [cm.tab20(id_) for id_ in track_ids]
        alpha = 0.6

        labels = [
            f'Track {id_} {label}' for label, id_ in zip(labels, track_ids)
        ]

        # increase font size
        if self._default_font_size < 20: self._default_font_size *= 1.3

        if self._instance_mode == ColorMode.IMAGE_BW:
            assert predictions.has(
                "pred_masks"), "ColorMode.IMAGE_BW requires segmentations"
            self.output.img = self._create_grayscale_image(
                (predictions.pred_masks.any(dim=0) > 0).numpy())

        self.overlay_instances(
            masks=masks,
            boxes=boxes,
            labels=labels,
            keypoints=keypoints,
            assigned_colors=colors,
            alpha=alpha,
        )
        return self.output
def create_annotated_scan(original, mask, output_dir, suffix):
    original = original.copy()
    mask = GenericMask(mask, *mask.shape)
    polygons = [poly.reshape(-1, 2) for poly in mask.polygons]
    cv2.polylines(original,
                  polygons,
                  isClosed=True,
                  color=(0, 255, 0),
                  thickness=3)
    cv2.imwrite(os.path.join(output_dir, f'{suffix}.jpg'), original)
    return cv2.imread(os.path.join(output_dir, f'{suffix}.jpg'))
예제 #9
0
def format_predictions(predictions, height, width):
    masks = np.asarray(predictions.pred_masks)
    masks = [GenericMask(mask, height, width) for mask in masks]
    # boxes = predictions.pred_boxes if predictions.has("pred_boxes") else [mask.bbox() for mask in masks]
    classes = predictions.pred_classes if predictions.has(
        "pred_classes") else [None for _ in masks]
    areas = [mask.area() for mask in masks]

    return [(reshape_and_close_poly(mask.polygons[0]), area, cls)
            for mask, area, cls in zip(masks, classes, areas)
            if len(mask.polygons) > 0]
예제 #10
0
def predOneImg(predictor, imgNameFull, annoResName, visRoot, thing_classes, divNum=2, isVis = 0):

    img = cv2.imread(imgNameFull)
    hImg, wImg = img.shape[0], img.shape[1]
    stepH, stepW = int(hImg/divNum), int(wImg/divNum)
    imgName = str.split(imgNameFull, '/')[-1]
    resDict = {'filename':imgName, 'labels':[]}
    for ii in range(len(thing_classes)):
        resDict['labels'].append({'name':thing_classes[ii], 'annotations':[]})
    if isVis == 1:
        vPoly = Visualizer(img[:, :, ::-1],
                           scale=1.0,
                           instance_mode=ColorMode.IMAGE_BW
                           )
    segmentCount = 0
    for ii in range(divNum):
        startH = ii * stepH
        endH = hImg if ii == divNum - 1 else  stepH*(ii + 1) -1
        for jj in range(divNum):
            print(ii, jj)
            startW = jj * stepW
            endW = wImg if jj == divNum - 1 else stepW * (jj + 1) -1
            tmpImg = img[startH:endH+1, startW:endW+1, :]
            outputs = predictor(tmpImg)
            res = outputs["instances"].to("cpu")
            height = res.image_size[0]
            width = res.image_size[1]
            masks = [GenericMask(x.numpy(), height, width).mask_to_polygons(x.numpy()) for x in res.pred_masks]
            # masks1 = [x[0][0].reshape(-1, 2)+[startW, startH] for x in masks]
            labels = [int(x.numpy()) for x in res.pred_classes]
            colorMaps = [[0., 0., 1.], [1., 0., 0.], [1.0, 0.3, .5]]
            for ll in range(len(labels)):
                tmpLabel = thing_classes[labels[ll]]
                if len(masks[ll][0]) == 0:
                    continue
                tmpsegmentNP = masks[ll][0][0].reshape(-1, 2)+[startW, startH]
                tmpsegmentRDP = rdp(tmpsegmentNP, epsilon=6)
                tmpsegment = tmpsegmentRDP.reshape(-1, 1).squeeze().tolist()
                tmpInst = {'id':segmentCount, 'segmentation':tmpsegment}
                for cc in range(len(resDict['labels'])):
                    if resDict['labels'][cc]['name'] == tmpLabel:
                        resDict['labels'][cc]['annotations'].append(tmpInst)
                        if isVis ==  1:
                            vPoly.output = vPoly.draw_polygon(tmpsegmentRDP, colorMaps[cc], alpha=0.3)
                            # plt.imshow(vPoly.output.get_image()[:, :, ::-1])
                            # plt.show()
                segmentCount += 1

    with open(annoResName, 'w') as fp:
        json.dump(resDict, fp)
    if isVis == 1:
        picName = os.path.join(visRoot, imgName)
        plt.imsave(picName, vPoly.output.get_image()[:, :, ::-1])
예제 #11
0
def unwrap(predictions, imageShape):
    boxes = predictions.pred_boxes.tensor.numpy() if predictions.has(
        "pred_boxes") else None
    scores = predictions.scores.numpy() if predictions.has("scores") else None
    classes = predictions.pred_classes.numpy() if predictions.has(
        "pred_classes") else None
    if predictions.has("pred_masks"):
        masks = np.asarray(predictions.pred_masks)
        masks = [
            GenericMask(x, imageShape[0], imageShape[1]).mask for x in masks
        ]
    else:
        masks = None
    return boxes, masks, scores, classes
def to_polygons(predictions):
    if type(predictions) == np.ndarray:
        masks = [
            GenericMask(predictions, predictions.shape[0],
                        predictions.shape[1])
        ]
    else:
        boxes = predictions.pred_boxes if predictions.has(
            "pred_boxes") else None
        scores = predictions.scores if predictions.has("scores") else None
        classes = predictions.pred_classes if predictions.has(
            "pred_classes") else None
        keypoints = predictions.pred_keypoints if predictions.has(
            "pred_keypoints") else None
        if not predictions.has('pred_masks'):
            return None

        masks = np.asarray(predictions.pred_masks)
        masks = [GenericMask(x, x.shape[0], x.shape[1]) for x in masks]

    polygons = [
        poly.reshape(-1, 2) for mask in masks for poly in mask.polygons
    ]
    return polygons
def extract_predictions(predictions):
    if not predictions.has('pred_masks'):
        return None, None

    masks = np.asarray(predictions.pred_masks)
    if masks.shape[0] == 0:
        return None, None

    mask = np.zeros_like(masks[0, :, :])
    for m in masks:
        mask |= m

    masks = [GenericMask(m, m.shape[0], m.shape[1]) for m in masks]

    polygons = [
        poly.reshape(-1, 2) for mask in masks for poly in mask.polygons
    ]
    return polygons, mask
예제 #14
0
def get_labeled_seg(predictions,
                    score_threshold,
                    vis,
                    assigned_colors=None,
                    paper_img=False):
    boxes = predictions.pred_boxes
    scores = predictions.scores
    classes = predictions.pred_classes
    chosen = (scores > score_threshold).nonzero()[0]
    boxes = boxes[chosen]
    scores = scores[chosen]
    classes = classes[chosen]
    # labels = list(range(len(predictions)))
    labels = [f"{idx}: {score:.2f}" for idx, score in enumerate(scores)]
    masks = np.asarray(predictions.pred_masks)
    masks = [
        GenericMask(x, vis.output.height, vis.output.width) for x in masks
    ]
    alpha = 0.5

    if vis._instance_mode == ColorMode.IMAGE_BW:
        vis.output.img = vis._create_grayscale_image(
            (predictions.pred_masks.any(dim=0) > 0).numpy())
        alpha = 0.3
    if paper_img:
        boxes = None
        labels = None
    vis.overlay_instances(
        masks=masks,
        assigned_colors=assigned_colors,
        boxes=boxes,
        labels=labels,
        alpha=alpha,
    )
    seg_pred = vis.output.get_image()
    return seg_pred
예제 #15
0
    def draw_instance_predictions(self, predictions):
        """
        :param predictions:
        :return: Besides the functions of its mother class method, this method deals with extreme points.
        """
        ext_points = predictions.ext_points if predictions.has(
            "ext_points") else None
        pred_polys = predictions.pred_polys if predictions.has(
            "pred_polys") else None
        if False:
            return super().draw_instance_predictions(predictions)
        else:
            boxes = predictions.pred_boxes if predictions.has(
                "pred_boxes") else None
            scores = predictions.scores if predictions.has("scores") else None
            classes = predictions.pred_classes if predictions.has(
                "pred_classes") else None
            labels = _create_text_labels(
                classes, scores, self.metadata.get("thing_classes", None))
            keypoints = predictions.pred_keypoints if predictions.has(
                "pred_keypoints") else None

            if predictions.has("pred_masks"):
                masks = np.asarray(predictions.pred_masks)
                masks = [
                    GenericMask(x, self.output.height, self.output.width)
                    for x in masks
                ]
            else:
                if predictions.has("pred_polys"):
                    output_height = predictions.image_size[0]
                    output_width = predictions.image_size[1]
                    pred_masks = get_polygon_rles(
                        predictions.pred_polys.flatten(),
                        (output_height, output_width))

                    masks = np.asarray(pred_masks)
                    masks = [
                        GenericMask(x, self.output.height, self.output.width)
                        for x in masks
                    ]
                else:
                    masks = None

            path = predictions.pred_path.numpy() if predictions.has(
                "pred_path") else None

            if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get(
                    "thing_colors"):
                colors = [
                    self._jitter(
                        [x / 255 for x in self.metadata.thing_colors[c]])
                    for c in classes
                ]
                alpha = 0.8
            else:
                colors = None
                alpha = 0.5

            if self._instance_mode == ColorMode.IMAGE_BW:
                assert predictions.has(
                    "pred_masks"), "ColorMode.IMAGE_BW requires segmentations"
                self.output.img = self._create_grayscale_image(
                    (predictions.pred_masks.any(dim=0) > 0).numpy())
                alpha = 0.3

            self.overlay_instances(
                masks=masks,
                boxes=boxes,
                labels=labels,
                ext_points=ext_points,
                path=path,
                keypoints=keypoints,
                assigned_colors=colors,
                alpha=alpha,
            )
            return self.output
예제 #16
0
    def run_on_image(self, image, debug):
        """
        Args:
            image (np.ndarray): an image of shape (H, W, C) (in BGR order).
                This is the format used by OpenCV.

        Returns:
            predictions (dict): the output of the model.
            vis_output (VisImage): the visualized image output.
        """
        vis_output = None
        obj = None
        predictions = self.predictor(image.astype(np.uint8))
        # Convert image from OpenCV BGR format to Matplotlib RGB format.
        image = image[:, :, ::-1]
        visualizer = Visualizer(image,
                                self.metadata,
                                instance_mode=self.instance_mode)
        if "panoptic_seg" in predictions:
            panoptic_seg, segments_info = predictions["panoptic_seg"]
            vis_output = visualizer.draw_panoptic_seg_predictions(
                panoptic_seg.to(self.cpu_device), segments_info)
            if debug:
                print('in panoptic_seg')
        else:
            if "sem_seg" in predictions:
                vis_output = visualizer.draw_sem_seg(
                    predictions["sem_seg"].argmax(dim=0).to(self.cpu_device))
                if debug:
                    print("in sem_seg")
            if "instances" in predictions:
                instances = predictions["instances"].to(self.cpu_device)

                if debug:
                    vis_output = visualizer.draw_instance_predictions(
                        predictions=instances)
                    print('in instances')

                #if output is json, debug is false
                if not debug:
                    boxes = instances.pred_boxes.tensor.numpy(
                    ) if instances.has("pred_boxes") else None
                    scores = instances.scores if instances.has(
                        'scores') else None
                    classes = instances.pred_classes if instances.has(
                        "pred_classes") else None
                    labels = _create_text_labels(
                        classes, scores,
                        visualizer.metadata.get("thing_classes", None))
                    keypoints = instances.pred_keypoints if instances.has(
                        "pred_keypoints") else None

                    if instances.has("pred_masks"):
                        masks = np.asarray(instances.pred_masks)
                        masks = [
                            GenericMask(x, visualizer.output.height,
                                        visualizer.output.width) for x in masks
                        ]
                    else:
                        masks = None

                    obj = {}

                    for i, _ in enumerate(labels):
                        tmp = {}
                        split = labels[i].split()
                        tmp['class'] = split[0]
                        tmp['score'] = scores[i].item()
                        tmp['box'] = {}
                        tmp['box']['left-up'] = [
                            boxes[i][0].item(), boxes[i][1].item()
                        ]
                        tmp['box']['right-down'] = [
                            boxes[i][2].item(), boxes[i][3].item()
                        ]
                        tmp['polygons'] = {}

                        if masks is not None:
                            for idx, segment in enumerate(masks[i].polygons):
                                tmp['polygons'][idx] = segment.reshape(
                                    -1, 2).tolist()

                        obj[i] = tmp

        return predictions, vis_output, obj
예제 #17
0
def main(args):
    # # register dataset
    # register_coco_instances(name="cause_brain_2019_train", metadata={},
    #                         json_file="./datasets/coco/annotations/instances_train2019.json",
    #                         image_root="./datasets/coco/train2019")
    #
    # register_coco_instances(name="cause_brain_2019_val", metadata={},
    #                         json_file="./datasets/coco/annotations/instances_valid2019.json",
    #                         image_root="./datasets/coco/valid2019")
    #
    # register_coco_instances(name="cause_brain_2019_test", metadata={},
    #                         json_file="./datasets/coco/annotations/instances_test2019.json",
    #                         image_root="./datasets/coco/test2019")

    cfg = setup(args, eval=True)

    # os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)

    # evaluate trained model
    if not args.masks_only:
        os.makedirs(os.path.join(cfg.OUTPUT_DIR, "inference"), exist_ok=True)
        os.makedirs(os.path.join(cfg.OUTPUT_DIR, "masks"), exist_ok=True)

    # # COCO OUTPUT:
    #
    # # setup trainer and evaluate
    # trainer = DefaultTrainer(cfg)
    # evaluator = COCOEvaluator(dataset_name="balloon_val", cfg=cfg, distributed=False, output_dir="./output/")
    # val_loader = build_detection_test_loader(cfg, "balloon_val")
    # print(inference_on_dataset(trainer.model, val_loader, evaluator))
    # # another equivalent way is to use trainer.test

    # MASK OUTPUT:

    predictor = DefaultPredictor(cfg)

    # dataset_dicts = DatasetCatalog.get(cfg.DATASETS.TEST[0])
    metadata = MetadataCatalog.get(cfg.DATASETS.TEST[0])
    class_names = metadata.get("thing_classes", None)

    for filename in get_paths(args.input):
        basename = os.path.basename(filename)

        # logger.info("Loading: " + filename)
        im = cv2.imread(filename)

        outputs = predictor(im)
        if len(outputs['instances']) > 0:
            if len(outputs['instances']) > 0:
                instances = outputs["instances"].to("cpu")

                scores = instances.scores
                logger.info("Scores" + str(scores))
                classes = instances.pred_classes.numpy()
                # labels = _create_text_labels(classes, scores, metadata.get("thing_classes", None))
                labels = [class_names[i] for i in classes]

                # logger.info("MASKS {}".format(instances.pred_masks))

                try:
                    masks = np.asarray(instances.pred_masks)
                    masks = [
                        GenericMask(x, im.shape[0], im.shape[1]) for x in masks
                    ]

                    # print(filename)
                    # print("Masks")
                    # print(labels)
                    for i in range(len(masks)):
                        name, ext = tuple(os.path.splitext(basename))
                        output_filename = name + "_" + labels[i] + ext
                        output_path = os.path.join(
                            cfg.OUTPUT_DIR, "" if args.masks_only else "masks",
                            output_filename)

                        draw_polygons(im.shape[0], im.shape[1],
                                      masks[i].polygons, output_path)
                        # for segment in masks[i].polygons:
                        #     print(i, segment.reshape(-1, 2).shape, labels[i])

                    if not args.masks_only:
                        vis = Visualizer(
                            im[:, :, ::-1],
                            metadata=metadata,
                            scale=2.0,
                        )

                        vis = vis.draw_instance_predictions(
                            outputs["instances"].to("cpu"))
                        vis.save(
                            os.path.join(cfg.OUTPUT_DIR, "inference",
                                         basename))
                except AttributeError:
                    logger.error("No segmentation exists!")
            else:
                logger.info('No Instances found!')
예제 #18
0
def main(dataRoot, testDir, annoRoot, taskName):
    testFunc = createDataFunc(testDir, annoRoot)
    DatasetCatalog.register("TestSetBatch", testFunc)
    MetadataCatalog.get('TestSetBatch').set(
        thing_classes=['Houses', 'Buildings', 'Sheds/Garages'])

    visRoot = os.path.join(dataRoot, 'visRes')
    predVisRoot = os.path.join(visRoot, 'predRes')
    predPlVisRoot = os.path.join(visRoot, 'predPolyRes')
    predMkVisRoot = os.path.join(visRoot, 'predMaskRes')
    if not os.path.exists(visRoot):
        os.mkdir(visRoot)
    if not os.path.exists(predVisRoot):
        os.mkdir(predVisRoot)
    if not os.path.exists(predPlVisRoot):
        os.mkdir(predPlVisRoot)
    if not os.path.exists(predMkVisRoot):
        os.mkdir(predMkVisRoot)
    cfg = get_cfg()
    cfg.merge_from_file(
        "Cfg/COCO-InstanceSegmentation/mask_rcnn_R_101_FPN_3x.yaml")
    cfg.DATASETS.TRAIN = ("TrainSetBatch", )
    cfg.DATALOADER.NUM_WORKERS = 24
    cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 512
    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 3
    cfg.OUTPUT_DIR = './' + taskName + '_output'
    cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth")
    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5  #测试的阈值
    predictor = DefaultPredictor(cfg)

    import cv2
    import matplotlib.pyplot as plt
    from detectron2.utils.visualizer import Visualizer, ColorMode, GenericMask
    dataset_dicts = testFunc()
    meta_dicts = MetadataCatalog.get('TestSetBatch')
    from rdp import rdp
    for ii in range(0, len(dataset_dicts)):
        img = cv2.imread(dataset_dicts[ii]["file_name"])
        vPred = Visualizer(img[:, :, ::-1],
                           metadata=meta_dicts,
                           scale=1.0,
                           instance_mode=ColorMode.IMAGE_BW)
        vPoly = Visualizer(img[:, :, ::-1],
                           metadata=meta_dicts,
                           scale=1.0,
                           instance_mode=ColorMode.IMAGE_BW)
        vMask = Visualizer(img[:, :, ::-1],
                           metadata=meta_dicts,
                           scale=1.0,
                           instance_mode=ColorMode.IMAGE_BW)
        outputs = predictor(img)
        res = outputs["instances"].to("cpu")
        vPred.output = vPred.draw_instance_predictions(res)

        picName = str.split(dataset_dicts[ii]["file_name"], '/')[-1]
        picName = os.path.join(predVisRoot, picName)
        plt.imsave(picName, vPred.output.get_image()[:, :, ::-1])

        height = res.image_size[0]
        width = res.image_size[1]
        masks = [
            GenericMask(x.numpy(), height, width).mask_to_polygons(x.numpy())
            for x in res.pred_masks
        ]
        masksBin = [
            GenericMask(x.numpy(), height, width).mask for x in res.pred_masks
        ]
        labels = [int(x.numpy()) for x in res.pred_classes]

        count = 0
        colorMaps = [[0., 0., 1.], [1., 0., 0.], [1.0, 0.3, .5]]
        for mask in masks:
            colorIn = colorMaps[labels[count]]
            maskRaw = mask[0][0].reshape(-1, 2)
            maskSim = rdp(maskRaw, epsilon=6)
            vPoly.output = vPoly.draw_polygon(maskSim, colorIn, alpha=0.3)
            vMask.output = vMask.draw_binary_mask(masksBin[count],
                                                  colorIn,
                                                  alpha=0.3)
            count += 1
        picName = str.split(dataset_dicts[ii]["file_name"], '/')[-1]
        picName = os.path.join(predPlVisRoot, picName)
        plt.imsave(picName, vPoly.output.get_image()[:, :, ::-1])

        picName = str.split(dataset_dicts[ii]["file_name"], '/')[-1]
        picName = os.path.join(predMkVisRoot, picName)
        plt.imsave(picName, vMask.output.get_image()[:, :, ::-1])
예제 #19
0
    def draw_instance_predictions(self, predictions, category=None):
        """
        Draw instance-level prediction results on an image.

        Args:
            predictions (Instances): the output of an instance detection/segmentation
                model. Following fields will be used to draw:
                "pred_boxes", "pred_classes", "scores", "pred_masks" (or "pred_masks_rle").
            category: the integer category for the desired annotation to display as a list or None if all of them

        Returns:
            output (VisImage): image object with visualizations.
        """

        # start additional code
        if category == None:
            boxes = predictions.pred_boxes if predictions.has(
                "pred_boxes") else None
            scores = predictions.scores if predictions.has("scores") else None
            classes = predictions.pred_classes if predictions.has(
                "pred_classes") else None
            labels = self._create_text_labels(
                classes, scores, self.metadata.get("thing_classes", None))
            keypoints = predictions.pred_keypoints if predictions.has(
                "pred_keypoints") else None
        else:
            all_boxes = predictions.pred_boxes if predictions.has(
                "pred_boxes") else None
            all_scores = predictions.scores if predictions.has(
                "scores") else None
            all_classes = predictions.pred_classes if predictions.has(
                "pred_classes") else None
            all_labels = self._create_text_labels(
                all_classes, all_scores,
                self.metadata.get("thing_classes", None))
            all_keypoints = predictions.pred_keypoints if predictions.has(
                "pred_keypoints") else None

            boxes = [] if all_boxes != None else None
            scores = [] if all_scores != None else None
            classes = [] if all_classes != None else None
            labels = [] if all_labels != None else None
            keypoints = [] if all_keypoints != None else None

            for c in category:
                for i in range(0, len(all_classes)):
                    if all_classes[i] == c:
                        classes.append(all_classes[i])

                        if all_boxes != None:
                            boxes.append(all_boxes[i])
                        if all_scores != None:
                            scores.append(all_scores[i])
                        if all_labels != None:
                            labels.append(all_labels[i])
                        if all_keypoints != None:
                            keypoints.append(all_keypoints[i])

            if boxes != None and len(boxes) > 0:
                boxes = Boxes(torch.cat([b.tensor for b in boxes], dim=0))
            if scores != None and len(scores) > 0:
                scores = torch.stack(scores)
            if classes != None and len(classes) > 0:
                classes = torch.stack(classes)
        # end additional code

        # removed alpha from here and put it as fixed value
        if predictions.has("pred_masks"):
            masks = np.asarray(predictions.pred_masks)
            masks = [
                GenericMask(x, self.output.height, self.output.width)
                for x in masks
            ]
        else:
            masks = None
        if self._instance_mode == ColorMode.SEGMENTATION and self.metadata.get(
                "thing_colors"):
            colors = [
                self._jitter([x / 255 for x in self.metadata.thing_colors[c]])
                for c in classes
            ]
        else:
            colors = None
        if self._instance_mode == ColorMode.IMAGE_BW:
            self.output.img = self._create_grayscale_image(
                (predictions.pred_masks.any(dim=0) > 0).numpy())

        self.overlay_instances(labels=labels,
                               boxes=boxes,
                               masks=masks,
                               keypoints=keypoints,
                               assigned_colors=colors,
                               alpha=1)
        return self.output
예제 #20
0
def iou_metrics(det_masks: List[np.ndarray],
                gt_masks: List[np.ndarray],
                tp_threshold=0.5,
                det_bboxes=None,
                gt_bboxes=None):
    """
    iou metric in one frame
    :param dets:
    :param gts:
    :param tp_threshold:
    :return:
    """
    FNs = []
    FPs = []
    TPs = []

    # create iou mapping. only above threshold objects are recorded
    iou_map = {}  # [i_det][i_gt]=iou
    iou_rev_map = {}  # [i_gt][i_det]=iou

    # create bboxes if bboxes are not provided
    if gt_bboxes is None:
        gt_bboxes = [GenericMask(m, *m.shape).bbox() for m in gt_masks]
    if det_bboxes is None:
        det_bboxes = [GenericMask(m, *m.shape).bbox() for m in det_masks]

    for i_gt, i_det in product(range(len(gt_masks)), range(len(det_masks))):
        gt_mask = gt_masks[i_gt]
        det_mask = det_masks[i_det]

        gt_bbox = gt_bboxes[i_gt]
        det_bbox = det_bboxes[i_det]

        # use bbox to determine if iou should be calculated
        if bbox_iou(gt_bbox, det_bbox) < tp_threshold:
            continue

        iou_value = compute_iou(gt_mask, det_mask)
        if iou_value >= tp_threshold:
            iou_map.setdefault(i_det, {})[i_gt] = iou_value
            iou_rev_map.setdefault(i_gt, {})[i_det] = iou_value

    for i_gt, _ in enumerate(gt_masks):
        # False Negative: gt no det
        if i_gt not in iou_rev_map:
            FNs.append(i_gt)
        else:
            dets_of_gt: dict = iou_rev_map[i_gt]
            if len(dets_of_gt) == 1:
                # single TP
                TPs.append((list(dets_of_gt.keys())[0], i_gt))
            else:
                # multiple det on same GT
                dets_sorted = sorted(dets_of_gt.items(), key=lambda x: x[1])
                TPs.append((dets_sorted[0][0], i_gt))
                for det_lower_iou, _ in enumerate(dets_sorted[1:]):
                    FPs.append(det_lower_iou)

    for i_det, _ in enumerate(det_masks):
        # False Positive: det no gt
        if i_det not in iou_map:
            FPs.append(i_det)

    tp_ious = [iou_map[tp[0]][tp[1]] for tp in TPs]

    # precision:
    precision_ious = [0] * len(FPs) + tp_ious
    precision = np.mean(precision_ious)

    # recall:
    common_recall_ious = [0] * len(FNs) + [
        1 if x > tp_threshold else 0 for x in tp_ious
    ]
    common_recall = np.mean(common_recall_ious)
    recall_ious = [0] * len(FNs) + tp_ious
    recall = np.mean(recall_ious)

    return {
        "FPs": FPs,
        "TPs": TPs,
        "FNs": FNs,
        "iou_map": iou_map,
        "iou_rev_map": iou_rev_map,
        "precision": precision,
        "recall": recall,
        "common_recall": common_recall,
        "precision_ious": precision_ious,
        "recall_ious": recall_ious,
        "common_recall_ious": common_recall_ious,
    }