在 Python 中使用 OpenCV 构建 Color Catcher 游戏

news2024/12/23 9:31:14

介绍

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

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

设置游戏窗口

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

# Set up the game window
window_size = (640, 480)
window_name = 'Color Catcher'
cv2.namedWindow(window_name)
cv2.moveWindow(window_name, 0, 0)

定义游戏对象

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

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

# Set up the game objects
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 从网络摄像头捕获视频。

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

# Set up the video capture device
cap = cv2.VideoCapture(0)

while True:
    # Read a frame from the video capture device
    ret, frame = cap.read()
    if not ret:
        break

检测玩家的手

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

# Convert the frame to grayscale and apply a threshold
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

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

# Find the contours in the thresholded image
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Find the contour with the largest area, which should be the hand
if contours:
    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 坐标进行比较。如果手在接球手的左侧,我们通过从接球手的当前位置减去接球手的速度,将接球手向左移动。如果手在捕手的右侧,我们通过将捕手的速度添加到其当前位置来将捕手移动到右侧。

if hand_center[0] < catcher_position[0] and catcher_position[0] > 0:
        catcher_position -= catcher_velocity
    elif hand_center[0] > catcher_position[0]+catcher_width and catcher_position[0]+catcher_width < window_size[0]:
        catcher_position += catcher_velocity

生成和移动球:

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

if len(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列表中移除并跳出循环。

for i in range(len(balls)):
        balls[i] = (balls[i][0], balls[i][1]+balls[i][2], balls[i][2])
        ball_position = balls[i][1]
        if ball_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
        elif ball_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)
    for ball in balls:
        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 代码进行比较,如果匹配则退出循环。

# Exit the game if the user presses the 'q' key
if cv2.waitKey(1) & 0xFF == ord('q'):
    break

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

# Release the video capture device and close the game window
cap.release()
cv2.destroyAllWindows()

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

编码愉快!

完整代码:

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

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

1551ea6ddb9a2a29492b9b278dedf6b4.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/542869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swift静态代码检测工程实践

本文字数&#xff1a;22817字 预计阅读时间&#xff1a;58分钟 引言 随着App功能不断增加&#xff0c;工程代码量也随之快速增加&#xff0c;依靠人工CodeReview来保证项目的质量&#xff0c;越来越不现实&#xff0c;这时就有必要借助于自动化的代码审查工具&#xff0c;进行程…

【运维知识进阶篇】集群架构-Nginx七层负载均衡详解

为什么要使用负载均衡 当我们的Web服务器直接面向用户&#xff0c;往往要承载大量并发请求&#xff0c;单台服务器难以负荷&#xff0c;我使用多台Web服务器组成集群&#xff0c;前端使用Nginx负载均衡&#xff0c;将请求分散的打到我们的后端服务器集群中&#xff0c;实现负载…

音频品鉴与歌唱评价——音频内容理解实践

歌唱评价是K歌系统中核心技术之一。近年来&#xff0c;歌唱评价领域也发生着多元化和深度化的变革。本次LiveVideoStackCon 2022 北京站邀请到腾讯音乐天琴实验室高级研究员——江益靓&#xff0c;为大家介绍全民K歌的多维度评价技术和深度歌唱评价技术的实践&#xff0c;以及优…

Linux系统编程学习 NO.3 ——基础指令的学习

* 通配符 通匹配任意字符&#xff08;包括空字符&#xff09;&#xff0c;用于匹配任意长度的字符串。包括空字符。加入你要匹配任何以.txt后缀的文件&#xff0c;只需要在*通配符后加上.txt后缀即可。 样例演示 ls *.后缀名 ls xxx* 找到匹配的字符串man指令(重要) Linux的…

理论力学专题:张量分析

张量方法的引入 自然法则与坐标无关&#xff0c;坐标系的引入方便分析&#xff0c;但也掩盖了物理本质指标符号哑标和自由标 Einstein求和约定&#xff1a;凡在某一项内&#xff0c;重复一次且仅重复一次的指标&#xff0c;表示对该指标在它的取值范围内求和&#xff0c;并称这…

【C++ 入坑指南】(10)函数

文章目录 简介定义实例函数的分文件编写 简介 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;即主函数 main() &#xff0c;所有简单的程序都可以定义其他额外的函数。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定…

分享3个深度学习练手的小案例

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

0ctf_2017_babyheap-fastbin_dup_into_stack

参考&#xff1a; [1]https://uaf.io/exploitation/2017/03/19/0ctf-Quals-2017-BabyHeap2017.html [2]https://blog.csdn.net/qq_43935969/article/details/115877748 [3]https://bbs.kanxue.com/thread-223461.htm 题目下载参考[1] 说明下如何调试堆&#xff0c;在payload中…

