在 Python 中使用 OpenCV 构建 Color Catcher 游戏
2023-05-19 11:33:40    磐创AI

介绍

你是否曾经想在 Python 中使用 OpenCV 创建自己的游戏?

今天我们将构建一个名为 Color Catcher 的游戏,该游戏挑战玩家使用手部跟踪机制接住从屏幕顶部掉落的彩球。


(资料图片)

设置游戏窗口

构建游戏的第一步是使用 OpenCV 设置游戏窗口。我们将定义窗口大小、创建窗口并设置其在屏幕上的位置:

#Setupthegamewindow

window_size=(640,480)

window_name="ColorCatcher"

cv2.namedWindow(window_name)

cv2.moveWindow(window_name,0,0)

定义游戏对象

接下来,我们将定义游戏对象。在 Color Catcher 中,我们有两个主要的游戏对象:捕手和球。

捕手是玩家用手移动的矩形,而球是从屏幕顶部落下的随机生成的圆圈。我们将定义这些游戏对象的属性:

#Setupthegameobjects

catcher_color=(0,0,255)

catcher_width=100

catcher_height=20

catcher_position=np.array([window_size[0]//2,window_size[1]-catcher_height],dtype=int)

catcher_velocity=np.array([10,0],dtype=int)

ball_radius=20

ball_speed=5

ball_colors=[(0,255,0),(255,0,0),(0,0,255)]

balls=[]

score=0

从网络摄像头捕获视频

为了跟踪玩家的手部动作,我们需要使用 OpenCV 从网络摄像头捕获视频。

我们将创建一个视频捕获设备并循环播放视频的每一帧:

#Setupthevideocapturedevice

cap=cv2.VideoCapture(0)

whileTrue:

#Readaframefromthevideocapturedevice

ret,frame=cap.read()

ifnotret:

break

检测玩家的手

为了跟踪玩家的手部动作,我们将使用 OpenCV 的轮廓检测功能。首先,我们将每个帧转换为灰度并应用阈值以便更容易检测轮廓:

#Converttheframetograyscaleandapplyathreshold

gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

_,thresh=cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

接下来,我们将在阈值图像中找到轮廓,并确定面积最大的轮廓,这应该是玩家的手:

#Findthecontoursinthethresholdedimage

contours,_=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

#Findthecontourwiththelargestarea,whichshouldbethehand

ifcontours:

hand_contour=max(contours,key=cv2.contourArea)

hand_hull=cv2.convexHull(hand_contour)

hand_center=np.mean(hand_contour,axis=0,dtype=int)[0]

移动捕手

一旦我们检测到玩家手的位置,我们就可以相应地移动捕手。

在代码中,我们检查手中心的 x 坐标并将其与接球手位置的 x 坐标进行比较。如果手在接球手的左侧,我们通过从接球手的当前位置减去接球手的速度,将接球手向左移动。如果手在捕手的右侧,我们通过将捕手的速度添加到其当前位置来将捕手移动到右侧。

ifhand_center[0]0:

catcher_position-=catcher_velocity

elifhand_center[0]>catcher_position[0]+catcher_widthandcatcher_position[0]+catcher_width

catcher_position+=catcher_velocity

生成和移动球:

如果当前比赛中的球数少于五个,我们将生成具有随机颜色和位置的新球。我们将包含球的颜色、位置和速度的元组附加到balls列表中。

iflen(balls)<5:

ball_color=random.choice(ball_colors)

ball_position=np.array([random.randint(ball_radius,window_size[0]-ball_radius),0],dtype=int)

ball_velocity=np.array([0,ball_speed],dtype=int)

balls.append((ball_color,ball_position,ball_velocity))

然后我们遍历balls列表中的每个球,通过将其速度添加到其当前位置来更新其位置,并检查它是否与接球手发生碰撞或击中游戏窗口的底部。

如果球与接球手发生碰撞,我们将其从balls列表中移除,增加玩家的得分,然后跳出循环。

如果球击中了游戏窗口的底部,我们将其从balls列表中移除并跳出循环。

foriinrange(len(balls)):

balls[i]=(balls[i][0],balls[i][1]+balls[i][2],balls[i][2])

ball_position=balls[i][1]

ifball_position[1]+ball_radius>=catcher_position[1]and

ball_position[0]>=catcher_position[0]and

ball_position[0]<=catcher_position[0]+catcher_width:

balls.pop(i)

score+=1

break

elifball_position[1]+ball_radius>=window_size[1]:

balls.pop(i)

break

绘制游戏对象:

最后,我们使用cv2.rectangle()和cv2.circle()函数在框架上绘制游戏对象。我们使用np.zeros()创建一个黑色框架,将捕手绘制为红色矩形,并将每个球绘制为彩色圆圈。

我们还使用cv2.putText()函数在框架的左上角显示玩家的分数。

frame=np.zeros(window_size+(3,),dtype=np.uint8)

cv2.rectangle(frame,tuple(catcher_position),tuple(catcher_position+np.array([catcher_width,catcher_height])),catcher_color,-1)

forballinballs:

cv2.circle(frame,tuple(ball[1]),ball_radius,ball[0],-1)

cv2.putText(frame,"Score:{}".format(score),(10,30),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),2)

cv2.imshow(window_name,frame)

退出游戏:

最后,游戏循环包含在while循环中。在这个循环中,执行以下任务:

使用cap.read()方法从视频捕获设备读取新帧。处理框架以检测手区域并相应地移动捕手。如有必要,将生成一个具有随机颜色和位置的新球。球被移动并检查是否与接球手发生碰撞。游戏对象绘制在框架上。框架显示在屏幕上。循环继续,直到用户按下“q”键。

按“q”键可以退出游戏。这是使用cv2.waitKey()方法完成的,该方法等待键盘事件的给定毫秒数。如果按键被按下,该方法返回按键的 ASCII 代码,如果没有按键被按下,则返回 -1。

我们使用按位与运算符 ( &) 提取结果的最低有效 8 位,这为我们提供了按 256 模的按下键的 ASCII 代码。我们将此值与 "q" 键 ( ord("q")) 的 ASCII 代码进行比较,如果匹配则退出循环。

#Exitthegameiftheuserpressesthe"q"key

ifcv2.waitKey(1)&0xFF==ord("q"):

break

退出循环后,我们分别使用cap.release()和cv2.destroyAllWindows()方法释放视频捕获设备并关闭游戏窗口。

#Releasethevideocapturedeviceandclosethegamewindow

cap.release()

cv2.destroyAllWindows()

就是这样!你现在应该能够运行代码并玩游戏了。这个游戏是一个简单的例子,说明了如何使用计算机视觉来实时控制游戏对象的移动。当然,还有很大的改进和优化空间,但这应该足以让你入门。

编码愉快!

完整代码:

https://github.com/Yaga987/Computer-Vision/blob/main/CompVisGame.py

原文标题:在 Python 中使用 OpenCV 构建 Color Catcher 游戏

关键词:

下一篇: 车间员工优秀事迹范文(热门40篇)
上一篇: 金价显著下跌!

摩洛哥南部地震致至少296人遇难 血液中心呼吁民众积极献血

被蜱虫咬属于意外险吗?赔偿要提供什么材料?

2023国际高桥极限运动邀请赛举行

筹集5693套保租房 开建4267套棚改房 宜昌5000余“新市民”圆了“安居梦”

富士X100V迭代款将更新 配备新镜头

持续推进长三角一体化,沪苏水域交通组织一体化若干措施发布

【青视点】剑指“中国休闲体育之城” 莱西打算这么干

长城汽车魏建军转型中很擅长做“毫不犹豫”的事

幻想传说修复弓(幻想传说x)

祝贺!中国女乒包揽四强!王艺迪逆转伊藤美诚,日本女乒全军覆没

烧瓷器的失败作品“嘴硬壶”意外成网红 山东买家288元买下 2000元不愿意转让

“种黄花这条路走对啦!”

火山引擎ByteHouse上线ELT能力,进一步降低企业数字化维护成本

iFixit拆毁了三星的新款GalaxyS22和S22Ultra智能手机

600元可亲吻? 莫把“沉浸式消费”玩成“沉沦式消费”

今日车轱辘是什么意思饭圈(车轱辘话什么意思)

公职人员被儿子举报出轨朋友妻子 官方回应:已被停职并立案调查

人工智能赋能可持续投资

探索数字化普惠金融新路径

通辽市奈曼旗300MW风电项目二标段37台风机吊装完成

安卓将迈入2TB时代!三星Galaxy S24 Ultra首发:售价过万

亚盛集团:8月31日融资净买入276.08万元,连续3日累计净买入734万元

南京新百4140万预付款背后 交易对手疑为控股股东关联方

sw2018破解版详细安装教程云魔方(solidworks魔方云学院)

江苏南通可提供东芝洗碗机维修服务地址在哪

公大研招网 公大

世茂股份:截止8月底未能按期支付债务累计84.8亿元

8月31日超讯通信涨停分析:智能制造,5G,智慧物流概念热股

捷途大圣对比长安CS55 PLUS,谁高颜高配强动力,更讨年轻人欢心?

新城发展:一年内到期债务256.16亿元,确保每一笔债务提前或到期偿付

主板纺织股(主板纺织上市企业名单2023)

宋祖儿前公司否认实名举报 称未参与艺人纳税申报

9月1日起实施!呼和浩特市三部门联合通知

供应链人士称Wi-Fi 7出货将于2024年放量

首张水上加油站危化品经营许可证颁发 崇川区18家相关企业计划年底前全部领证

北京市全力以赴确保“课前到书,人手一册”迎开学