基于YOLO目标检测及OpenCV实现的游戏代玩人工智能体(Auto Gaming Agent) [2]

大型生存类游戏自动代玩人工智能[2] -- 屏幕截取

使用Python中的PIL库截取屏幕

当需要获取电脑屏幕的信息时,往往需要进行屏幕截取操作。而万能的python就有非常方便快捷的方法来截取屏幕,就是用python中的图像处理库Pillow (PIL)来完成。安装PIL库的具体操作详见官方文档

安装好PIL库以后我们最快只需两步就可以进行屏幕截取:

1.首先导入PIL库中的ImageGrab模块

from PIL import ImageGrab

2.然后就可以用ImageGrab模块来直接截取屏幕了

screenshot = ImageGrab.grab()

返回的screenshot变量就是全屏图像。

在这里插入图片描述

如果想要指定位置的截屏,可以输入bbox参数:

x=20
y=60
width=1024
height=576
screenshot = ImageGrab.grab(bbox=(x,y,width,height))

返回的screenshot变量就是 左上角顶点坐标(20,60) 宽1024 高576 的屏幕图像。

在这里插入图片描述

想要使用OpenCV来显示图像以及进行更多的图像处理,非常必要的操作是将screenshot转成numpy数组:

import numpy as np
screenshot_array = np.array(ImageGrab.grab(bbox=(x,y,width,height)))

转换后的screenshot_array就是一个numpy数组,可以使用OpenCV来显示图像:

import cv2
cv2.imshow('screenshot',screenshot_array)
cv2.waitKey(0)
cv2.destroyAllWindows()

(python版OpenCV的安装详见官方文档,推荐使用Anaconda来安装)

在这里插入图片描述

但是显示出来的图片有RGB颜色错乱的问题,应该是转换成numpy数组时导致的,所以要得到正常的图像需要用OpenCV进行一次RGB颜色通道转换:

screenshot_array = cv2.cvtColor(screenshot_array, cv2.COLOR_BGR2RGB)

最后得到的screenshot_array就是正常颜色的numpy数组了。

在这里插入图片描述

实时屏幕监控

我们的游戏代玩程序需要不断获取游戏截屏来监控游戏的状态,所以最简单的方法就是无限循环地截屏,加一个while True死循环即可:

while True:
    image_array = np.array(ImageGrab.grab(bbox=(x,y,width,height)))
    image_array = cv2.cvtColor(image_array, cv2.COLOR_BGR2RGB)
    cv2.imshow('screen monitoring',image_array)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

由于PIL库的运行效率问题,这种方法的屏幕监控只能做到 10FPS 左右,更快的方法是用win32gui库来截屏(详见这里)。不过每秒10帧的速度对于我们这个程序来说够用了,所以就不用繁琐的win32gui来截屏了,不过下面我们还是会用到win32gui来帮助我们截取指定窗口的屏幕信息。

在这里插入图片描述

用win32gui获取指定窗口位置

很多时候我们想要截屏的窗口不是全屏的,所以这个窗口有可能存在桌面的任意位置而且窗口大小也不固定。所以稳妥起见,我们需要获取我们想要截屏的窗口的位置和大小(即窗口的bbox)。这里如果是windows系统(Mac和Linux的方法请自行查询)我们可以用到另外一个库win32gui来实现,安装方法详见官方文档

首先导入win32gui库中的FindWindowGetWindowRect两个模块:

from win32gui import FindWindow, GetWindowRect

然后用FindWindow模块来获取目标窗口的程序id号,通过输入窗口名字(窗口名字可以在桌面下方的任务栏查看),这里我们的目标窗口是游戏的模拟器:

window_name = "明日之后 - MuMu模拟器"
id = FindWindow(None, window_name)

得到id号以后就可以通过GetWindowRect来获取目标窗口的bbox了:

bbox = GetWindowRect(id)

拿到了目标窗口的bbox以后,只需输入到之前的ImageGrab参数中就可以实时监视你想要的窗口了,从头到尾完整代码如下:

# coding=gbk
import numpy as np
import cv2
from PIL import ImageGrab
from win32gui import FindWindow, GetWindowRect

while True:
    window_name = "明日之后 - MuMu模拟器"
    id = FindWindow(None, window_name)
    bbox = GetWindowRect(id)
    image_array = np.array(ImageGrab.grab(bbox=bbox))
    image_array = cv2.cvtColor(image_array, cv2.COLOR_BGR2RGB)
    cv2.imshow('screenshot',image_array)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

需要注意的是目标窗口必须要在打开状态并且在桌面的最上层,如果窗口处于最小化或者被其他窗口覆盖的话是无法通过这个方法获取截屏的

还有代码中的# coding=gbk一定不能少,这个是python中的中文编码来识别"明日之后 - MuMu模拟器"这些中文字符的

在这里插入图片描述
可以看到无论游戏窗口在屏幕的哪个位置都可以准确定位到。

下一篇:用YOLO目标检测来识别游戏中的资源

  • 10
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值