|
@@ -9,6 +9,12 @@ import pyscreeze
|
|
|
|
|
|
pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False
|
|
|
|
|
|
+g_isDown = False
|
|
|
+
|
|
|
+def set_isDown(value):
|
|
|
+ global g_isDown
|
|
|
+ g_isDown = value
|
|
|
+
|
|
|
|
|
|
def color_string_to_rgb(color_string):
|
|
|
r = int(color_string[0:2], 16)
|
|
@@ -144,42 +150,58 @@ class pcacc_img:
|
|
|
return True, positions
|
|
|
|
|
|
@staticmethod
|
|
|
- def find_img_cv(image_path, region=None):
|
|
|
+ def find_img_cv(image_path, region=None, search_order='bottom-up'):
|
|
|
+ """
|
|
|
+ 改进版的模板匹配函数,支持从下往上搜索
|
|
|
+ :param image_path: 模板图片路径
|
|
|
+ :param region: 截图区域 (left, top, width, height)
|
|
|
+ :param search_order: 搜索顺序 ('top-down'或'bottom-up')
|
|
|
+ :return: (是否找到, 随机点坐标)
|
|
|
+ """
|
|
|
# 读取模板和屏幕截图
|
|
|
confidence_threshold = 0.95
|
|
|
-
|
|
|
template = cv2.imread(image_path, cv2.IMREAD_COLOR)
|
|
|
screenshot = cv2.cvtColor(np.array(pyautogui.screenshot(region=region)), cv2.COLOR_RGB2BGR)
|
|
|
|
|
|
# 模板匹配
|
|
|
result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
|
|
|
- _, max_val, _, max_loc = cv2.minMaxLoc(result)
|
|
|
+ width, height = template.shape[1], template.shape[0]
|
|
|
|
|
|
- if max_val > confidence_threshold: # 置信度阈值
|
|
|
- left, top = max_loc # 左上角坐标
|
|
|
- width, height = template.shape[1], template.shape[0] # 模板宽高
|
|
|
-
|
|
|
- #mid
|
|
|
- mid_left = int(left + width / 4)
|
|
|
- mid_right = int(left + width / 4 * 3)
|
|
|
- mid_top = int(top + height / 4)
|
|
|
- mid_bottom = int(top + height / 4 * 3)
|
|
|
-
|
|
|
- #want_position
|
|
|
- want_x = random.randint(mid_left, mid_right)
|
|
|
- want_y = random.randint(mid_top, mid_bottom)
|
|
|
-
|
|
|
- #dst_position
|
|
|
- dst_x = random.randint(int(want_x - width / 3), int(want_x + width / 3))
|
|
|
- dst_y = random.randint(int(want_y - height / 3), int(want_y + height / 3))
|
|
|
-
|
|
|
-
|
|
|
- print(f"{image_path}:({dst_x}, {dst_y})")
|
|
|
- return True, (dst_x, dst_y)
|
|
|
- else:
|
|
|
+ # 获取所有匹配位置[3,5](@ref)
|
|
|
+ loc = np.where(result >= confidence_threshold)
|
|
|
+ matches = list(zip(*loc[::-1])) # 转换为(x,y)坐标列表
|
|
|
+
|
|
|
+ if len(matches) == 0:
|
|
|
print(f"{image_path} cv图片未找到")
|
|
|
return False, (-1, -1)
|
|
|
-
|
|
|
+
|
|
|
+ # 根据搜索顺序排序匹配结果[7](@ref)
|
|
|
+ if search_order == 'bottom-up':
|
|
|
+ # 从下往上排序:先按y坐标降序,再按x坐标升序
|
|
|
+ matches.sort(key=lambda m: (-m[1], m[0]))
|
|
|
+ else: # 默认从上往下
|
|
|
+ matches.sort(key=lambda m: (m[1], m[0]))
|
|
|
+
|
|
|
+ # 选择第一个匹配结果(根据搜索顺序)
|
|
|
+ left, top = matches[0]
|
|
|
+
|
|
|
+ # 计算中间区域(避免点击边缘)
|
|
|
+ mid_left = int(left + width / 4)
|
|
|
+ mid_right = int(left + width / 4 * 3)
|
|
|
+ mid_top = int(top + height / 4)
|
|
|
+ mid_bottom = int(top + height / 4 * 3)
|
|
|
+
|
|
|
+ # 生成随机点击位置
|
|
|
+ want_x = random.randint(mid_left, mid_right)
|
|
|
+ want_y = random.randint(mid_top, mid_bottom)
|
|
|
+
|
|
|
+ # 添加随机偏移(避免每次都点击相同位置)
|
|
|
+ dst_x = random.randint(int(want_x - width / 3), int(want_x + width / 3))
|
|
|
+ dst_y = random.randint(int(want_y - height / 3), int(want_y + height / 3))
|
|
|
+
|
|
|
+ print(f"{image_path}:({dst_x}, {dst_y}) [搜索顺序: {search_order}]")
|
|
|
+ return True, (dst_x, dst_y)
|
|
|
+
|
|
|
@staticmethod
|
|
|
def find_img_origin(image_path):
|
|
|
# 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
|
|
@@ -199,6 +221,46 @@ class pcacc_img:
|
|
|
else:
|
|
|
print(f"{image_path}图片未找到")
|
|
|
return False, (-1, -1)
|
|
|
+
|
|
|
+ def find_img_down(image_path):
|
|
|
+ # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
|
|
|
+ confidence_threshold = 0.95
|
|
|
+
|
|
|
+ # 查找模糊图片在屏幕上的位置
|
|
|
+ positionAll = pyautogui.locateAllOnScreen(image_path, confidence=confidence_threshold)
|
|
|
+
|
|
|
+ location_list = list(positionAll)
|
|
|
+ localtion_sort = sorted(location_list, key=lambda x: x.top, reverse=True)
|
|
|
+
|
|
|
+ if len(localtion_sort) == 0:
|
|
|
+ return False, (-1, -1)
|
|
|
+
|
|
|
+ position = localtion_sort[0]
|
|
|
+ if position is not None:
|
|
|
+ # 图片找到了,获取图片的中心点坐标
|
|
|
+ #mid
|
|
|
+ mid_left = int(position.left + position.width / 4)
|
|
|
+ mid_right = int(position.left + position.width / 4 * 3)
|
|
|
+ mid_top = int(position.top + position.height / 4)
|
|
|
+ mid_bottom = int(position.top + position.height / 4 * 3)
|
|
|
+
|
|
|
+ #want_position
|
|
|
+ want_x = random.randint(mid_left, mid_right)
|
|
|
+ want_y = random.randint(mid_top, mid_bottom)
|
|
|
+
|
|
|
+ #dst_position
|
|
|
+ dst_x = random.randint(int(want_x - position.width / 3), int(want_x + position.width / 3))
|
|
|
+ dst_y = random.randint(int(want_y - position.height / 3), int(want_y + position.height / 3))
|
|
|
+
|
|
|
+
|
|
|
+ print(f"down {image_path}:({dst_x}, {dst_y})")
|
|
|
+ return True, (dst_x, dst_y)
|
|
|
+ else:
|
|
|
+ print(f"{image_path} down图片未找到")
|
|
|
+ return False, (-1, -1)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
def find_img(image_path):
|
|
@@ -234,8 +296,12 @@ class pcacc_img:
|
|
|
|
|
|
@staticmethod
|
|
|
def find_imgArr(imgArr):
|
|
|
+ global g_isDown
|
|
|
for cur_img in imgArr:
|
|
|
- ret, pos = pcacc_img.find_img(cur_img)
|
|
|
+ if g_isDown:
|
|
|
+ ret, pos = pcacc_img.find_img_down(cur_img)
|
|
|
+ else:
|
|
|
+ ret, pos = pcacc_img.find_img(cur_img)
|
|
|
if ret:
|
|
|
return ret, pos
|
|
|
return False, None
|
|
@@ -250,11 +316,15 @@ class pcacc_img:
|
|
|
|
|
|
@staticmethod
|
|
|
def find_imgs(images, is_cv=False):
|
|
|
+ global g_isDown
|
|
|
if is_cv:
|
|
|
return pcacc_img.find_imgs_cv(images)
|
|
|
else:
|
|
|
if isinstance(images, str):
|
|
|
- return pcacc_img.find_img(images)
|
|
|
+ if g_isDown:
|
|
|
+ return pcacc_img.find_img_down(images)
|
|
|
+ else:
|
|
|
+ return pcacc_img.find_img(images)
|
|
|
elif isinstance(images, (list, tuple)):
|
|
|
return pcacc_img.find_imgArr(images)
|
|
|
else:
|