import json from typing import Sequence, Union import cv2 import numpy as np from PIL import Image from cv_analysis.utils.rectangle import Rectangle Image_t = Union[Image.Image, np.ndarray] def contour_to_rectangle(contour): return box_to_rectangle(cv2.boundingRect(contour)) def box_to_rectangle(box: Sequence[int]) -> Rectangle: x, y, w, h = box return Rectangle(x, y, x + w, y + h) def rectangle_to_box(rectangle: Rectangle) -> Sequence[int]: return [rectangle.x1, rectangle.y1, rectangle.width, rectangle.height] class RectangleJSONEncoder(json.JSONEncoder): def __init__(self, *args, **kwargs): json.JSONEncoder.__init__(self, *args, **kwargs) self._replacement_map = {} def default(self, o): if isinstance(o, Rectangle): return {"x1": o.x1, "x2": o.x2, "y1": o.y1, "y2": o.y2} else: return json.JSONEncoder.default(self, o) def encode(self, o): result = json.JSONEncoder.encode(self, o) return result def normalize_image_format_to_array(image: Image_t): return np.array(image).astype(np.uint8) if isinstance(image, Image.Image) else image def normalize_image_format_to_pil(image: Image_t): return Image.fromarray(image.astype(np.uint8)) if isinstance(image, np.ndarray) else image