Source code for dtlpy.entities.annotation_definitions.cube

import math
import numpy as np

from . import BaseAnnotationDefinition


[docs]class Cube(BaseAnnotationDefinition): """ Cube annotation object """ type = "cube" def __init__(self, label, front_tl, front_tr, front_br, front_bl, back_tl, back_tr, back_br, back_bl, angle=None, attributes=None, description=None): super().__init__(description=description, attributes=attributes) self.front_bl = front_bl self.front_br = front_br self.front_tr = front_tr self.front_tl = front_tl self.back_bl = back_bl self.back_br = back_br self.back_tr = back_tr self.back_tl = back_tl self._angle = angle self.label = label self.keys = ["front_tl", "front_tr", "front_br", "front_bl", "back_tl", "back_tr", "back_br", "back_bl"] @staticmethod def calculate_angle(b, c): a = [b[0] + 200, b[1]] if b in (a, c): return 0 ang = math.degrees( math.atan2(c[1] - b[1], c[0] - b[0]) - math.atan2(a[1] - b[1], a[0] - b[0])) return ang + 360 if ang < 0 else ang @property def angle(self): if self._angle is None: self._angle = Cube.calculate_angle(self.front_tl, self.front_tr) return self._angle @property def x(self): return self.geo[:, 0] @property def y(self): return self.geo[:, 1] @property def geo(self): return np.asarray([self.front_tl, self.front_tr, self.front_br, self.front_bl, self.back_tl, self.back_tr, self.back_br, self.back_bl ])
[docs] def show(self, image, thickness, with_text, height, width, annotation_format, color, alpha=1): """ Show annotation as ndarray :param image: empty or image to draw on :param thickness: :param with_text: not required :param height: item height :param width: item width :param annotation_format: options: list(dl.ViewAnnotationOptions) :param color: color :param alpha: opacity value [0 1], default 1 :return: ndarray """ try: import cv2 except (ImportError, ModuleNotFoundError): self.logger.error( 'Import Error! Cant import cv2. Annotations operations will be limited. import manually and fix errors') raise image = cv2.polylines(image, pts=[np.asarray( [self.front_bl, self.front_br, self.front_tr, self.front_tl]).round().astype(int)], isClosed=True, color=color, thickness=thickness) image = cv2.polylines(image, pts=[np.asarray([self.back_bl, self.back_br, self.back_tr, self.back_tl]).round().astype( int)], isClosed=True, color=color, thickness=thickness) image = cv2.line(image, pt1=tuple(np.asarray(self.front_bl).round().astype(int)), pt2=tuple(np.asarray(self.back_bl).round().astype(int)), color=color, thickness=thickness) image = cv2.line(image, pt1=tuple(np.asarray(self.front_br).round().astype(int)), pt2=tuple(np.asarray(self.back_br).round().astype(int)), color=color, thickness=thickness) image = cv2.line(image, pt1=tuple(np.asarray(self.front_tl).round().astype(int)), pt2=tuple(np.asarray(self.back_tl).round().astype(int)), color=color, thickness=thickness) image = cv2.line(image, pt1=tuple(np.asarray(self.front_tr).round().astype(int)), pt2=tuple(np.asarray(self.back_tr).round().astype(int)), color=color, thickness=thickness) return image
def to_coordinates(self, color): coordinates = {self.keys[idx]: {"x": float(x), "y": float(y), "z": 0} for idx, [x, y] in enumerate(self.geo)} coordinates['angle'] = self.angle return coordinates @staticmethod def from_coordinates(coordinates): geo = list() for key, pt in enumerate(coordinates): geo.append([pt["x"], pt["y"]]) return np.asarray(geo) @classmethod def from_json(cls, _json): if "coordinates" in _json: key = "coordinates" elif "data" in _json: key = "data" else: raise ValueError('can not find "coordinates" or "data" in annotation. id: {}'.format(_json["id"])) return cls( front_bl=np.asarray([_json[key]["front_bl"]['x'], _json[key]["front_bl"]['y']]), front_br=np.asarray([_json[key]["front_br"]['x'], _json[key]["front_br"]['y']]), front_tl=np.asarray([_json[key]["front_tl"]['x'], _json[key]["front_tl"]['y']]), front_tr=np.asarray([_json[key]["front_tr"]['x'], _json[key]["front_tr"]['y']]), back_bl=np.asarray([_json[key]["back_bl"]['x'], _json[key]["back_bl"]['y']]), back_br=np.asarray([_json[key]["back_br"]['x'], _json[key]["back_br"]['y']]), back_tl=np.asarray([_json[key]["back_tl"]['x'], _json[key]["back_tl"]['y']]), back_tr=np.asarray([_json[key]["back_tr"]['x'], _json[key]["back_tr"]['y']]), label=_json["label"], angle=_json[key]["angle"], attributes=_json.get("attributes", None) ) @staticmethod def rotate(center, point, angle): angle = math.radians(angle) cx, cy = center px, py = point qx = cx + math.cos(angle) * (px - cx) - math.sin(angle) * (py - cy) qy = cy + math.sin(angle) * (px - cx) + math.cos(angle) * (py - cy) return [qx, qy]
[docs] @classmethod def from_boxes_and_angle(cls, front_left, front_top, front_right, front_bottom, back_left, back_top, back_right, back_bottom, label, angle=0, attributes=None): """ Create cuboid by given front and back boxes with angle the angle calculate fom the center of each box """ if angle != 0: front_center = [front_left + (front_right - front_left) / 2, front_top + (front_bottom - front_top) / 2] back_center = [back_left + (back_right - back_left) / 2, back_top + (back_bottom - back_top) / 2] front_tl = Cube.rotate(center=front_center, point=[front_left, front_top], angle=angle) front_tr = Cube.rotate(center=front_center, point=[front_right, front_top], angle=angle) front_br = Cube.rotate(center=front_center, point=[front_right, front_bottom], angle=angle) front_bl = Cube.rotate(center=front_center, point=[front_left, front_bottom], angle=angle) back_tl = Cube.rotate(center=back_center, point=[back_left, back_top], angle=angle) back_tr = Cube.rotate(center=back_center, point=[back_right, back_top], angle=angle) back_br = Cube.rotate(center=back_center, point=[back_right, back_bottom], angle=angle) back_bl = Cube.rotate(center=back_center, point=[back_left, back_bottom], angle=angle) else: front_tl = [front_left, front_top] front_tr = [front_right, front_top] front_br = [front_right, front_bottom] front_bl = [front_left, front_bottom] back_tl = [back_left, back_top] back_tr = [back_right, back_top] back_br = [back_right, back_bottom] back_bl = [back_left, back_bottom] return cls( front_tl=front_tl, front_tr=front_tr, front_br=front_br, front_bl=front_bl, back_tl=back_tl, back_tr=back_tr, back_br=back_br, back_bl=back_bl, label=label, angle=angle, attributes=attributes )