import math
import cv2
import numpy as np
from ...transformers import json2contours
[docs]def add_area(json_object: dict) -> None:
"""
Calculate and add the area of a geometric object to a JSON annotation object.
This function takes a JSON object representing a geometric annotation in standard AxionBio format (ellipse, polygon, or circle),
calculates the area of the object, and adds it as the "area" key in the JSON object.
Args:
json_object (dict): A JSON object following the standard AxionBio format.
Raises:
ValueError: If the type of the annotation in the JSON object is not supported.
Example::
circle_json = {
"type": "circle",
"center": {"x": 10, "y": 10},
"radiusX": 5
}
add_area(circle_json)
print(circle_json)
{
"type": "circle",
"center": {"x": 10, "y": 10},
"radiusX": 5,
"area": 78.53981633974483
}
Note:
- Supported annotation types are "circle," "ellipse," and "polygon."
- The area is calculated based on the properties of the geometric object:
- For circles, it uses the formula: π * (radiusX^2)
- For ellipses, it uses the formula: π * radiusX * radiusY
- For polygons, it calculates the area using OpenCV's `cv2.contourArea` function.
"""
type_anno = json_object["type"]
if type_anno == "circle":
area = math.pi * (json_object["radiusX"] ** 2)
elif type_anno == "ellipse":
area = math.pi * json_object["radiusX"] * json_object["radiusY"]
elif type_anno == "polygon":
outer_contour = json2contours(json_object)
area = cv2.contourArea(outer_contour)
if "inner_points" in json_object:
for inner_contour in json_object["inner_points"]:
inner_contour_result = np.array(
[[i["x"], i["y"]] for i in inner_contour], dtype=np.int32
)
inner_area = cv2.contourArea(inner_contour_result)
area -= inner_area
else:
raise ValueError(f"{type_anno} is not supported")
json_object["area"] = area