2222from aao .utils .logger import logger
2323
2424# MAA 常量(1280×720)
25- _FLAG_ROI = [33 , 600 , 1245 , 18 ]
26- _FLAG_THRESHOLD = 0.65
27- _AVATAR_OFFSET = [- 35 , 39 , 45 , 46 ] # BattleOperAvatar rectMove
28- _NAME_ROI = [3 , 195 , 192 , 35 ] # BattleOperName OCR roi
2925_DETAIL_WAIT = 0.5 # 等详情页打开
3026
3127
@@ -37,6 +33,22 @@ def _avatar_dir() -> Path:
3733 return d
3834
3935
36+ def _match_avatar_roi_offset () -> tuple [int , int , int , int ]:
37+ """读取 reco.json 中 MatchAvatar.roi_offset(flag_rect → avatar_rect)。"""
38+ from aao .utils .runtime_paths import project_root
39+
40+ path = project_root () / "resource" / "base" / "pipeline" / "reco.json"
41+ raw = json .loads (path .read_text (encoding = "utf-8" ))
42+ offset = raw ["MatchAvatar" ].get ("roi_offset" , [0 , 0 , 0 , 0 ])
43+ return tuple (int (v ) for v in offset ) # type: ignore[return-value]
44+
45+
46+ def _apply_roi_offset (rect : tuple [int , int , int , int ]) -> tuple [int , int , int , int ]:
47+ ox , oy , ow , oh = _match_avatar_roi_offset ()
48+ x , y , w , h = rect
49+ return x + ox , y + oy , w + ow , h + oh
50+
51+
4052def _get_char_id (oper_name : str ) -> str :
4153 from aao .utils .runtime_paths import project_root
4254
@@ -59,24 +71,9 @@ def _normalize_name(name: str) -> str:
5971def detect_slots (
6072 context : Context ,
6173 image : np .ndarray ,
62- threshold : float = _FLAG_THRESHOLD ,
6374) -> list [dict ]:
64- """用 TemplateMatch 检测待部署区所有干员槽位。"""
65- reco_detail = context .run_recognition (
66- "DetectSlots" ,
67- image ,
68- pipeline_override = {
69- "DetectSlots" : {
70- "recognition" : "TemplateMatch" ,
71- "template" : "BattleOpersFlag.png" ,
72- "threshold" : threshold ,
73- "roi" : _FLAG_ROI ,
74- "method" : 5 ,
75- "green_mask" : True ,
76- "order_by" : "Horizontal" ,
77- }
78- },
79- )
75+ """用 pipeline 节点 DetectSlots 检测待部署区所有干员槽位。"""
76+ reco_detail = context .run_recognition ("DetectSlots" , image )
8077
8178 if not reco_detail or not reco_detail .hit :
8279 return []
@@ -86,17 +83,15 @@ def detect_slots(
8683 box = getattr (result , "box" , None )
8784 if box is None :
8885 continue
89- fx , fy , fw , fh = box
90- ax = int (fx + _AVATAR_OFFSET [0 ])
91- ay = int (fy + _AVATAR_OFFSET [1 ])
92- aw = _AVATAR_OFFSET [2 ]
93- ah = _AVATAR_OFFSET [3 ]
86+ fx , fy , fw , fh = (int (v ) for v in box )
87+ flag_rect = (fx , fy , fw , fh )
88+ avatar_rect = _apply_roi_offset (flag_rect )
9489 click_x = int (fx - 45 + 75 // 2 )
9590 click_y = int (fy + 6 + 120 // 2 )
9691 slots .append (
9792 {
98- "flag_rect" : ( int ( fx ), int ( fy ), int ( fw ), int ( fh )) ,
99- "avatar_rect" : ( ax , ay , aw , ah ) ,
93+ "flag_rect" : flag_rect ,
94+ "avatar_rect" : avatar_rect ,
10095 "click_pos" : (click_x , click_y ),
10196 }
10297 )
@@ -137,18 +132,16 @@ def locate_oper(
137132 if char_id and (_avatar_dir () / f"{ char_id } .png" ).exists ():
138133 for i , slot in enumerate (slots ):
139134 ax , ay , aw , ah = slot ["avatar_rect" ]
140- roi = [max (0 , ax - 5 ), max (0 , ay - 5 ), aw + 10 , ah + 10 ]
135+ # MatchAvatar 的 roi_offset 写在 pipeline/reco.json 中;这里动态传 flag_rect。
136+ roi = list (slot ["flag_rect" ])
141137
142138 reco = context .run_recognition (
143- f"MatchAvatar_ { char_id } _ { i } " ,
139+ "MatchAvatar " ,
144140 image ,
145141 pipeline_override = {
146- f"MatchAvatar_{ char_id } _{ i } " : {
147- "recognition" : "TemplateMatch" ,
142+ "MatchAvatar" : {
148143 "template" : f"avatar/{ char_id } .png" ,
149- "threshold" : 0.7 ,
150144 "roi" : roi ,
151- "method" : 5 ,
152145 }
153146 },
154147 )
@@ -196,18 +189,7 @@ def locate_oper(
196189
197190def _ocr_oper_name (context : Context , detail_img : np .ndarray ) -> str | None :
198191 """OCR 读取详情页干员名。"""
199- reco = context .run_recognition (
200- "OcrOperName" ,
201- detail_img ,
202- pipeline_override = {
203- "OcrOperName" : {
204- "recognition" : "OCR" ,
205- "roi" : _NAME_ROI ,
206- "threshold" : 0.3 ,
207- "order_by" : "Area" ,
208- }
209- },
210- )
192+ reco = context .run_recognition ("OcrOperName" , detail_img )
211193
212194 if not reco or not reco .hit :
213195 return None
0 commit comments