详细分析PyAutoGUI中的locate函数(附Demo)

目录

  • 前言
  • 1. 基本知识
  • 2. 源代码分析
  • 3. Demo

前言

起因是实战中locate对个别定位会有偏差,导致一直识别错误

相应的基本知识推荐阅读:详细分析Python中的Pyautogui库(附Demo)

1. 基本知识

pyautogui.locate()函数用于在屏幕上定位指定图像或颜色的区域

作用:

  • 定位屏幕上的指定图像或颜色区域
  • 用于自动化任务,例如查找特定的应用程序窗口、按钮、图标等

函数如下:locate(needleImage, haystackImage, **kwargs): 在haystackImage中查找needleImage的位置

  • needleImage: 要搜索的图像(可以是字符串文件名或PIL.Image对象)
  • haystackImage: 要搜索的图像或区域(可以是字符串文件名、PIL.Image对象或(left, top, width, height)元组)
  • **kwargs: 传递给locateAll的其他关键字参数

最终的结果返回值:如果找到匹配点,则返回第一个匹配点,否则返回None

对于**kwargs的关键字参数,可以详细参考下locateAll的函数源码,补充其参数如下:

  • grayscale: 可选参数,指定是否将图像转换为灰度图像。默认为None
  • limit: 可选参数,指定要返回的匹配数量的上限。默认为None,表示没有限制
  • region: 可选参数,指定在哪个区域内搜索图像(以(left, top, width, height)元组形式指定)。默认为None,表示整个图像
  • step: 可选参数,指定搜索时的步长。默认为1,表示逐像素搜索
  • confidence: 可选参数,置信度阈值。仅当安装了OpenCV时才可用。默认为None

该函数的返回值为 所有匹配的位置的Box对象

2. 源代码分析

源代码已加入注释:

def locate(needleImage, haystackImage, **kwargs):# 将limit设置为1,仅返回第一个匹配点kwargs['limit'] = 1# 查找所有匹配点points = tuple(locateAll(needleImage, haystackImage, **kwargs))# 如果至少找到一个匹配点if len(points) > 0:return points[0]else:# 如果USE_IMAGE_NOT_FOUND_EXCEPTION为True,则抛出异常if USE_IMAGE_NOT_FOUND_EXCEPTION:raise ImageNotFoundException('无法定位图像。')# 否则返回Noneelse:return None

其中使用到了locateAll函数,再次给出源代码:

