from dataclasses import dataclass, field from typing import Optional, Dict import numpy as np from dataclasses_json import dataclass_json, config import utils @dataclass_json @dataclass class Point: x:float y:float def __iter__(self): # 使对象可迭代,可直接转为元组 yield self.x yield self.y @dataclass class RectangleArea: x: int y: int w: int h: int @classmethod def from_dict(cls, data: dict): return cls( x=data['x'], y=data['y'], w=data['w'], h = data['h']) @dataclass class Threshold: binary: int gauss: int @dataclass_json @dataclass class TargetInfo: # 标靶方形区域 rectangle_area:RectangleArea threshold:Threshold # 标靶物理半径 radius:float=0.0 id:int =-1 desc:str="" base:bool=False def __init__(self,id,desc,rectangle_area:RectangleArea,radius,threshold:Threshold,base:bool,**kwargs): self.id = id self.desc = desc self.rectangle_area=rectangle_area self.radius=radius self.threshold=threshold self.base=base @classmethod def from_dict(cls,data: dict): return cls(data['id'],data['rectangle_area'],data['radius']) @dataclass_json @dataclass class HandlerInfo: # 初始话 is_init=True radius_pix:float= 1.0 pix_length:float=0.0 # 标靶中心 center_point: Optional[Point]= field(default=None, metadata=config(exclude=lambda x: x is None)) center_init : Optional[Point]= field(default=None, metadata=config(exclude=lambda x: x is None)) # 标靶位移(像素) displacement_pix: Optional[Point]= field(default=None, metadata=config(exclude=lambda x: x is None)) displacement_phy: Optional[Point]= field(default=None, metadata=config(exclude=lambda x: x is None)) @dataclass_json @dataclass class CircleTarget: # 标靶方形区域 info:TargetInfo # 标靶透视矩阵 perspective: np.ndarray = field( metadata=config( encoder=utils.encode_perspective, decoder=utils.decode_perspective ) ) handler_info: Optional[HandlerInfo]=None # def __init__(self,info:TargetInfo,center_point,center_init,displacement_pix,displacement_phy): # self.info=info # self.center_point=center_point # self.center_init=center_init # self. displacement_pix=displacement_pix # self.displacement_phy=displacement_phy @classmethod def init_by_info(cls,t:TargetInfo): return CircleTarget(t,None,None,None,None) def circle_displacement(self): previous = self.handler_info.center_init if previous != (): self.handler_info.displacement_pix = Point(self.handler_info.center_point.x - previous.x, self.handler_info.center_point.y - previous.y) if self.info.radius != 0: # 单位像素距离 self.handler_info.pix_length = self.info.radius / self.handler_info.radius_pix offset_x = round(float(self.handler_info.displacement_pix.x * self.handler_info.pix_length), 5) offset_y = round(float(self.handler_info.displacement_pix.y * self.handler_info.pix_length), 5) self.handler_info.displacement_phy = Point(offset_x, offset_y) return self