import copy
import warnings
from typing import Any, Optional, Tuple
import numpy as np
import cv2
from pydantic import Field, validator
from isimple.core.config import BaseConfig
[docs]class Coo(BaseConfig):
"""Image coordinate
"""
x: float = Field(default = 0)
y: float = Field(default = 0)
def __repr__(self):
return f"Coo({self.x}, {self.y})"
@property
def rel(self) -> Tuple[float, float]:
return (self.y, self.x)
@property
def list(self) -> list:
return [self.x, self.y]
[docs]class ShapeCoo(Coo):
shape: Tuple[int, int]
def __repr__(self):
return f"Coo({self.x}, {self.y}) ~ {self.shape}"
def __eq__(self, other: object) -> bool:
assert isinstance(other, ShapeCoo)
return self.abs == other.abs and self.shape == other.shape
@property
def abs(self) -> Tuple[float, float]:
if self.shape is not None:
return (self.y * self.shape[0], self.x * self.shape[1])
else:
raise ValueError('No shape provided')
@property
def idx(self) -> Tuple[int, int]:
abs = self.abs
return (int(round(abs[0])), int(round(abs[1])))
@property
def cv2(self): # todo: the whole flip thing is confusing.
abs = self.abs
return (abs[1], abs[0])
[docs] def value(self, image: np.ndarray) -> Any:
# Image matrix should be [height x width]
assert image.shape[0:2] == self.shape
# todo: make sure x/y stuff is ok
coo_idx = self.idx
return image[
coo_idx[0], coo_idx[1]
]
[docs]class Roi(BaseConfig):
"""Region of interest"""
BL: Coo = Field(default=None)
TL: Coo = Field(default=None)
TR: Coo = Field(default=None)
BR: Coo = Field(default=None)