原文名称:Reading game frames in Python with OpenCV - Python Plays GTA V

原文链接:Python Programming Tutorials

原文作者:@Harrison

本文是Harrison《Python Plays GTA V》系列教程第一篇。

当OpenAI's Universe(Universe)出现后,很多文章都在鼓吹大量的游戏(甚至GTA5)已经做好了迎接AI时代的准备。我当时跃跃欲试,然而GTA5最终被神神秘秘的清除出Universe,连个解释都没有。

后来我短暂的放弃了这个念头,但偶尔想起来依然有点抑制不住的小激动。所以我还是决定在这件事情上多花点功夫,同时好好思考这件事情到底是不是非得用OpenAI不可。OpenAI的好处在于针对一些简单的游戏项目可以实现每分钟上千次的迭代训练,但是GTA5这种游戏嘛,情况就不一样了。

我们来说一下为什么选择GTA5。至少对我来说,GTA5是一个有无数理由让我去进行练习的绝佳环境。在这个开放世界里你几乎没有不能做的事情——举一个最简单的例子:自动驾驶汽车。在游戏中,我们可以用MOD控制时间、天气、交通、速度、遇到的紧急状况等等等等。这是个完全的、可以量身订制(有时需要MOD)的世界。

我的教程有时候经过充足的计划、有些计划过一点、有的完全没有计划过。这个项目就是完全没有计划的教程之一。我知道不是所有人都有GTA5,不过我想你可以使用其他类似的游戏来和我一起学习这个项目——我们有很多游戏都可以拿来使用。(如果使用其他游戏)你需要对某些部分进行调整以使其正常运行,所以你可能得有点基础才行。

我的初步目标是创造一个自动驾驶汽车,所以任何一个有公路和汽车的游戏都可以拿来用。我用来接入游戏的方法几乎可以在其他所有游戏中也使用,如果你选择了更简单的游戏,那就省事多了。因为GTA5的高度拟真,阳光会让电脑识别变得更加具有挑战性。

我可能也会尝试其他游戏——因为我相信我们可以通过简单示范来教AI怎么玩。通过卷积神经网络处理信息,然后让AI进行练习就行。

我的初步判断是:尽管Python并没有现成的库可用,不过 1.我们可以读取屏幕图像 2.我们可以模拟按键

这两项足够我们处理常规事务,不过对于深度学习来说,我们可能还想要记录游戏世界的进程。好在现在的大部分游戏已经完全可视化,这已经不再是个难题,我们可以通过追踪鼠标和按键,这一切都为深度学习提供了条件。

我猜这一路不会一帆风顺,但至少会很有趣。我的担忧主要集中在项目推进的速度上。我们可以做,最少是值得做。

总而言之,这是一个大项目,如果我们不拆分来做,显然就超纲了。所以我们来一点一点的尝试,第一步的目标是:

找个像样的FPS工具以访问游戏画面,能用就行的那种。我们的要求是能看就行。

确保键盘输入的指令可用。我觉得这很简单,但是必须得试试才知道。

尝试手柄输入。特别是转向、刹车等操作。

尝试使用OpenCV。希望不会遇到大问题。

在简单的道路环境下实现自动驾驶。

好了,第一步,我们如何实现读取屏幕画面?我一直在想可以做,但还真没想过怎么做。所以,Google!我找到不少案例,不过大部分都不能用,只有这个还算可以:Screen Capture with OpenCV and Python-2.7。

注意:导入的时候似乎有点错误,ImageGrab是PIL的一部分。

import numpy as np

import ImageGrab

import cv2

while(True):

printscreen_pil = ImageGrab.grab()

printscreen_numpy = np.array(printscreen_pil.getdata(),dtype=uint8)\

.reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

cv2.imshow('window',printscreen_numpy)

if cv2.waitKey(25) & 0xFF == ord('q'):

cv2.destroyAllWindows()

break

----------------------------------------------------------------------

ImportError Traceback (most recent call last)

in ()

1 import numpy as np

----> 2 import ImageGrab

3 import cv2

4

5 while(True):

ImportError: No module named 'ImageGrab'

果然出错了,我们改一下:

import numpy as np

from PIL import ImageGrab

import cv2

while(True):

printscreen_pil = ImageGrab.grab()

printscreen_numpy = np.array(printscreen_pil.getdata(),dtype=uint8)\

.reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

cv2.imshow('window',printscreen_numpy)

if cv2.waitKey(25) & 0xFF == ord('q'):

