|
可以直接通过pip获取,无需手动安装其他依赖pipinstallxug示例:importxugxug.find_image_on_screen(,,,)=========================================================================一、依赖安装pipinstallopencv-pythonpipinstallpyautogui二、获取系统缩放比例注意:必须先通过ctypes获取wid之后才能导入pyautogui,如果需要在其它代码中引用该模块,最好把获取分辨率这部分代码放到程序入口处,然后传递给识图函数,避免提前导入pyautogui导致获取分辨率失败。#获取当前系统缩放比例importctypes#wid必须在导入pyautogui之前赋值wid=ctypes.windll.user32.GetSystemMetrics(0)importpyautoguiscreen_width,_=pyautogui.size()true_scale=screen_width/wid 三、定义匹配结果类x,y表示中心坐标,x1,y1,x2,y2表示四个顶点的坐标,match表示匹配度,取值范围0-100。fromdataclassesimportdataclass#定义匹配结果类@dataclassclassMatchInfo:match:float=0x:int=0y:int=0x1:int=0y1:int=0x2:int=0y2:int=0@staticmethoddefnot_found():returnMatchInfo()def__str__(self):return(f"匹配度={self.match:.2f},"f"中心坐标{self.x},{self.y})")四、完整代码参数:template:模板图片,字符串,即待匹配图片,支持两种形式,可以传入图片地址,也可以直接传入图片名称,此时会从代码中设定的图片文件夹寻找图片;min_threshold:最小匹配度,浮点数,只返回匹配度大于等于该值的结果,取值范围0-100gray:灰度匹配,布尔值,为真时则忽略颜色,可以大幅提升匹配速度,适用于不考虑颜色的情况a,b,c,d:区域匹配坐标,整数,都为0时不生效,否则只在该区域匹配,但是返回的结果坐标任然是相对于整个屏幕image_sacle:图片缩放,浮点数,即传入的图片的缩放,也就是截图时电脑对应的缩放,默认和1.25,即125%,需要自己根据情况修改,取值是(1,1.25,1.5,1.75,2)max_deviation:最大偏差值,整数,多个匹配结果之间距离的最小值,如果存在同一个目标被识别成两个结果的情况,可以适当增加这个参数的值返回值:列表类型,包含所有符合条件的匹配结果(MatchInfo对象),如果没有匹配到则是空列表#获取当前系统缩放比例importctypes#wid必须在导入pyautogui之前赋值wid=ctypes.windll.user32.GetSystemMetrics(0)importpyautoguiscreen_width,_=pyautogui.size()true_scale=screen_width/widfromdataclassesimportdataclass#定义匹配结果类@dataclassclassMatchInfo:match:float=0x:int=0y:int=0x1:int=0y1:int=0x2:int=0y2:int=0@staticmethoddefnot_found():returnMatchInfo()def__str__(self):return(f"匹配度={self.match:.2f},"f"中心坐标{self.x},{self.y})")importcv2importosimportnumpyasnp#识图函数deffind_image_on_screen(template,min_threshold,gray=False,a=0,b=0,c=0,d=0,image_sacle=1.25,max_deviation=13):#图片存放地址image_path='D:\\test\\image'#处理传入的匹配度min_threshold=min_threshold/100#路径处理,如果传入的参数只是图片名称,就从默认路径寻找改图片ifnotos.path.isabs(template):template=os.path.join(image_path,template)#读取模板图片templ=cv2.imread(template)#获取屏幕截图screenshot=cv2.cvtColor(np.array(pyautogui.screenshot()),cv2.COLOR_RGB2BGR)#获取模板图片长宽xx,yy=templ.shape[:-1]#如果实际缩放和图片缩放不一致,就进行调整iftrue_scale!=image_sacle:screenshot=cv2.resize(screenshot,None,fx=image_sacle/true_scale,fy=image_sacle/true_scale)#判断是否需要灰度匹配ifgray:screenshot=cv2.cvtColor(screenshot,cv2.COLOR_BGR2GRAY)templ=cv2.cvtColor(templ,cv2.COLOR_BGR2GRAY)#判断是否需要区域匹配ifa==0andb==0andc==0andd==0:screenshot_region=screenshot#默认情况下,使用整个截图else:#这里需要特殊处理,避免裁剪后的截图比模板图片小导致报错c=max(a+yy,c)d=max(b+xx,d)#裁剪截图screenshot_region=screenshot[b:d,a:c]#执行模板匹配result=cv2.matchTemplate(screenshot_region,templ,cv2.TM_CCOEFF_NORMED)#获取满足匹配度的结果locations=np.where(result>=min_threshold)locations=list(zip(*locations[::-1]))match_info={}#对匹配结果进行筛选和去重,避免同一个目标被识别成多个结果,可以通过调整max_deviation的值来调整效果forlocinlocations:x,y=locx=x+a#调整x坐标以匹配整个截图y=y+b#调整y坐标以匹配整个截图match_value=result[y-b,x-a]skip_current=Falsefor(prev_x,prev_y),prev_match_valueinmatch_info.items():ifabs(x-prev_x)prev_match_value:match_info[(x,y)]=match_valuedelmatch_info[(prev_x,prev_y)]else:skip_current=Truebreakifnotskip_current:match_info[(x,y)]=match_value#构建匹配结果列表match_info_objects=[]for(x,y),match_valueinsorted(match_info.items(),key=lambdax:x[1],reverse=True):h,w=xx,yytop_left=(x,y)bottom_right=(x+w,y+h)center=(x+w//2,y+h//2)matche=MatchInfo(match_value*100,center[0],center[1],top_left[0],top_left[1],bottom_right[0],bottom_right[1],)match_info_objects.append(matche)returnmatch_info_objects五、示例用法if__name__=='__main__':#根据图片名称匹配,其他参数取默认值print("test1:")forsin(find_image_on_screen('test1.png')):print(s)print("test2:")#根据图片路径匹配,匹配度85forsin(find_image_on_screen('D:\\test\\image\\test2.png',min_threshold=85)):print(s)print("test3:")#根据路径匹配,忽略颜色,在指定区域匹配forsin(find_image_on_screen('D:\\test\\image\\test3.png',gray=True,a=11,b=35,c=983,d=639)):print(s)运行结果:
|
|