在Minecraft这个充满无限创造与探索机会的游戏中,收集材料是一项重复且耗时的任务。为了简化这一过程,可以利用计算机视觉技术来构建一个视频游戏控制器。近年来,计算机视觉技术取得了飞速发展,它在许多领域都展现出了强大的能力。因此,借助计算机视觉,可以为Minecraft创建一个简单的木材采集脚本。
本教程将教授如何创建一个计算机视觉模型,并使用Workflows这个免费的无代码工具来实现计算机视觉。还将学习如何实现方向逻辑,以便在Minecraft中构建一个简单的脚本。通过本指南的学习,将掌握如何在Minecraft中构建一个简单的木材采集脚本。
在深入学习之前,以下是将要覆盖的步骤,以成功构建此项目:
首先,注册并创建一个Roboflow账户。然后,进入工作区并创建一个项目,自定义项目名称和注释组。确保创建一个目标检测项目。接下来,添加图片。为了创建一个Minecraft脚本,添加游戏图片。然后,添加希望模型检测的类别。在例子中,需要检测准星和树木。
接下来,标注数据集并在必要的对象周围绘制边界框。现在已经拥有了标注和图片,可以生成一个带有标签的图片的数据集版本。每个版本都是唯一的,并且与训练的模型相关联,因此可以迭代增强和数据实验。
Workflows是一个基于Web的交互式计算机视觉应用程序构建器。可以使用Workflows来定义可以在云端或自己的硬件上运行的多阶段计算机视觉应用程序。在这一步结束时,工作流将能够:
总体的工作流将类似于这样:
# 进入Roboflow应用程序中的Workflows
# 点击“创建工作流”
# 点击“自定义工作流”并点击“创建”
# 导航到添加块并搜索“目标检测”
# 添加目标检测块
# 选择想要使用的具体目标检测模型
# 使用过滤器预测块来过滤特定的预测
# 使用类过滤器来分离树木预测和准星预测
现在,工作流应该类似于这样。但是,这不是想要的。需要将两个检测过滤器连接到目标检测模型上,并将两者都作为输出。为了改变这一点,点击第二个检测过滤器并将参考输入更改为模型。
最后,将两个作为单独的输出添加到响应块中。现在可以保存并部署模型。确保保存部署代码,因为将在稍后的教程中使用它。
在这一步中,将开始下载所需的库以开始编程。首先下载必要的库:
pip install supervision inference numpy pyautogui
接下来,将库导入到喜欢的代码编辑器中的新脚本:
import cv2
import numpy as np
import pyautogui
import supervision as sv
from inference_sdk import InferenceHTTPClient
import time
为了看到检测结果,需要使用Supervision库。Supervision提供了一个全面的资源列表,以满足所有的计算机视觉需求。这个库将帮助轻松实现检测到的树木和准星的视觉效果。
# 创建一个显示预测的函数
def show_detections(input):
detections = sv.Detections.from_inference(input)
frame = sv.BoxAnnotator().annotate(scene=frame, detections=detections)
frame = sv.LabelAnnotator().annotate(scene=frame, detections=detections)
# 创建一个在Minecraft中采矿的函数
def mine_block():
pyautogui.mouseDown(button='left')
time.sleep(4)
pyautogui.mouseUp(button='left')
pyautogui.keyDown('w')
time.sleep(1)
pyautogui.keyUp('w')
在这个函数中,将预测最近的树木相对于准星的位置,然后采矿。首先,获取部署代码并使用托管的API选项。还要确保创建一个循环,该循环截取屏幕截图并将其发送到工作流。
# 获取部署代码并使用托管的API选项
client = InferenceHTTPClient(api_url="https://detect.roboflow.com", api_key="API")
while True:
img = pyautogui.screenshot(region=(1055, 0, 855, 510))
frame = np.array(img)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
results = client.run_workflow(workspace_name="", workflow_id="", images={"image": frame})
# 从工作流的输出中获取树木和准星的值
trees = results[0]['predictions']
crosshair = results[0]['output']
if trees:
show_detections(trees)
if crosshair:
show_detections(crosshair)
cv2.imshow("annoated_frame", frame)
接下来,需要计算最近的树木相对于准星的位置。可以通过使用每个项目的x轴来做到这一点。以下代码循环遍历一个数组,并使用树木的x轴位置减去准星的x轴位置的绝对值来找到最近的树木。
prev_abs = 2000
num = 0
if crosshair['predictions'] and trees['predictions']:
for i, tree in enumerate(trees['predictions']):
if np.abs(tree['x'] - crosshair['predictions'][0]['x']) < prev_abs:
prev_abs = tree['x']
num = i
使用最近的树木,需要将光标移动到树木的特定区域以进行采矿。首先,需要看看树木是在准星的右侧还是左侧。找到准星相对于树木的位置后,可以通过减去准星的x轴距离来获得光标的移动(或者对于左侧方向则相反)。如果准星和树木之间的距离小于30像素(一个随机设置的变量),那么将调用mine_block函数,该函数将按住鼠标并移动以收集块。
if (crosshair['predictions'][0]['x']) > trees['predictions'][num]['x']:
print("detected move right")
move_amount = int(crosshair['predictions'][0]['x'] - trees['predictions'][num]['x'])
time.sleep(0.5)
pyautogui.moveRel(move_amount, 0)
if ((crosshair['predictions'][0]['x']) - trees['predictions'][num]['x']) < 30:
mine_block()
elif (crosshair['predictions'][0]['x']) < trees['predictions'][num]['x']:
print("detected move left")
move_amount = int(trees['predictions'][num]['x'] - crosshair['predictions'][0]['x'])
time.sleep(0.5)
pyautogui.moveRel(-move_amount, 0)
if (trees['predictions'][num]['x'] - crosshair['predictions'][0]['x']) < 30:
mine_block()
最后,需要设置一个停止键来停止程序:
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()