OpenCV图像识别初探-50行代码教机器玩2D游戏

最近在研究OpenCV,希望能通过机器视觉解决一些网络安全领域的问题。本文简要介绍如何通过OpenCV实现简单的图像识别,并让计算机通过“视觉”自动玩一个简单的2D小游戏,文末有视频演示及完整代码。

0x01 OpenCV介绍

Open Source Computer Vision Library.OpenCV于1999年由Intel建立,如今由Willow Garage提供支持。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、MacOS操作系统上。它轻量级而且高效——由一系列 C 函数和少量C++类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。最新版本是3.1 ,2016年1月29日发布。(引自百度百科openCV)   

简言之,通过openCV可实现计算机图像、视频的编辑。广泛应用于图像识别、运动跟踪、机器视觉等领域。

0x02 环境

Win7 或Win10操作系统

Python 3.5 以上

0x03 安装

pip install --upgrade setuptools

pip install numpy Matplotlib

pip install opencv-python

pip install pyautogui

pip install mss

pip install pynput

0x04 代码说明

这个网站提供一个简单的2D小游戏,越过障碍获得分数,我们希望让计算机模拟人的行为控制小恐龙跳过地面上不断出现的树木,整个程序可以被分成三个阶段,即屏幕监控(看) > 障碍物识别(识别) > 键盘控制(控制)。

屏幕监控

我们使用python mss对屏幕的指定区域进行监控,其实就是不断截图并对一帧一帧的图片进行分析。 这里monitor变量保存的是屏幕监控的区域

1 with mss.mss() as sct:
2     # Part of the screen to capture
3    ** = {‘top‘: 280, ‘left‘: 100, ‘width‘: 660, ‘height‘: 300}
4     while ‘Screen capturing‘:
5         # Get raw pixels from the screen, save it to a Numpy array
6         img = numpy.array(sct.grab(monitor))

图像识别

上一步我们通过监控屏幕上的指定区域可以获取到一帧一帧的图片,我们的目的是识别屏幕上出现的障碍物,以及障碍物的相对位置,这里主要是用OpenCV的matchTemplate方法在目标截图中查找已知的图像元素,所以我们要先截取一些障碍物的图片,如下图所示:

然后在目标图像中查找,这里我们设定图片比对的相似度阈值为65%,这样相当于是做模糊匹配,虽然可能会降低识别精准度,但可以少准备几个截图
 1 res2 = cv2.matchTemplate(img_gray, tree1, cv2.TM_CCOEFF_NORMED) 2 threshold = 0.65 3 loc2 = numpy.where(res2 >= threshold)

识别到相应的障碍物以后我们希望在物体周围画一个矩形框,这样方便调试和查看效果

1 for pt in zip(*loc2[::-1]):
2 cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th), (0, 0, 255), 2)

鼠标及键盘控制

识别到屏幕上的障碍物以后,我们要控制鼠标和键盘做出相应的操作,这里我们使用pyautoguipynput实现鼠标键盘的模拟

 1 def startgame():
 2     pyautogui.click(web)
 3     time.sleep(0.03)
 4     pyautogui.keyDown(‘space‘)
 5     time.sleep(0.03)
 6     pyautogui.keyUp(‘space‘)
 7     print(‘game start‘)
 8
 9 def jump():
10     key.release(Key.down)
11     key.press(Key.space)
12     print(‘jump‘)
13     time.sleep(0.3)
14     key.release(Key.space)
15     key.press(Key.down)

效果演示

 1 import time
 2 import pyautogui
 3 from pynput.keyboard import Key, Controller
 4 import cv2
 5 import mss
 6 import numpy
 7
 8 # use browser to visit http://www.trex-game.skipser.com/
 9 # put the browser to the left side and run the programme