cv2.destroyAllWindows()

break

----------------------------------------------------------------------

NameError Traceback (most recent call last)

in ()

5 while(True):

6 printscreen_pil = ImageGrab.grab()

----> 7 printscreen_numpy = np.array(printscreen_pil.getdata(),dtype=uint8) .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

8 cv2.imshow('window',printscreen_numpy)

9 if cv2.waitKey(25) & 0xFF == ord('q'):

NameError: name 'uint8' is not defined

什么鬼?dtype明显应该是字符串,而不是什么没定义的变量名。这哥们写完代码到底运行了没?

import numpy as np

from PIL import ImageGrab

import cv2

def screen_record():

while True:

printscreen_pil = ImageGrab.grab()

printscreen_numpy = np.array(printscreen_pil.getdata(),dtype='uint8')\

.reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

cv2.imshow('window',printscreen_numpy)

if cv2.waitKey(25) & 0xFF == ord('q'):

cv2.destroyAllWindows()

break

这回终于正常了。不过这段代码太长,而且太慢。改一下吧。

import numpy as np

from PIL import ImageGrab

import cv2

def screen_record():

while True:

# 800x600 windowed mode

printscreen_pil = ImageGrab.grab(bbox=(0,40,800,640))

printscreen_numpy = np.array(printscreen_pil.getdata(),dtype='uint8')\

.reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))

if cv2.waitKey(25) & 0xFF == ord('q'):

cv2.destroyAllWindows()

break

这个看着还不错,就是太慢了,每秒大概只能有个2-3帧的样子。再改一下试试。

import numpy as np

from PIL import ImageGrab

import cv2

import time

def screen_record():

last_time = time.time()

while True:

# 800x600 windowed mode

printscreen_pil = ImageGrab.grab(bbox=(0,40,800,640))

printscreen_numpy = np.array(printscreen_pil.getdata(),dtype='uint8')\

.reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

print('loop took {} seconds'.format(time.time()-last_time))

last_time = time.time()

## cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))

## if cv2.waitKey(25) & 0xFF == ord('q'):

## cv2.destroyAllWindows()

## break

还是2-3帧。所以问题不是出在imshow函数上。

import numpy as np

from PIL import ImageGrab

import cv2

import time

def screen_record():

last_time = time.time()

while True:

# 800x600 windowed mode

printscreen_pil = ImageGrab.grab(bbox=(0,40,800,640))

## printscreen_numpy = np.array(printscreen_pil.getdata(),dtype='uint8')\

## .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))

print('loop took {} seconds'.format(time.time()-last_time))

last_time = time.time()

##

## cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))

## if cv2.waitKey(25) & 0xFF == ord('q'):

## cv2.destroyAllWindows()

## break

好了,现在的成绩是:loop took 0.05849909782409668 seconds

loop took 0.044053077697753906 seconds

loop took 0.04760456085205078 seconds

loop took 0.04805493354797363 seconds

loop took 0.05989837646484375 seconds

我们还需要一个numpy数组给OpenCV的imshow函数使用。相对于重新编写.getdata,我还是选择把ImageGrab.grab(bbox=(0,40,800,640))转化为numpy数组。重写是没必要的。

import numpy as np

from PIL import ImageGrab

import cv2

import time

def screen_record():

last_time = time.time()

while(True):

# 800x600 windowed mode

printscreen = np.array(ImageGrab.grab(bbox=(0,40,800,640)))

print('loop took {} seconds'.format(time.time()-last_time))

last_time = time.time()

cv2.imshow('window',cv2.cvtColor(printscreen, cv2.COLOR_BGR2RGB))

if cv2.waitKey(25) & 0xFF == ord('q'):

cv2.destroyAllWindows()

break

做了这么多事,现在大概有个每秒12-13帧的样子。这个成绩不算好,但是够用了。

https://www.zhihu.com/video/874326866318745600

——————————————————————————————————————

第一篇翻译完啦~关于配套的还有一部视频,本来想做个字幕出来的...但是...我这初中英语水平实在是应付不来了...有机会再做吧~(考虑后面利用语音识别做个机翻)

翻译这篇文章一方面是对Python的兴趣,另一方面也算是锻炼自己的英文水平了。巧的是,这两个技能水平都不高,所以如果看到错误,欢迎指正~

你想更深入了解学习Python知识体系,你可以看一下我们花费了一个多月整理了上百小时的几百个知识点体系内容:

