# match 匹配 PC端使用
import os
import cv2
import pyautogui
'''
注意:文件路径不能含有中文!!!文件名也不能含有中文!!!
picPath:要找的图的路劲
tress:kd树的数量,数值越大,精度越大,但耗时越高,建议设置为100足够
checks:节点检查数量,数值越大,精度越大,但耗时越高,建议设置为1000足够
maxInit:最大搜索系数,范围为大于0~1的小数,建议设置为0.5或者0.7。数值越小找的越精确,但是也可能找不到;数值越大找到的可能性更大,但也可能会找错。
screen:全屏图的保存路径
'''
def FindPicSIFT(picPath, trees, checks, maxInit, screen):
# 第一步:获取屏幕截图与目标图片数据
# 我们将使用pyautogui截取全屏图片,然后通过OpenCV读取屏幕截图和待匹配的目标图像。
# 以下代码将截屏并读取图像数据,返回numpy数组:
screenshot = pyautogui.screenshot() # 截取全屏图片
screenshot.save(screen) # 全屏图片保存到指定目录
screenPic = cv2.imread(screen) # 读取全屏图片
img_url = r""+picPath # 图标路径
myPic = cv2.imread(img_url) # 读取图标图片
# 第二步:获取图像的关键点与描述符
# 使用SIFT算法提取屏幕截图和目标图片的关键点及描述符:
sift = cv2.SIFT_create()
screenPicKP, screenPicDES = sift.detectAndCompute(screenPic, None)
myPicKP, myPicDES = sift.detectAndCompute(myPic, None)
# 第三步:配置Flann匹配器
# 接下来,设置Flann匹配器的参数。Flann是一种快速匹配算法,适合大数据集的匹配。我们可以通过设置trees和checks参数来调整精度和速度的平衡:
indexParams = dict(algorithm=0, trees=trees)
searcheParams = dict(checks=checks)
flann = cv2.FlannBasedMatcher(indexParams, searcheParams)
# 第四步:进行图像匹配
# 使用Flann的knn匹配法获取初步匹配结果,并根据特征点的距离对结果进行排序:
matches = flann.knnMatch(screenPicDES, myPicDES, k=2)
matches = sorted(matches, key=lambda x: x[0].distance)
# 第五步:筛选最优匹配并返回坐标
# 通过循环调整匹配率,找到最优匹配并返回坐标。最大搜索系数和初始匹配率都可自定义,以确保找到图像的最优位置:
x, y = None, None
max_init_num = maxInit
init_num = 0.1
while init_num <= max_init_num:
goodMatches = []
for m, n in matches:
if m.distance < init_num * n.distance:
goodMatches.append(m)
index = int(len(goodMatches) / 2)
try:
x, y = screenPicKP[goodMatches[index].queryIdx].pt
break
except:
init_num += 0.1
os.remove(screen) # 删除截取的全屏文件
print(f"图像在屏幕上的x坐标为:{x}")
print(f"图像在屏幕上的y坐标为:{y}")
# 左键点击屏幕上的这个位置
pyautogui.click(x, y, button='left')
原文链接:Python找图辅助-使用最高精准匹配算法SIFT(你还在用Pyautogui?)- 幽络源-CSDN博客