@requiresPillow
def _locateAll_python(needleImage, haystackImage, grayscale=None, limit=None, region=None, step=1, confidence=None):"""在haystackImage中查找所有的needleImage的位置。Args:needleImage: 要搜索的图像(可以是字符串文件名或PIL.Image对象)。haystackImage: 要搜索的图像或区域(可以是字符串文件名、PIL.Image对象或(left, top, width, height)元组)。grayscale: 可选参数,指定是否将图像转换为灰度图像。默认为None。limit: 可选参数,指定要返回的匹配数量的上限。默认为None,表示没有限制。region: 可选参数,指定在哪个区域内搜索图像(以(left, top, width, height)元组形式指定)。默认为None,表示整个图像。step: 可选参数,指定搜索时的步长。默认为1,表示逐像素搜索。confidence: 可选参数,置信度阈值。仅当安装了OpenCV时才可用。默认为None。Returns:生成器,用于生成所有匹配的位置的Box对象。Raises:NotImplementedError: 如果confidence参数在没有安装OpenCV时被使用。ImageNotFoundException: 如果未找到匹配点且USE_IMAGE_NOT_FOUND_EXCEPTION为True时引发。"""if confidence is not None:raise NotImplementedError('当没有安装OpenCV时,confidence关键字参数不可用。')# 设置所有参数if grayscale is None:grayscale = GRAYSCALE_DEFAULTneedleFileObj = Noneif isinstance(needleImage, (str, unicode)):# 'image' 是一个文件名,加载图像对象needleFileObj = open(needleImage, 'rb')needleImage = Image.open(needleFileObj)haystackFileObj = Noneif isinstance(haystackImage, (str, unicode)):# 'image' 是一个文件名,加载图像对象haystackFileObj = open(haystackImage, 'rb')haystackImage = Image.open(haystackFileObj)if region is not None:haystackImage = haystackImage.crop((region[0], region[1], region[0] + region[2], region[1] + region[3]))else:region = (0, 0)  # 因为代码总是考虑区域,所以设置为0if grayscale:  # 如果启用了灰度模式,则将needle和haystack图像转换为灰度图像needleImage = ImageOps.grayscale(needleImage)haystackImage = ImageOps.grayscale(haystackImage)else:# 如果不使用灰度,则确保比较的是RGB图像,而不是RGBA图像if needleImage.mode == 'RGBA':needleImage = needleImage.convert('RGB')if haystackImage.mode == 'RGBA':haystackImage = haystackImage.convert('RGB')# 设置一些常量needleWidth, needleHeight = needleImage.sizehaystackWidth, haystackHeight = haystackImage.sizeneedleImageData = tuple(needleImage.getdata())haystackImageData = tuple(haystackImage.getdata())needleImageRows = [needleImageData[y * needleWidth:(y + 1) * needleWidth] for y in range(needleHeight)]needleImageFirstRow = needleImageRows[0]assert len(needleImageFirstRow) == needleWidth, '计算出的第一行的宽度与图像宽度不同。'assert [len(row) for row in needleImageRows] == [needleWidth] * needleHeight, 'needleImageRows的大小与原始图像大小不同。'numMatchesFound = 0# 注意: 经过在以下代码上运行测试/基准测试.py之后,似乎步长大于1并不会带来任何显著的性能改进。# 由于使用大于1的步长会导致匹配不够精确,因此将其设置为1。step = 1  # 硬编码步长为1,直到找到改进的方法。if step == 1:firstFindFunc = _kmpelse:firstFindFunc = _steppingFindfor y in range(haystackHeight):for matchx in firstFindFunc(needleImageFirstRow, haystackImageData[y * haystackWidth:(y + 1) * haystackWidth], step):foundMatch = Truefor searchy in range(1, needleHeight, step):haystackStart = (searchy + y) * haystackWidth + matchxif needleImageData[searchy * needleWidth:(searchy + 1) * needleWidth] != haystackImageData[haystackStart:haystackStart + needleWidth]:foundMatch = Falsebreakif foundMatch:# 找到匹配,报告匹配区域在haystack中的x、y、宽度、高度。numMatchesFound += 1yield Box(matchx + region[0], y + region[1], needleWidth, needleHeight)if limit is not None and numMatchesFound >= limit:# 达到限制。关闭文件句柄。if needleFileObj is not None:needleFileObj.close()if haystackFileObj is not None:haystackFileObj.close()return# 没有限制或限制未达到,但是无论如何都要关闭文件句柄。if needleFileObj is not None:needleFileObj.close()if haystackFileObj is not None:haystackFileObj.close()if numMatchesFound == 0:if USE_IMAGE_NOT_FOUND_EXCEPTION:raise ImageNotFoundException('无法定位图像。')else:return

3. Demo

(×)错误版: (这里使用默认参数,有可能会错误,建议加上置信度参数)
我们先给一个Demo:(截图区域为当前,jd.jpg为当前区域的某一区域)

import pyautoguitarget_image = 'target_image.png'# 截取屏幕指定区域并保存为图像文件
screenshot = pyautogui.screenshot('shot.png')
print("截图已保存为 'shot.png'")target_position = pyautogui.locate(target_image, screenshot)
print(target_position)if target_position is not None:center_x = target_position.left + (target_position.width / 2)center_y = target_position.top + (target_position.height / 2)print("目标图像中心坐标:", center_x, center_y)

结果输出如下:

在这里插入图片描述

在PyAutoGUI中,locate()函数用于在屏幕截图(screenshot)中查找目标图像(target_image)的位置。它默认使用图像的灰度模式,并且没有指定置信度阈值时,默认置信度阈值为None。这意味着如果未指定置信度阈值,则需要确保目标图像与屏幕截图非常相似,才能成功定位。如果目标图像与屏幕截图不是完全相同,例如在颜色、尺寸或旋转方面有细微差异,那么可能会导致无法成功定位,此时返回的位置将为None。

