def from_json(cls, data): ''' The function from_json convert ProjectMeta from json format to ProjectMeta class object. Generate exception error if all project tags not in a single collection :param data: input ProjectMeta in json format :return: ProjectMeta class object ''' tag_metas_json = data.get(ProjectMetaJsonFields.TAGS, []) img_tag_metas_json = data.get(ProjectMetaJsonFields.IMG_TAGS, []) obj_tag_metas_json = data.get(ProjectMetaJsonFields.OBJ_TAGS, []) project_type = data.get(ProjectMetaJsonFields.PROJECT_TYPE, None) if len(tag_metas_json) > 0: # New format - all project tags in a single collection. if any(len(x) > 0 for x in [img_tag_metas_json, obj_tag_metas_json]): raise ValueError( 'Project meta JSON contains both the {!r} section (current format merged tags for all of ' 'the project) and {!r} or {!r} sections (legacy format with separate collections for images ' 'and labeled objects). Either new format only or legacy format only are supported, but not a ' 'mix.'.format( ProjectMetaJsonFields.TAGS, ProjectMetaJsonFields.IMG_TAGS, ProjectMetaJsonFields.OBJ_TAGS)) tag_metas = TagMetaCollection.from_json(tag_metas_json) else: img_tag_metas = TagMetaCollection.from_json(img_tag_metas_json) obj_tag_metas = TagMetaCollection.from_json(obj_tag_metas_json) tag_metas = _merge_img_obj_tag_metas(img_tag_metas, obj_tag_metas) return cls(obj_classes=ObjClassCollection.from_json(data[ProjectMetaJsonFields.OBJ_CLASSES]), tag_metas=tag_metas, project_type=project_type)
def _model_out_tags(self): temp_collection = TagMetaCollection.from_json( self.train_config[self.classification_tags_key]) res_collection = TagMetaCollection([ TagMeta(x.name, TagValueType.ANY_NUMBER) for x in temp_collection ]) return res_collection
def __init__(self, obj_classes=None, img_tag_metas=None, obj_tag_metas=None): self._obj_classes = take_with_default(obj_classes, ObjClassCollection()) # TODO do we actualy need two sets of tags? self._img_tag_metas = take_with_default(img_tag_metas, TagMetaCollection()) self._obj_tag_metas = take_with_default(obj_tag_metas, TagMetaCollection())
def __init__(self, obj_classes=None, tag_metas=None): ''' :param obj_classes: Collection that stores ObjClass instances with unique names. :param tag_metas: Collection that stores TagMeta instances with unique names. ''' self._obj_classes = ObjClassCollection() if obj_classes is None else obj_classes self._tag_metas = take_with_default(tag_metas, TagMetaCollection())
def delete_tag_metas(self, tag_names): ''' The function delete_tag_metas delete tags with given list of names from ProjectMeta collection that stores TagMeta instances and return copy of ProjectMeta :param tag_names: list of names TagMeta objects to delete :return: ProjectMeta class object ''' res_items = self._delete_items(self._tag_metas, tag_names) return self.clone(tag_metas=TagMetaCollection(res_items))
def _replace_labels_classes(labels, obj_class_mapper: ObjClassMapper, tags_meta_mapper: TagMetaMapper, skip_missing=False) -> list: result = [] for label in labels: dest_obj_class = obj_class_mapper.map(label.obj_class) if dest_obj_class is not None: mapped_tags = TagMetaCollection(items=[ Tag(meta=tags_meta_mapper.map(tag.meta), value=tag.value) for tag in label.tags ]) result.append( label.clone(obj_class=dest_obj_class, tags=mapped_tags)) elif not skip_missing: raise KeyError( 'Object class {} could not be mapped to a destination object class.' .format(label.obj_class.name)) return result
def setUp(self): self._obj_class_gt = ObjClass(name='a', geometry_type=Rectangle) self._obj_class_pred = ObjClass(name='b', geometry_type=Rectangle) self._confidence_tag_meta = TagMeta(name='confidence', value_type=TagValueType.ANY_NUMBER) self._meta = ProjectMeta( obj_classes=ObjClassCollection([self._obj_class_gt, self._obj_class_pred]), tag_metas=TagMetaCollection([self._confidence_tag_meta])) # Will match self._pred_obj_1 self._gt_obj_1 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(0, 0, 10, 10)) # Will match self._pred_obj_3 self._gt_obj_2 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(13, 13, 15, 15)) # Will be a false negative self._gt_obj_3 = Label(obj_class=self._obj_class_gt, geometry=Rectangle(43, 43, 45, 45)) # Will match self._gt_obj_1 self._pred_obj_1 = Label( obj_class=self._obj_class_pred, geometry=Rectangle(0, 0, 9, 9), tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.7)])) # Will be a false positive (self._pred_obj_1 has higher IoU). self._pred_obj_2 = Label( obj_class=self._obj_class_pred, geometry=Rectangle(0, 0, 8, 8), tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.6)])) # Will match self._gt_obj_2 self._pred_obj_3 = Label( obj_class=self._obj_class_pred, geometry=Rectangle(13, 13, 15, 15), tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=0.1)])) # More false positives. self._pred_objs_fp = [ Label(obj_class=self._obj_class_pred, geometry=Rectangle(20, 20, 30, 30), tags=TagCollection([Tag(meta=self._confidence_tag_meta, value=v / 100)])) for v in range(15, 85, 10)] self._metric_calculator = MAPMetric(class_mapping={'a': 'b'}, iou_threshold=0.5)
def from_json(cls, data): return cls( ObjClassCollection.from_json( data[ProjectMetaJsonFields.OBJ_CLASSES]), TagMetaCollection.from_json(data[ProjectMetaJsonFields.IMG_TAGS]), TagMetaCollection.from_json(data[ProjectMetaJsonFields.OBJ_TAGS]))
def delete_obj_tag_metas(self, tag_names): res_items = self._delete_items(self._obj_tag_metas, tag_names) return self.clone(obj_tag_metas=TagMetaCollection(res_items))
def _model_out_tags(self): return TagMetaCollection() # Empty by default