10
11 key = Controller()
12
13 web = (200, 400)
14
15 tree1 = cv2.imread(‘tree1.png‘, 0)
16 tw, th = tree1.shape[::-1]
17
18 tree4 = cv2.imread(‘tree4.png‘, 0)
19 tw4, th4 = tree4.shape[::-1]
20
21 birdie = cv2.imread(‘birdie1.png‘, 0)
22 nw, nh = birdie.shape[::-1]
23
24
25 def startgame():
26     pyautogui.click(web)
27     time.sleep(0.03)
28     pyautogui.keyDown(‘space‘)
29     time.sleep(0.03)
30     pyautogui.keyUp(‘space‘)
31     print(‘game start‘)
32
33
34 def jump():
35     key.release(Key.down)
36     key.press(Key.space)
37     print(‘jump‘)
38     time.sleep(0.3)
39     key.release(Key.space)
40     key.press(Key.down)
41
42
43 startgame()
44
45 with mss.mss() as sct:
46     # Part of the screen to capture
47
48     monitor = {‘top‘: 280, ‘left‘: 100, ‘width‘: 660, ‘height‘: 300}
49
50     while ‘Screen capturing‘:
51         key.press(Key.down)
52         # Get raw pixels from the screen, save it to a Numpy array
53         img = numpy.array(sct.grab(monitor))
54
55         img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
56
57         res2 = cv2.matchTemplate(img_gray, tree1, cv2.TM_CCOEFF_NORMED)
58         res5 = cv2.matchTemplate(img_gray, tree4, cv2.TM_CCOEFF_NORMED)
59         res3 = cv2.matchTemplate(img_gray, birdie, cv2.TM_CCOEFF_NORMED)
60
61         threshold = 0.65
62
63         loc2 = numpy.where(res2 >= threshold)
64         for pt in zip(*loc2[::-1]):
65             cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th), (0, 0, 255), 2)
66             if pt[0] + tw < 280:
67                 jump()
68                 break
69
70         loc2 = numpy.where(res3 >= threshold)
71         for pt in zip(*loc2[::-1]):
72             cv2.rectangle(img, pt, (pt[0] + nw, pt[1] + nh), (0, 0, 255), 2)
73             print("{0},{1}".format(pt[0], pt[1]))
74             if pt[1] + nh > 280 and pt[0] + nw < 420:
75                 jump()
76                 break
77
78         loc5 = numpy.where(res5 >= threshold)
79         for pt in zip(*loc5[::-1]):
80             cv2.rectangle(img, pt, (pt[0] + tw4, pt[1] + th4), (0, 0, 255), 2)
81             if pt[0] + tw4 < 280:
82                 jump()
83                 break
84
85         # Display the picture
86         cv2.imshow(‘OpenCV/Numpy normal‘, img)
87
88         # Press "q" to quit
89         if cv2.waitKey(25) & 0xFF == ord(‘q‘):
90             cv2.destroyAllWindows()
91             break

HDC.Cloud 华为开发者大会2020 即将于2020年2月11日-12日在深圳举办,是一线开发者学习实践鲲鹏通用计算、昇腾AI计算、数据库、区块链、云原生、5G等ICT开放能力的最佳舞台。

欢迎报名参会https://www.huaweicloud.com/HDC.Cloud.html?utm_source=&utm_medium=&utm_campaign=&utm_content=techcommunity

原文地址:https://www.cnblogs.com/huaweicloud/p/12229581.html

时间: 2024-11-05 15:00:09

OpenCV图像识别初探-50行代码教机器玩2D游戏的相关文章

HTML5游戏实战(1):50行代码实现正面跑酷游戏

前段时间看到一个"熊来了"的HTML5跑酷游戏,它是一个典型的正面2D跑酷游戏,这里借用它来介绍一下用Gamebuilder+CanTK开发正面跑酷游戏的基本方法. 0.先Show一下最终成果: 在线运行:http://gamebuilder.duapp.com/apprun.php?appid=ZecSmA0UGRTh9juSEmu8RjkK-41416104149375 在线编辑:http://gamebuilder.duapp.com/gamebuilder.php?appid=

iOS开发——实用技术OC篇&amp;8行代码教你搞定导航控制器全屏滑动返回效果

8行代码教你搞定导航控制器全屏滑动返回效果 前言 此次文章,讲述的是导航控制器全屏滑动返回效果,而且代码量非常少,10行内搞定. 效果如图: 如果喜欢我的文章,可以关注我,也可以来小码哥,了解下我们的iOS培训课程.陆续还会有更新ing.... 一.自定义导航控制器 目的:以后需要使用全屏滑动返回功能,就使用自己定义的导航控制器. 二.分析导航控制器侧滑功能 效果:导航控制器默认自带了侧滑功能,当用户在界面的左边滑动的时候,就会有侧滑功能. 系统自带的侧滑效果: 分析: 1.导航控制器的view

