You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.3 KiB
112 lines
3.3 KiB
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
|