imgFind.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. # -*- coding: utf-8 -*-
  2. import pyautogui
  3. import random
  4. import time
  5. import numpy as np
  6. import cv2
  7. from PIL import Image
  8. import pyscreeze
  9. pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False
  10. def color_string_to_rgb(color_string):
  11. r = int(color_string[0:2], 16)
  12. g = int(color_string[2:4], 16)
  13. b = int(color_string[4:6], 16)
  14. return (r, g, b)
  15. def savePic(screenshot, fileName):
  16. image = Image.frombytes('RGB', screenshot.size, screenshot.bgra, 'raw', 'BGRX')
  17. image.save(fileName) # 保存为PNG格式的图像文件
  18. def find_center_point(pointArr):
  19. min_distance = float('inf')
  20. center_point = None
  21. for point in pointArr:
  22. total_distance = 0
  23. for other_point in pointArr:
  24. distance = ((other_point[0] - point[0]) ** 2 + (other_point[1] - point[1]) ** 2) ** 0.5
  25. total_distance += distance
  26. if total_distance < min_distance:
  27. min_distance = total_distance
  28. center_point = point
  29. return center_point
  30. class pcacc_img:
  31. def __init__(specifically):
  32. random.seed()
  33. @staticmethod
  34. def find_maxColor_position(cur_region, colorArr): #(left, top, width, height)
  35. left = cur_region[0]
  36. top = cur_region[1]
  37. width = cur_region[2]
  38. height = cur_region[3]
  39. region = (left, top, width, height)
  40. # 目标颜色和容差值
  41. tolerance = 10 # 容差值
  42. # 在指定区域获取屏幕图像
  43. screenshotSrc = pyautogui.screenshot(region=region)
  44. print(region)
  45. screenshot = np.array(screenshotSrc)
  46. dstPointArr = []
  47. # 创建颜色范围的上下界
  48. for color_str in colorArr:
  49. target_color = color_string_to_rgb(color_str)
  50. lower_color = np.array(target_color) - tolerance
  51. upper_color = np.array(target_color) + tolerance
  52. # 在图像中查找匹配的像素
  53. mask = cv2.inRange(screenshot, lower_color, upper_color)
  54. # 显示 mask 图像
  55. #plt.imshow(mask, cmap='gray')
  56. #plt.show()
  57. points = np.transpose(np.where(mask > 0))
  58. if len(points) < 5:
  59. continue
  60. # 转换坐标到全局坐标系
  61. points[:, 0] += region[0]
  62. points[:, 1] += region[1]
  63. '''
  64. # 使用K-means聚类将匹配点分为不同的簇
  65. n_clusters = 5 # 簇的数量,可根据需要进行调整
  66. kmeans = KMeans(n_clusters=n_clusters)
  67. kmeans.fit(points)
  68. # 找到最大的簇
  69. max_cluster_label = np.argmax(np.bincount(kmeans.labels_))
  70. max_cluster_points = points[kmeans.labels_ == max_cluster_label]
  71. '''
  72. # 输出最集中的像素区域的位置
  73. for point in points:
  74. dstPointArr.append(point)
  75. if len(dstPointArr) > 0:
  76. return True, find_center_point(dstPointArr)
  77. else:
  78. return False, (-1, -1)
  79. @staticmethod
  80. def find_img_position(image_path):
  81. # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
  82. confidence_threshold = 0.85
  83. # 查找模糊图片在屏幕上的位置
  84. position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)
  85. if position is not None:
  86. return True, position
  87. else:
  88. return False, None
  89. @staticmethod
  90. def choose_two_point_from_position(position):
  91. dst_x1 = random.randint(position.left, position.left + position.width)
  92. dst_y1 = random.randint(position.top, position.top + position.height)
  93. dst_x2 = random.randint(position.left, position.left + position.width)
  94. dst_y2 = random.randint(position.top, position.top + position.height)
  95. return (dst_x1, dst_y1), (dst_x2, dst_y2)
  96. @staticmethod
  97. def choose_one_point_from_position(position):
  98. dst_x1 = random.randint(position.left, position.left + position.width)
  99. dst_y1 = random.randint(position.top, position.top + position.height)
  100. return (dst_x1, dst_y1)
  101. @staticmethod
  102. def find_all_img(image_path):
  103. # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
  104. confidence_threshold = 0.95
  105. # 查找模糊图片在屏幕上的位置
  106. positions = pyautogui.locateAllOnScreen(image_path, confidence=confidence_threshold)
  107. if len(positions) == 0:
  108. return False, []
  109. return True, positions
  110. @staticmethod
  111. def find_img_cv(image_path, region=None):
  112. # 读取模板和屏幕截图
  113. confidence_threshold = 0.95
  114. template = cv2.imread(image_path, cv2.IMREAD_COLOR)
  115. screenshot = cv2.cvtColor(np.array(pyautogui.screenshot(region=region)), cv2.COLOR_RGB2BGR)
  116. # 模板匹配
  117. result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
  118. _, max_val, _, max_loc = cv2.minMaxLoc(result)
  119. if max_val > confidence_threshold: # 置信度阈值
  120. left, top = max_loc # 左上角坐标
  121. width, height = template.shape[1], template.shape[0] # 模板宽高
  122. #mid
  123. mid_left = int(left + width / 4)
  124. mid_right = int(left + width / 4 * 3)
  125. mid_top = int(top + height / 4)
  126. mid_bottom = int(top + height / 4 * 3)
  127. #want_position
  128. want_x = random.randint(mid_left, mid_right)
  129. want_y = random.randint(mid_top, mid_bottom)
  130. #dst_position
  131. dst_x = random.randint(int(want_x - width / 3), int(want_x + width / 3))
  132. dst_y = random.randint(int(want_y - height / 3), int(want_y + height / 3))
  133. print(f"{image_path}:({dst_x}, {dst_y})")
  134. return True, (dst_x, dst_y)
  135. else:
  136. print(f"{image_path} cv图片未找到")
  137. return False, (-1, -1)
  138. @staticmethod
  139. def find_img_origin(image_path):
  140. # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
  141. confidence_threshold = 0.95
  142. # 查找模糊图片在屏幕上的位置
  143. position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)
  144. if position is not None:
  145. #dst_position
  146. dst_x = position.left
  147. dst_y = position.top
  148. print(f"{image_path}:({dst_x}, {dst_y})")
  149. return True, (dst_x, dst_y)
  150. else:
  151. print(f"{image_path}图片未找到")
  152. return False, (-1, -1)
  153. def find_img(image_path):
  154. # 设置查找的置信度(confidence)阈值,范围从0到1,默认为0.999
  155. confidence_threshold = 0.92
  156. # 查找模糊图片在屏幕上的位置
  157. position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)
  158. if position is not None:
  159. # 图片找到了,获取图片的中心点坐标
  160. #mid
  161. mid_left = int(position.left + position.width / 4)
  162. mid_right = int(position.left + position.width / 4 * 3)
  163. mid_top = int(position.top + position.height / 4)
  164. mid_bottom = int(position.top + position.height / 4 * 3)
  165. #want_position
  166. want_x = random.randint(mid_left, mid_right)
  167. want_y = random.randint(mid_top, mid_bottom)
  168. #dst_position
  169. dst_x = random.randint(int(want_x - position.width / 3), int(want_x + position.width / 3))
  170. dst_y = random.randint(int(want_y - position.height / 3), int(want_y + position.height / 3))
  171. print(f"{image_path}:({dst_x}, {dst_y})")
  172. return True, (dst_x, dst_y)
  173. else:
  174. print(f"{image_path}图片未找到")
  175. return False, (-1, -1)
  176. @staticmethod
  177. def find_imgArr(imgArr):
  178. for cur_img in imgArr:
  179. ret, pos = pcacc_img.find_img(cur_img)
  180. if ret:
  181. return ret, pos
  182. return False, None
  183. @staticmethod
  184. def find_imgArr_cv(imgArr):
  185. for cur_img in imgArr:
  186. ret, pos = pcacc_img.find_img_cv(cur_img)
  187. if ret:
  188. return ret, pos
  189. return False, None
  190. @staticmethod
  191. def find_imgs(images, is_cv=False):
  192. if is_cv:
  193. return pcacc_img.find_imgs_cv(images)
  194. else:
  195. if isinstance(images, str):
  196. return pcacc_img.find_img(images)
  197. elif isinstance(images, (list, tuple)):
  198. return pcacc_img.find_imgArr(images)
  199. else:
  200. raise ValueError("Invalid input type for 'images' parameter.")
  201. @staticmethod
  202. def find_imgs_cv(images):
  203. if isinstance(images, str):
  204. return pcacc_img.find_img_cv(images)
  205. elif isinstance(images, (list, tuple)):
  206. return pcacc_img.find_imgArr_cv(images)
  207. else:
  208. raise ValueError("Invalid input type for 'images' parameter.")
  209. @staticmethod
  210. def find_all_image_locations(image):
  211. confidence_threshold = 0.90
  212. # 查找所有符合条件的图片位置
  213. locations = pyautogui.locateAllOnScreen(image, confidence=confidence_threshold)
  214. # 将位置信息保存到列表中
  215. image_locations = []
  216. for location in locations:
  217. # 获取位置信息的左上角坐标和宽高
  218. x, y, width, height = location
  219. # 将位置信息添加到列表中
  220. image_locations.append((x, y, width, height))
  221. return image_locations
  222. @staticmethod
  223. def find_img_in_area(image,region=None):
  224. confidence_threshold = 0.85
  225. location = pyautogui.locateOnScreen(image,region=region, confidence=confidence_threshold)
  226. if location is not None:
  227. return True
  228. return False
  229. if __name__ == '__main__':
  230. time.sleep(2)
  231. begin = time.time()
  232. pcacc_img.find_maxColor_position((200, 200, 800, 200), {'2EA043'})
  233. cost = time.time() - begin
  234. print("函数执行耗时:", cost, "秒")