def assert_correct_angles( self, *, center_x: int, center_y: int, w: int = 10, h: int = 10, phi: Union[float, Tuple[float, float]], theta: Union[float, Tuple[float, float]], ): obj = DetectedROCOObject(ObjectType.ARMOR, Box.from_size(center_x - w // 2, center_y - h // 2, w, h), confidence=1) img = empty((self.h, self.w, 3)) target: SimpleTarget = self.target_factory.from_object(obj, img) if isinstance(theta, float): self.assertAlmostEqual(theta, target.theta) self.assertAlmostEqual(phi, target.phi) else: print(theta, target.theta) self.assertLess(theta[0], target.theta) self.assertGreater(theta[1], target.theta) self.assertLess(phi[0], target.phi) self.assertGreater(phi[1], target.phi)
def from_json(self, json: Json) -> ROCOObject: t: ObjectType = ObjectType(json["name"]) x1, y1, x2, y2 = ( int(float(json["bndbox"]["xmin"])), int(float(json["bndbox"]["ymin"])), int(float(json["bndbox"]["xmax"])), int(float(json["bndbox"]["ymax"])), ) x1, y1 = max(0, x1), max(0, y1) x2, y2 = min(x2, self.image_w - 1), min(y2, self.image_h - 1) box = Box.from_positions(x1, y1, x2, y2) if t is not ObjectType.ARMOR: return ROCOObject(type=t, box=box) armor_number = int(json["armor_class"]) if json["armor_class"] != "none" else 0 return Armor( type=t, box=box, number=armor_number, digit=ArmorDigit.from_number(armor_number), color=ArmorColor(json["armor_color"]), )
def _find_directions_of_close_boxes_avoidable( box: Box, boxes: List[Box], missing_width: int, missing_height: int ) -> Tuple[bool, bool, bool, bool]: left, top, right, bottom = False, False, False, False for b in boxes: dx, dy = box.distance_among_axis(b, 0), box.distance_among_axis(b, 1) if dx <= missing_width // 2 and dy <= missing_height // 2: left ^= b.x1 <= box.x1 right ^= b.x1 >= box.x1 top ^= b.y1 <= box.y1 bottom ^= b.y1 >= box.y1 if top and bottom: top, bottom = False, False if left and right: left, right = False, False return left, top, right, bottom
def _scale_annotation(annotation: ROCOAnnotation, height: int, width: int): vertical_ratio, horizontal_ratio = height / annotation.h, width / annotation.w for obj in annotation.objects: obj.box = Box.from_positions( x1=int(obj.box.x1 * horizontal_ratio), y1=int(obj.box.y1 * vertical_ratio), x2=int(obj.box.x2 * horizontal_ratio), y2=int(obj.box.y2 * vertical_ratio), ) annotation.w, annotation.h = width, height
def _re_frame_box_with_respect_of(self, box: Box, boxes: List[Box], annotation: ROCOAnnotation) -> Box: missing_width = self.w - box.w missing_height = self.h - box.h ( close_box_on_left, close_box_on_top, close_box_on_right, close_box_on_bottom, ) = self._find_directions_of_close_boxes_avoidable(box, boxes, missing_width, missing_height) dx = -(missing_width // 2) * (not close_box_on_left) * (1 + close_box_on_right) dy = -(missing_height // 2) * (not close_box_on_top) * (1 + close_box_on_bottom) x = max(0, min(annotation.w - self.w, box.x1 + dx)) y = max(0, min(annotation.h - self.h, box.y1 + dy)) return Box.from_size(x, y, self.w, self.h)
def crop_image_annotation( image: Image, annotation: ROCOAnnotation, box: Box, min_coverage: float, name: str ) -> Tuple[Image, ROCOAnnotation, str]: objects = InBoxObjectFilter(box, min_coverage).filter(annotation.objects) objects = [copy(o) for o in objects] for obj in objects: obj.box = Box.from_positions( x1=max(0, obj.box.x1 - box.x1), y1=max(0, obj.box.y1 - box.y1), x2=min(box.x2, obj.box.x2 - box.x1), y2=min(box.y2, obj.box.y2 - box.y1), ) return ( image[box.y1 : box.y2, box.x1 : box.x2], ROCOAnnotation(w=box.w, h=box.h, objects=objects, has_rune=False), name, )
def make_robots_and_armors( self, objects_params: List[ObjectParams], image: Image ) -> Tuple[List[DetectedRobot], List[DetectedArmor]]: image_height, image_width, *_ = image.shape robots, armors = [], [] for object_params in objects_params: object_type = ObjectType(self.label_map.name_of(object_params.object_class_id)) box = Box.from_positions( # TODO what about using relative coordinates ? x1=int(object_params.xmin * image_width), y1=int(object_params.ymin * image_height), x2=int(object_params.xmax * image_width), y2=int(object_params.ymax * image_height), ) if object_type is ObjectType.ARMOR: armors.append(DetectedArmor(object_type, box, object_params.score)) else: robots.append(DetectedRobot(object_type, box, object_params.score)) return robots, armors
def setUp(self) -> None: self.in_box_validator = InBoxObjectFilter(Box.from_size(2, 2, 6, 4), 0.5)
def _test_obj(self, x: int, y: int, w: int, h: int, is_inside: bool): self.assertEqual( is_inside, self.in_box_validator.validate_single( ROCOObject(ObjectType.CAR, Box.from_size(x, y, w, h))))