在没有设置confidence参数的情况下,默认的阈值为None,这意味着需要与完全相同的图像匹配。而当设置了confidence参数时,PyAutoGUI会尝试寻找与目标图像非常相似的区域,只要相似度超过了设置的置信度阈值,就会返回匹配的位置

(√)正确版:

截图如下:

import pyautoguitarget_image = 'target_image.png'# 截取屏幕指定区域并保存为图像文件
screenshot = pyautogui.screenshot('shot.png')
print("截图已保存为 'shot.png'")# 注意此处修改的位置
target_position = pyautogui.locate(target_image, screenshot,confidence=0.68)
print(target_position)if target_position is not None:center_x = target_position.left + (target_position.width / 2)center_y = target_position.top + (target_position.height / 2)print("目标图像中心坐标:", center_x, center_y)

截图如下:

在这里插入图片描述

对于其他的参数还有region 以及 grayscale等
以下虽然可以执行,但是对于作者来说输出为None

  • 默认参数:
    target_position = pyautogui.locate('target_image.png', screenshot)
  • 区域参数:
    target_position = pyautogui.locate('target_image.png', screenshot, region=(100, 100, 800, 600))
  • 灰度参数:
    target_position = pyautogui.locate('target_image.png', screenshot, grayscale=True)

确保confidence可选参数在的话,在额外加其他可选参数,结果会正常:

# 注意此处修改的位置
target_position = pyautogui.locate(target_image, screenshot, confidence = 0.68 ,region=(1264, 32, 86, 24))

截图如下所示:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/765002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TWT:一个让WiFi6更省电的特性

更多精彩内容在公众号。 再wifi6前,已经有了不少节能特性:PSM,PSMP,APSD。在一个 Beacon 周期内,终端 会观察 AP 是否会向其发送数据,如果是,那么终端就保持等待,直到接收完成后, 才会进入休眠模…

微服务cloud--抱团取暖吗 netflix很多停更了

抱团只会卷,卷卷也挺好的 DDD 高内聚 低耦合 服务间不要有业务交叉 通过接口调用 分解技术实现的复杂性,围绕业务概念构建领域模型;边界划分 业务中台: 数据中台: 技术中台: 核心组件 eureka&#x…

linux系统------------MySQL 存储引擎

目录 一、存储引擎概念介绍 二、常用的存储引擎 2.1MyISAM 2.1.1MYlSAM的特点 2.1.2MyISAM 表支持 3 种不同的存储格式⭐: (1)静态(固定长度)表 (2)动态表 (3)压缩表 2.1.3MyISAM适…

深度学习知识【CSPNet网络详解】

CSPNet的贡献 1.增强了CNN的学习能力,能够在轻量化的同时保持准确性。 2.降低计算瓶颈。 3.降低内存成本。 CSPNet介绍 在神经网络推理过程中计算量过高的问题是由于网络优化中的梯度信息重复导致的。CSPNet通过将梯度的变化从头到尾地集成到特征图中&#xff0c…

操作简单的城市内涝一维二维耦合模拟软件

原文链接:最简单的城市内涝一维二维耦合模拟软件https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598401&idx3&sn0c4c86b3a5d09a75b8f07e6fad81aa9c&chksmfa8200a6cdf589b0970a6854869e8e3a9f132fe40a19977863c091cbcf6d9786f067e0c5651e&…

深度学习:复杂工业场景下的复杂缺陷检测方法

摘要:在复杂的工业场景中,缺陷检测一直是一个重要而具有挑战性的任务。近年来,深度学习技术的快速发展为复杂工业场景下的缺陷检测提供了新的解决方案。本文将介绍深度学习在复杂工业场景下的复杂缺陷检测中的应用,并探讨其技术进…

【机器学习入门 】逻辑斯蒂回归和分类

系列文章目录 第1章 专家系统 第2章 决策树 第3章 神经元和感知机 识别手写数字——感知机 第4章 线性回归 文章目录 系列文章目录前言一、分类问题的数学形式二、最大似然估计三、交叉熵损失函数四、多类别分类多类别逻辑斯蒂回归归一化指数函数交叉熵误差和均方误差的比较 五…

