From 573251f1ab73a513367b63b23ef2e3aa0bc8b6b8 Mon Sep 17 00:00:00 2001 From: infstellar <98541813+infstellar@users.noreply.github.com> Date: Sat, 10 Jun 2023 22:18:44 +0800 Subject: [PATCH] fix: auto switch channels --- source/map/detection/minimap.py | 38 ++++++++++++++++++++++--------- source/map/map.py | 29 +++++++++++++++++++++-- source/mission/mission_manager.py | 2 +- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/source/map/detection/minimap.py b/source/map/detection/minimap.py index 653c9ef8..be7cc61a 100644 --- a/source/map/detection/minimap.py +++ b/source/map/detection/minimap.py @@ -12,7 +12,7 @@ THREE_CHANNEL = 3 class MiniMap(MiniMapResource): - COLOR_CHANNEL = THREE_CHANNEL + def init_position(self, position: t.Tuple[int, int]): # logger.info(f"init_position:{position}") self.position = position @@ -40,7 +40,7 @@ def get_img_near_posi(self, image, posi): search_image = crop(self.TChannelGIMAP, search_area) return search_image - def _predict_position(self, image, scale): + def _predict_position(self, image, scale, channel=ONE_CHANNEL): """ Args: image: @@ -60,9 +60,9 @@ def _predict_position(self, image, scale): search_area = area_offset((0, 0, *search_size), offset=(-search_size // 2).astype(np.int64)) search_area = area_offset(search_area, offset=np.multiply(search_position, self.POSITION_SEARCH_SCALE)) search_area = np.array(search_area).astype(np.int64) - if self.COLOR_CHANNEL == ONE_CHANNEL: + if channel == ONE_CHANNEL: search_image = crop(self.GIMAP, search_area) - elif self.COLOR_CHANNEL == THREE_CHANNEL: + elif channel == THREE_CHANNEL: search_image = crop(self.TChannelGIMAP, search_area) result = cv2.matchTemplate(search_image, local, cv2.TM_CCOEFF_NORMED) @@ -124,29 +124,39 @@ def update_position(self, origin_image): else: image = origin_image image = self._get_minimap(image, self.MINIMAP_POSITION_RADIUS) - if self.COLOR_CHANNEL == ONE_CHANNEL: - image = rgb2luma(image) - image &= self._minimap_mask - else: - image &= np.expand_dims(self._minimap_mask,axis=2).repeat(3,axis=2) + + image_one = image.copy() + image_one = rgb2luma(image) + image_one &= self._minimap_mask + + image_three = image.copy() + image_three &= np.expand_dims(self._minimap_mask,axis=2).repeat(3,axis=2) best_sim = -1. best_local_sim = -1. best_loca = (0, 0) best_scene = 'wild' for scene, scale in self._position_scale_dict.items(): - similarity, local_sim, location = self._predict_position(image, scale) + if scene == 'wild': + inp_img = image_one + channel = ONE_CHANNEL + else: + inp_img = image_three + channel = THREE_CHANNEL + similarity, local_sim, location = self._predict_position(inp_img, scale, channel=channel) # print(scene, scale, similarity, location) if similarity > best_sim: best_sim = similarity best_local_sim = local_sim best_loca = location best_scene = scene + best_channel = channel self.position_similarity = round(best_sim, 5) self.position_similarity_local = round(best_local_sim, 5) self.position = tuple(np.round(best_loca, 1)) self.scene = best_scene + self.channel = best_channel # logger.trace(f'P:({float2str(self.position[0], 4)}, {float2str(self.position[1], 4)}) ') return self.position @@ -392,14 +402,20 @@ def update_minimap(self, image): self.update_rotation(image, layer=MapConverter.LAYER_Teyvat, update_position=False) # MiniMap P:(4451.5, 3113.0) (0.184|0.050), S:wild, D:259.5 (0.949), R:180 (0.498) + + self.minimap_print_log() + + def minimap_print_log(self): logger.trace( f'MiniMap ' f'P:({float2str(self.position[0], 4)}, {float2str(self.position[1], 4)}) ' f'({float2str(self.position_similarity, 3)}|{float2str(self.position_similarity_local, 3)}), ' f'S:{self.scene}, ' f'D:{float2str(self.direction, 3)} ({float2str(self.direction_similarity, 3)}), ' + f'C:{self.channel}, ' f'R:{self.rotation} ({float2str(self.rotation_confidence)})') + def update_minimap_domain(self, image): """ Args: @@ -461,7 +477,7 @@ def is_rotation_near(self, rotation, threshold=10) -> bool: device = WindowsCapture() minimap = MiniMap(MiniMap.DETECT_Desktop_1080p) # 坐标位置是 GIMAP 的图片坐标 - minimap.init_position((5454,758)) + minimap.init_position(MapConverter.convert_cvAutoTrack_to_GIMAP([1334,-4057])) # 你可以移动人物,GIA会持续监听小地图位置和角色朝向 while 1: image = itt.capture() diff --git a/source/map/map.py b/source/map/map.py index 7bd4a34b..44a1a5c0 100644 --- a/source/map/map.py +++ b/source/map/map.py @@ -41,7 +41,7 @@ def __init__(self): self.TP_RANGE = 350 # 在该像素范围内可tp self.MINIMAP_UPDATE_LIMIT = 0.1 # minimap更新最短时间 self.MINIMAP_ERROR_BASE_LIMIT = 20 # minimap基本更新误差 - self.METER_PER_SECOND = 10+5 # 移动速度,m/s + self.METER_PER_SECOND = 25 # 移动速度,m/s self.smallmap_upd_timer = timer_module.Timer(10) self.small_map_init_flag = False @@ -49,6 +49,7 @@ def __init__(self): self.check_bigmap_timer = timer_module.Timer(5) self.init_timer = timer_module.AdvanceTimer(5) self.last_valid_position = [0,0] + self.history_position_list = [] @@ -105,6 +106,24 @@ def get_and_verify_position(self): # print(self.check_bigmap_timer.get_diff_time()) return curr_posi + def _is_reset_position(self, curr_posi, threshold=0.8): + """如果有threshold%的数据超过150,则返回True。 + + Args: + curr_posi (_type_): _description_ + threshold (float, optional): _description_. Defaults to 0.8. + + Returns: + _type_: _description_ + """ + if len(self.history_position_list) >= 20: + over_times = 0 + for i in self.history_position_list: + if euclidean_distance(i, curr_posi) >= 150: + over_times += 1 + return over_times/20 > threshold + return False + def get_position(self, is_verify_position = True): """get current character position @@ -115,17 +134,23 @@ def get_position(self, is_verify_position = True): self.reinit_smallmap() self.small_map_init_flag = True self._upd_smallmap() + self.history_position_list.append(self.position) if is_verify_position: - if self.smallmap_upd_timer.get_diff_time() <= 8: + if self._is_reset_position(self.position): + self.history_position_list = [] + else: last_dist = euclidean_distance(self.last_valid_position,self.convert_GIMAP_to_cvAutoTrack(self.position)) error_limit = self.MINIMAP_ERROR_BASE_LIMIT + self.smallmap_upd_timer.get_diff_time()*self.METER_PER_SECOND if last_dist > error_limit: logger.warning(f"migration of position {round(last_dist,2)} over limit {round(error_limit,2)}, give up position") + self.minimap_print_log() return self.last_valid_position self.smallmap_upd_timer.reset() r_posi = self.convert_GIMAP_to_cvAutoTrack(self.position) self.last_valid_position = r_posi + if len(self.history_position_list)>20: + self.history_position_list.pop(0) return r_posi def is_similarity_qualified(self, offset_rate=1): diff --git a/source/mission/mission_manager.py b/source/mission/mission_manager.py index 6b1fcc4e..00d8417e 100644 --- a/source/mission/mission_manager.py +++ b/source/mission/mission_manager.py @@ -16,7 +16,7 @@ def set_mission_list(self,mission_list:list): self.missions_list = mission_list def exec_mission(self, mission_name): - mission = missions.mission_index .get_mission_object(mission_name) + mission = missions.mission_index.get_mission_object(mission_name) self._add_sub_threading(mission, start=False) self.blocking_startup(mission) mission.stop_threading()