[Lua]50行代码的解释器,用来演示lambda calculus

嗯,来写写经过: 在知乎上看见用Belleve牛用javascript写了一个精简的lisp解释器 => 我也想写一个,用lua写,能多简单呢? => 写了一个阉割的scheme解释器,包含lambda/if两个special form,以及+-=print几个过程,60行代码 => 能再精简吗?比如把if给去掉? => 搜索,嗯,lambda calculus能帮我 => 阅读wiki上lambda calculus的"Encoding datatypes&quo

50行代码实现缓存,JAVA内存模型原理

遇见这样的高人怎么办??下面是一个简单缓存的实现,相当牛叉!自己看吧,只有50行代码. 摘自:http://www.oschina.net/code/snippet_55577_3887 import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.

50行代码实现Java方法代理

工作中经常需要对现有程序进行一些扩展,而不想修改现有代码.可以使用代理方法,常使用的代理技术有JDK的java.lang.reflect.Proxy.spring的代理等. 例如对方法加事务,就常用org.springframework.transaction.interceptor.TransactionInterceptor.他就是在现有方法前面开启事务,后面关闭事务. 本文以spring+aspectj做一个简单的例子: 1.使用maven依赖的文件如下:         <depende

Python 50行代码实现代理服务器(加强版)

网上很多python 50行代码实现代理服务器,但是易出现异常,导致退出. 这里的代理服务器,是指二级代理服务器.比如:A可以访问B,B可以访问C,A不能直接访问C.这时,如果在B开一个二级代理,就可实现A访问C.现有的工具有CCProxy. 这里就是使用Python简单的实现一个二级代理. #coding=utf-8 import socket import select import sys import threading import time import logging import

python爬虫实战:利用scrapy,短短50行代码下载整站短视频

近日,有朋友向我求助一件小事儿,他在一个短视频app上看到一个好玩儿的段子,想下载下来,可死活找不到下载的方法.这忙我得帮,少不得就抓包分析了一下这个app,找到了视频的下载链接,帮他解决了这个小问题. 因为这个事儿,勾起了我另一个念头,这不最近一直想把python爬虫方面的知识梳理梳理吗,干脆借机行事,正凑着短视频火热的势头,做一个短视频的爬虫好了,中间用到什么知识就理一理. 我喜欢把事情说得很直白,如果恰好有初入门的朋友想了解爬虫的技术,可以将就看看,或许对你的认识会有提升.如果有高手路过,

从零开始学C语言,200行代码完成一个打字母游戏!

很多刚开始学习编程的同学都希望自己可以去开发一些游戏,当学习了c语言的时候却发现总是用c语言去解决一些数学问题,今天我就分享给大家一个我学习c语言时候学到的一些好玩的东西,希望可以帮助大家保持对编程的兴趣. 创一个小群,供大家学习交流聊天如果有对学C++方面有什么疑惑问题的,或者有什么想说的想聊的大家可以一起交流学习一起进步呀.也希望大家对学C++能够持之以恒C++爱好群,如果你想要学好C++最好加入一个组织,这样大家学习的话就比较方便,还能够共同交流和分享资料,给你推荐一个学习的组织:快乐学习

Python黑科技:50行代码运用Python+OpenCV实现人脸追踪+详细教程+快速入门+图像识

嗨,我最亲爱的伙计们,很高兴我们又见面了. 首先先感谢朋友们的关注.当然我更希望认识与计算机相关的领域的朋友咱们一起探讨交流.重点说一下,我是真人,不是那些扒文章的自媒体组织,大家可以相互交流的! 本篇文章我们来讲一下关于AI相关的人脸追踪,人脸识别相关的一些知识.当然本篇教程为(上)部分,讲一下利用python+opencv来实现人脸识别与追踪,明后天出(下)部分,用python来通过指纹对比实现人脸验证.人脸解锁(大家感兴趣的可以提前关注哦). 这两节课呢,代码量都不是很多,鄙人尽量多注释点