Tomcat 服务器部署和 IDEA 配置 Tomcat

(一) Tomcat 简介 Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。 概念中提到了JavaEE规范,那什么又是JavaEE规范呢? JavaEE: Java Enterprise Edition,Java企业版。指Java企业级…

集简云新增“文本语音转换”功能,实现智能语音交互

为丰富人工智能领域的应用集成,为用户提供更便捷和智能化的信息获取和视觉创作方式,本周集简云上线了内置应用—文本语音转换。目前支持OpenAI TTS和TTS HD模型,实现文本语音高效智能转换,也可根据你的产品或品牌创建独特的神经网…

Go --- 编程知识点及其注意事项

new与make 二者都是用于内存分配,当声明的变量是引用类型时,不能给该变量赋值,因为没有分配空间。 我们可以用new和make对其进行内存分配。 首先说说new new函数定义 func new(Type) *Type传入一个类型,返回一个指向分配好该…

从原理到实践:深入探索Linux安全机制(一)

前言 本文将从用户和权限管理、文件系统权限、SELinux、防火墙、加密和安全传输、漏洞管理和更新等几个Linux安全机制中的重要方面,深入探索其工作原理和使用方法。在当今数字化时代,网络安全问题备受关注,Linux作为广泛应用的操作系统之一&…

每日一题 --- 977. 有序数组的平方[力扣][Go]

今天这一题和昨天的知识点是一样的,就是双指针法。 题目: 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 示例 1: 输入:nums [-4,-1,0,3,1…

对话悠易科技蔡芳:品牌逐渐回归核心能力建设,布局和构建自己的流量阵地

关于SaaS模式在中国的发展,网上出现多种声音。Marteker近期采访了一些行业专家,围绕SaaS模式以及Martech在中国的发展提出独特观点。悠易科技副总裁蔡芳认为,中国目前存在SaaS的应用场景与客户需求,用户的应用能力也在提升&#x…

containerd源代码分析: 整体架构

本文从代码的大的整体组织上来熟悉containerd项目 containerd项目总的说是一个cs模式的原生控制台程序组。containerd作为服务端来接收处理client的各种请求,如常用的拉取推送镜像,创建查询停止容器,生成快照,发送消息等。client/…

XS2105S,IEEE 802.3af 兼容、用电设备接口控制器集成功率 MOSFET V0.5

XS2105S 为用电设备(PD)提供符合以太网供电(PoE)系统 IEEE802.3af 标准的完整接口。XS2105S 为 PD 提供检测信号、分级信号以及带有浪涌电流控制的 集成隔离功率开关。发生浪涌期间,XS2105S 将电流限 制在 180mA 以内,直到隔离功率 MOSFET 完全开启后切 …

【Linux命令】查看内存占用情况(mem, swap)

1. 方法1(top) # top2.方法2(free) # free -h3. 方法3(swapon) # swapon -s

GraalVM详细安装及打包springboot、java、javafx使用教程(打包springboot3篇)

前言 在当前多元化开发环境下,Java作为一种广泛应用的编程语言,其应用部署效率与灵活性的重要性日益凸显。Spring Boot框架以其简洁的配置和强大的功能深受开发者喜爱,而JavaFX则为开发者提供了构建丰富桌面客户端应用的能力。然而&#xff…

什么是虚拟继承

由于C支持多继承&#xff0c;除了public、protected和private三种继承方式外&#xff0c;还支持虚拟&#xff08;virtual&#xff09;继承&#xff0c;举个例子&#xff1a; #include <iostream> using namespace std;class A {}; class B : virtual public A {}; class…

Vue模块化开发步骤—遇到的问题—解决办法

目录 1.npm install webpack -g 2.npm install -g vue/cli-init 3.初始化vue项目 4.启动vue项目 Vscode初建Vue时几个需要注意的问题-CSDN博客 1.npm install webpack -g 全局安装webpack 直接命令提示符运行改指令会报错&#xff0c;operation not permitted 注意&#…