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()
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
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
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)
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
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)
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
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