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

 

私货时间:5G时代,选择华为云!华为云专蜀月·西南钜惠活动开启,给力优惠请看文末。

感兴趣的四川小伙伴请访问:
https://activity.huaweicloud.com/citysummit/internet.html?utm_source=&utm_medium=&utm_campaign=&utm_content=sichuan

<https://activity.huaweicloud.com/citysummit/internet.html?utm_source=&utm_medium=&utm_campaign=&utm_content=sichuan>
,留下您的信息,我们会第一时间与您联系!

 

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 代码说明

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

屏幕监控

我们使用python mss对屏幕的指定区域进行监控,其实就是不断截图并对一帧一帧的图片进行分析。 这里monitor变量保存的是屏幕监控的区域
with mss.mss() as sct: # Part of the screen to capture ** = {'top': 280,
'left': 100, 'width': 660, 'height': 300} while 'Screen capturing': # Get raw
pixels from the screen, save it to a Numpy array img =
numpy.array(sct.grab(monitor))
图像识别

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

然后在目标图像中查找,这里我们设定图片比对的相似度阈值为65%,这样相当于是做模糊匹配,虽然可能会降低识别精准度,但可以少准备几个截图
res2 = cv2.matchTemplate(img_gray, tree1, cv2.TM_CCOEFF_NORMED) threshold =
0.65 loc2 = numpy.where(res2 >= threshold)
识别到相应的障碍物以后我们希望在物体周围画一个矩形框,这样方便调试和查看效果
for pt in zip(*loc2[::-1]): cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th),
(0, 0, 255), 2)
鼠标及键盘控制

识别到屏幕上的障碍物以后,我们要控制鼠标和键盘做出相应的操作,这里我们使用pyautogui和pynput实现鼠标键盘的模拟
def startgame(): pyautogui.click(web) time.sleep(0.03)
pyautogui.keyDown('space') time.sleep(0.03) pyautogui.keyUp('space')
print('game start') def jump(): key.release(Key.down) key.press(Key.space)
print('jump') time.sleep(0.3) key.release(Key.space) key.press(Key.down)
效果演示


import time import pyautogui from pynput.keyboard import Key, Controller
import cv2 import mss import numpy # use browser to visit
http://www.trex-game.skipser.com/ # put the browser to the left side and run
the programme key = Controller() web = (200, 400) tree1 =
cv2.imread('tree1.png', 0) tw, th = tree1.shape[::-1] tree4 =
cv2.imread('tree4.png', 0) tw4, th4 = tree4.shape[::-1] birdie =
cv2.imread('birdie1.png', 0) nw, nh = birdie.shape[::-1] def startgame():
pyautogui.click(web) time.sleep(0.03) pyautogui.keyDown('space')
time.sleep(0.03) pyautogui.keyUp('space') print('game start') def jump():
key.release(Key.down) key.press(Key.space) print('jump') time.sleep(0.3)
key.release(Key.space) key.press(Key.down) startgame() with mss.mss() as sct: #
Part of the screen to capture monitor = {'top': 280, 'left': 100, 'width': 660,
'height': 300} while 'Screen capturing': key.press(Key.down) # Get raw pixels
from the screen, save it to a Numpy array img = numpy.array(sct.grab(monitor))
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) res2 =
cv2.matchTemplate(img_gray, tree1, cv2.TM_CCOEFF_NORMED) res5 =
cv2.matchTemplate(img_gray, tree4, cv2.TM_CCOEFF_NORMED) res3 =
cv2.matchTemplate(img_gray, birdie, cv2.TM_CCOEFF_NORMED) threshold = 0.65 loc2
= numpy.where(res2 >= threshold) for pt in zip(*loc2[::-1]): cv2.rectangle(img,
pt, (pt[0] + tw, pt[1] + th), (0, 0, 255), 2) if pt[0] + tw < 280: jump() break
loc2 = numpy.where(res3 >= threshold) for pt in zip(*loc2[::-1]):
cv2.rectangle(img, pt, (pt[0] + nw, pt[1] + nh), (0, 0, 255), 2)
print("{0},{1}".format(pt[0], pt[1])) if pt[1] + nh > 280 and pt[0] + nw < 420:
jump() break loc5 = numpy.where(res5 >= threshold) for pt in zip(*loc5[::-1]):
cv2.rectangle(img, pt, (pt[0] + tw4, pt[1] + th4), (0, 0, 255), 2) if pt[0] +
tw4 < 280: jump() break # Display the picture cv2.imshow('OpenCV/Numpy normal',
img) # Press "q" to quit if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows() break
 来源:华为云社区 <https://bbs.huaweicloud.com/blogs/63072f268dbd11e9b759fa163e330718>
 作者:菊花茶

 

私货时间:

5G时代,选择华为云!华为云专蜀月·西南钜惠活动开启:

西南节点云主机低至华北节点价格48折,四川老用户新增消费最高返50%,还有云迁移、安全检测、等保咨询、耀星计划扶持等给力福利;四川新用户最高免费送2万
测试券,还有技术赋能、圈子赋能等诸多专享福利;华为云生态伙伴首单5折起。

感兴趣的四川小伙伴请访问:
https://activity.huaweicloud.com/citysummit/internet.html?utm_source=&utm_medium=&utm_campaign=&utm_content=sichuan

<https://activity.huaweicloud.com/citysummit/internet.html?utm_source=&utm_medium=&utm_campaign=&utm_content=sichuan>

留下您的信息,我们会第一时间与您联系!

 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信