# -*- coding: utf-8 -*- import pyautogui import random import time import numpy as np import cv2 from PIL import Image 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) g = int(color_string[2:4], 16) b = int(color_string[4:6], 16) return (r, g, b) def savePic(screenshot, fileName): image = Image.frombytes('RGB', screenshot.size, screenshot.bgra, 'raw', 'BGRX') image.save(fileName) # 保存为PNG格式的图像文件 def find_center_point(pointArr): min_distance = float('inf') center_point = None for point in pointArr: total_distance = 0 for other_point in pointArr: distance = ((other_point[0] - point[0]) ** 2 + (other_point[1] - point[1]) ** 2) ** 0.5 total_distance += distance if total_distance < min_distance: min_distance = total_distance center_point = point return center_point class pcacc_img: def __init__(specifically): random.seed() @staticmethod def find_maxColor_position(cur_region, colorArr): #(left, top, width, height) left = cur_region[0] top = cur_region[1] width = cur_region[2] height = cur_region[3] region = (left, top, width, height) # 目标颜色和容差值 tolerance = 10 # 容差值 # 在指定区域获取屏幕图像 screenshotSrc = pyautogui.screenshot(region=region) print(region) screenshot = np.array(screenshotSrc) dstPointArr = [] # 创建颜色范围的上下界 for color_str in colorArr: target_color = color_string_to_rgb(color_str) lower_color = np.array(target_color) - tolerance upper_color = np.array(target_color) + tolerance # 在图像中查找匹配的像素 mask = cv2.inRange(screenshot, lower_color, upper_color) # 显示 mask 图像 #plt.imshow(mask, cmap='gray') #plt.show() points = np.transpose(np.where(mask > 0)) if len(points) < 5: continue # 转换坐标到全局坐标系 points[:, 0] += region[0] points[:, 1] += region[1] ''' # 使用K-means聚类将匹配点分为不同的簇 n_clusters = 5 # 簇的数量,可根据需要进行调整 kmeans = KMeans(n_clusters=n_clusters) kmeans.fit(points) # 找到最大的簇 max_cluster_label = np.argmax(np.bincount(kmeans.labels_)) max_cluster_points = points[kmeans.labels_ == max_cluster_label] ''' # 输出最集中的像素区域的位置 for point in points: dstPointArr.append(point) if len(dstPointArr) > 0: return True, find_center_point(dstPointArr) else: return False, (-1, -1) @staticmethod def find_img_position(image_path): # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999 confidence_threshold = 0.85 # 查找模糊图片在屏幕上的位置 position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold) if position is not None: return True, position else: return False, None @staticmethod def choose_two_point_from_position(position): dst_x1 = random.randint(position.left, position.left + position.width) dst_y1 = random.randint(position.top, position.top + position.height) dst_x2 = random.randint(position.left, position.left + position.width) dst_y2 = random.randint(position.top, position.top + position.height) return (dst_x1, dst_y1), (dst_x2, dst_y2) @staticmethod def choose_one_point_from_position(position): dst_x1 = random.randint(position.left, position.left + position.width) dst_y1 = random.randint(position.top, position.top + position.height) return (dst_x1, dst_y1) @staticmethod def find_all_img(image_path): # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999 confidence_threshold = 0.95 # 查找模糊图片在屏幕上的位置 positions = pyautogui.locateAllOnScreen(image_path, confidence=confidence_threshold) if len(positions) == 0: return False, [] return True, positions @staticmethod 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) width, height = template.shape[1], template.shape[0] # 获取所有匹配位置[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 confidence_threshold = 0.95 # 查找模糊图片在屏幕上的位置 position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold) if position is not None: #dst_position dst_x = position.left dst_y = position.top print(f"{image_path} origin:({dst_x}, {dst_y})") return True, (dst_x, dst_y) else: print(f"{image_path} origin:图片未找到") 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): # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999 confidence_threshold = 0.92 # 查找模糊图片在屏幕上的位置 position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold) 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"{image_path}:({dst_x}, {dst_y})") return True, (dst_x, dst_y) else: print(f"{image_path}图片未找到") return False, (-1, -1) @staticmethod def find_imgArr(imgArr): global g_isDown for cur_img in imgArr: 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 @staticmethod def find_imgArr_cv(imgArr): for cur_img in imgArr: ret, pos = pcacc_img.find_img_cv(cur_img) if ret: return ret, pos return False, None @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): 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: raise ValueError("Invalid input type for 'images' parameter.") @staticmethod def find_imgs_cv(images): if isinstance(images, str): return pcacc_img.find_img_cv(images) elif isinstance(images, (list, tuple)): return pcacc_img.find_imgArr_cv(images) else: raise ValueError("Invalid input type for 'images' parameter.") @staticmethod def find_all_image_locations(image): confidence_threshold = 0.90 # 查找所有符合条件的图片位置 locations = pyautogui.locateAllOnScreen(image, confidence=confidence_threshold) # 将位置信息保存到列表中 image_locations = [] for location in locations: # 获取位置信息的左上角坐标和宽高 x, y, width, height = location # 将位置信息添加到列表中 image_locations.append((x, y, width, height)) return image_locations @staticmethod def find_img_in_area(image,region=None): confidence_threshold = 0.85 location = pyautogui.locateOnScreen(image,region=region, confidence=confidence_threshold) if location is not None: return True return False if __name__ == '__main__': time.sleep(2) begin = time.time() pcacc_img.find_maxColor_position((200, 200, 800, 200), {'2EA043'}) cost = time.time() - begin print("函数执行耗时:", cost, "秒")