chatgpt赋能Python-python3_7如何下载

Python3.7如何下载&#xff1f;详细步骤分享&#xff01; Python是一门当今最热门、最常用、最易学的编程语言之一&#xff0c;且拥有庞大的社区和强大的库支持。在这篇文章中&#xff0c;我们将会详细介绍如何下载Python3.7版本&#xff0c;让大家能够轻松上手Python编程。 …

代码随想录训练营Day44| 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

目录 学习目标 学习内容 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ 学习目标 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ 学习内容 完全背包 problems/背包问题理论基础完全背包.md programmercarl/leetcode-master&#xff08;代码随想录出品&#xff09; - Git…

chatgpt赋能Python-python3_5怎么打开

Python 3.5怎么打开&#xff1f;教你几种方法 Python是目前非常流行的一种编程语言&#xff0c;几乎在所有行业都得到了广泛的应用。Python非常容易上手&#xff0c;且有强大的数据处理和科学计算能力。现在我们来说一下&#xff0c;如何在您的计算机上打开Python 3.5。 方法…

万劫不复之地-云原生可观测性的几大误区

传统监控厂商正把可观测性引入万劫不复之地 可观测性是当前讨论非常多的话题&#xff0c;这个理念由来已久&#xff0c;却在最近开始流行。 在20世纪60年代&#xff0c;该理念首次由Rudolf E. Kalman在其论文中提出&#xff0c;论文题目是《on a general theory of control s…

自然语言处理基础

以下所有内容来自《自然语言处理 基于预训练模型的方法》 1. 文本的表示 利用计算机对自然语言进行处理&#xff0c;首先要解决语言在计算机内部的存储和计算问题。使用字符串表示计算文本的语义信息的时候&#xff0c;往往使用基于规则的方法。如&#xff1a;判断一个句子编…

一文深度解读机器学习模型的评估方法

我们训练学习好的模型&#xff0c;通过客观地评估模型性能&#xff0c;才能更好实际运用决策。模型评估主要有&#xff1a;预测误差情况、拟合程度、模型稳定性等方面。还有一些场景对于模型预测速度&#xff08;吞吐量&#xff09;、计算资源耗用量、可解释性等也会有要求&…

chatgpt赋能Python-python3_8怎么降版本

Python 3.8如何降级版本 在本文中&#xff0c;我们将介绍如何将Python 3.8降级到旧的Python版本。这在一些情况下是有必要的&#xff0c;例如某些软件或库并不支持Python 3.8。Python版本降级不仅有用&#xff0c;还可以帮助您控制您的系统上的软件版本&#xff0c;以确保您的…

网络通信—路由交换协议之TCP协议

目录 一、tcp协议 二、通信消息类型 三、准备阶段&#xff08;三次握手&#xff09; 准备阶段要干什么&#xff1f; 有什么特点&#xff1f; 准备阶段的核心&#xff1f; &#xff08;1&#xff09;准备阶段的数据传输单位 &#xff08;2&#xff09;三次握手的过程 1…

Linux之基础开发工具

文章目录 前言一、yum&#xff08;软件包管理器&#xff09;1.什么是软件包&#xff1f;2.下载软件包1. 安装软件之前需要将软件的安装包下载下来2. 软件包并不在我们的本地电脑&#xff0c;那么软件包在哪里呢&#xff1f;3. 那么问题来了&#xff0c;我们的电脑如何得知要去哪…

npm 配置双因素身份验证

目录 1、关于双因素身份验证 2、NPM上的双因素身份验证 2.1 授权和写入 2.2 仅限授权 3、先决条件 4、从网站配置2FA 4.1 启用2FA 4.2 为写入禁用2FA 4.3 禁用2FA 5、从命令行配置2FA 5.1 从命令行启用2FA 5.2 从命令行发送一次性密码 5.3 从命令行删除2FA 6、配…

chatgpt赋能Python-python3_8怎么安装库

Python 3.8怎么安装库 - 一个简单易懂的指南 如果你正在学习Python编程&#xff0c;或者想要在你的项目中使用Python 3.8&#xff0c;那么你可能需要安装一些Python库。Python库是一些预定义的Python模块&#xff0c;它们可以帮助你更快速地完成你的项目。在这篇文章中&#x…

chatgpt赋能Python-python3_9_6怎么用

Python 3.9.6简介 Python 3.9.6是2021年6月28日发布的Python编程语言的最新版本&#xff0c;它提供了一些有用的新功能和改进&#xff0c;包括优化的解释器性能和可变构造体。它是一种功能强大的编程语言&#xff0c;既易于学习又易于使用&#xff0c;非常适用于开发Web应用程…