python游戏目标识别_用Python玩GTA 5—使用OpenCV读取游戏面面相关推荐

  1. gta python解指纹_用Python玩GTA 5—使用OpenCV读取游戏面面

    原文名称:Reading game frames in Python with OpenCV - Python Plays GTA V原文链接:https://pythonprogramming.ne ...

  2. python 时间序列预测_使用Python进行动手时间序列预测

    python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...

  3. python 概率分布模型_使用python的概率模型进行公司估值

    python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...

  4. python能制作游戏吗_没有Python不能做的游戏,这些游戏都可以做

    简介:Python编程语言的强大,几乎是众所周知的!那么,下面我给大家介绍一下几个用Python实现的各种游戏吧.不仅能用来做web.爬虫.数据分析等,没想到还能用做这么多的游戏,实在令人惊讶不已.注 ...

  5. python怎么写游戏脚本_用PYTHON做一个简单的游戏脚本(基础,详细)

    引言 这段时间迷上了玩点点点的小游戏,但是某些重复的环节着实无聊,就想着能不能用PYTHON做一个游戏脚本,不过为了熟悉需要做脚本的各个模块,于是打算在4399上找一个比较像的游戏做个脚本练练手,后来 ...

  6. python读取游戏数据_用Python抓取并分析了1982场英雄联盟数据,教你开局前预测游戏对局胜负!...

    英雄联盟想必大多数读者不会陌生,这是一款来自拳头,由腾讯代理的大型网络游戏,现在一进网吧,你就能发现一大片玩英雄联盟的人.在2017年中国战队无缘鸟巢的世界总决赛后,一大片人选择了弃游,只是终究没躲过 ...

  7. python实现剪刀石头布_用Python Tkinter实现剪刀石头布小游戏的方法

    用Python Tkinter实现剪刀石头布小游戏的方法 发布时间:2020-12-07 10:38:11 来源:亿速云 阅读:90 作者:小新 这篇文章将为大家详细讲解有关用Python Tkint ...

  8. python游戏设计_用Python设计一个经典小游戏

    本文主要介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习. 游戏规则: 初始本金是 ...

  9. python编辑游戏脚本_用PYTHON做一个简单的游戏脚本(基础,详细)

    引言 这段时间迷上了玩点点点的小游戏,但是某些重复的环节着实无聊,就想着能不能用PYTHON做一个游戏脚本,不过为了熟悉需要做脚本的各个模块,于是打算在4399上找一个比较像的游戏做个脚本练练手,后来 ...

最新文章

  1. Camera HDR Algorithms
  2. Java学习总结:48(System类对IO的支持)
  3. 普通人也能用AI拍出3D大片?这位清华博士后这么做
  4. byte数组截取_Go解密:数组、切片
  5. gcc 提供的原子操作
  6. c语言结构体讲解,C语言基础之结构体讲解
  7. JVM异常之:方法区溢出OutOfMemoryError: PermGen space
  8. iphone7wifi模块多少钱_模块炉价格参差不齐,消费者应独具慧眼!
  9. 利用linux的df和du命令查看文件和目录的内存占用
  10. 用int还是用Integer?
  11. 电脑老是弹出vrvedp_m_解答电脑启动项如何设置
  12. 网络(13)-SYN flood及其应对方法
  13. 瑞幸咖啡退市成定局:董事长被要求辞职,新店却仍在扩张
  14. 秋风秋雨愁煞人:寒宵独坐心如捣
  15. poj1182食物链(种类并查集)
  16. mac gcc安装_16_超级小白Mac Pro下安装superset遇见的坑
  17. myeclipse中文界面改颜色_“颜色识别器”安卓APP功能详细介绍
  18. v$session,v$session_wait,v$session_wait_history,v$active_session_history
  19. 中职计算机基础课堂传统教学,中职计算机课堂教学初探
  20. [GXYCTF2019]Ping Ping Ping {命令执行总结}

热门文章

  1. mac使用homebrew安装postgresql
  2. Rabbitmq原理理解
  3. 《考勤管理系统——部分模块》项目研发阶段性总结
  4. mysql的相关优化和解释
  5. 网口芯片W5500使用笔记以及注意点
  6. 工业相机选型(选择工业相机必须搞懂这11大要素)
  7. 【Linux】文件系统的概念和类型
  8. 热点项目参考——数据中台解决方案(PPT,下载)
  9. 高通Camera驱动(3)-- configure_streams
  10. 计算机硬件知识试题,计算机硬件基础知识测试题