import numpy as np
from . import BaseAnnotationDefinition
[docs]class Ellipse(BaseAnnotationDefinition):
"""
Ellipse annotation object
"""
type = "ellipse"
def __init__(self, x, y, rx, ry, angle, label, attributes=None, description=None):
super().__init__(description=description, attributes=attributes)
self.label = label
self.angle = angle
self.x = x
self.y = y
self.rx = rx
self.ry = ry
@property
def geo(self):
return np.asarray([[self.x, self.y],
[self.rx, self.ry],
[self.angle, self.rad]])
@property
def rad(self):
return np.deg2rad(self.angle)
@property
def left(self):
return self.x - np.sqrt(np.power(self.rx, 2) * np.power(np.cos(-self.rad), 2)
+ np.power(self.ry, 2) * np.power(np.sin(-self.rad), 2))
@property
def top(self):
return self.y - np.sqrt(np.power(self.rx, 2) * np.power(np.sin(-self.rad), 2)
+ np.power(self.ry, 2) * np.power(np.cos(-self.rad), 2))
@property
def right(self):
return self.x + np.sqrt(np.power(self.rx, 2) * np.power(np.cos(-self.rad), 2)
+ np.power(self.ry, 2) * np.power(np.sin(-self.rad), 2))
@property
def bottom(self):
return self.y + np.sqrt(np.power(self.rx, 2) * np.power(np.sin(-self.rad), 2)
+ np.power(self.ry, 2) * np.power(np.cos(-self.rad), 2))
[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
if thickness is None:
thickness = 2
# draw annotation
image = cv2.ellipse(
image,
center=(int(np.round(self.x)), int(np.round(self.y))),
axes=(int(np.round(self.rx)), int(np.round(self.ry))),
angle=self.angle,
startAngle=0,
endAngle=360,
color=color,
thickness=thickness,
lineType=-1,
)
if with_text:
image = self.add_text_to_image(image=image, annotation=self)
return image
def to_coordinates(self, color):
return {'angle': float(self.angle),
'center': {'x': float(self.x),
'y': float(self.y),
'z': 0},
'rx': float(self.rx),
'ry': float(self.ry)}
@staticmethod
def from_coordinates(coordinates):
angle = coordinates["angle"]
x = coordinates["center"]["x"]
y = coordinates["center"]["y"]
rx = coordinates["rx"]
ry = coordinates["ry"]
return x, y, rx, ry, angle
@classmethod
def from_json(cls, _json):
if "coordinates" in _json:
x, y, rx, ry, angle = cls.from_coordinates(_json["coordinates"])
elif "data" in _json:
x, y, rx, ry, angle = cls.from_coordinates(_json["data"])
else:
raise ValueError('can not find "coordinates" or "data" in annotation. id: {}'.format(_json["id"]))
return cls(
angle=angle,
x=x,
y=y,
rx=rx,
ry=ry,
label=_json["label"],
attributes=_json.get("attributes", None),
)