详细分析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适…

Redis是如何避免“数组+链表”的过长问题

目录 一、扩展和收缩 二、使用高质量的哈希函数 三、使用跳跃表(skiplist)或其他数据结构 四、哈希表分片 一、扩展和收缩 Redis通过动态调整哈希表的大小来解决“数组链表”的长度问题,这涉及到两个过程:扩展(Expand)和收缩(S…

深度学习知识【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企业级…

opencv自定义间隔帧获取视频转存为图片

该代码只将mp4转为jpg 扩展 如果您只是想使用这段代码自定义间隔帧获取视频转存为图片的功能,在opencv自定义间隔帧获取视频转存为图片的GUI界面实现可以更方便您的使用。 背景 由于我要做一个深度学习方向的计算机视觉项目,需要一些数据集来进行训练…

哈工大sse C语言 困难

Q565.(10分数, 语言: C)程序中函数 fun()的功能: 将一个由八进制数字字符组成的字符串转换为与其值相等的十进制整数。规定输入的字符串最多只能包含5位八进制数字字符。 **输入格式要求:gets 提示信息:"输入一个八进制字符串(5位&…

软件工程可行性分析报告

软件工程实验报告 实 验 目 的 学会分析现有系统;2.学会分析项目的可行性。 实 验 内 容 对小组项目进行需求收集;对项目进行组织机构、业务流程分析;对项目进行粗略设计;对项目进行技术、经济、操作等可行性分析。 实 验 步 …

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

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

RUST: let task = mut task.unwrap().clone();

首先&#xff0c;我们分析一下各个部分的作用&#xff1a; task: 这个变量之前已经存在于作用域内&#xff0c;其类型为 Option<T> 或 Result<T, E> 其中 T 是某个实现了 Clone 特性的类型&#xff08;在这里没有具体说明类型 T&#xff0c;但可以根据上下文推断出…

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

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

【前端】CommonJS和ES Module

区别 语法差异&#xff1a; CommonJS&#xff1a;使用 require() 导入模块&#xff0c;使用 module.exports 或 exports 导出模块。 ES Module&#xff1a;使用 import 导入模块&#xff0c;使用 export 导出模块。 编译时 vs 运行时&#xff1a; CommonJS 是在运行时加载模块…

Python中的函数参数传递方式是怎样的?

Python中的函数参数传递方式是怎样的&#xff1f; 在Python中&#xff0c;函数参数传递是函数调用的重要部分&#xff0c;它决定了如何将数据从调用者传递到函数中。Python的参数传递方式主要可以分为两类&#xff1a;位置参数&#xff08;Positional Arguments&#xff09;和…

前端需要掌握的 mysql 基础知识

常用的 mysql 的操作方法 1. 新增 这里新增phone,username,password三个参数&#xff0c;后面的?就是写几个&#xff0c; 对应的[phone, username, password]要和前面的顺序一致。 const sql2 INSERT INTO user(phone,username,password) VALUES(?,?,?); const data2 aw…

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

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