AI 视觉仪#

简介#

VEX AIM 编码机器人的 AI 视觉传感器能够检测和跟踪物体、颜色以及 AprilTag ID。这使得机器人能够分析周围环境、跟踪物体并根据检测到的视觉数据做出反应。

AI视觉传感器的分辨率为320×240像素。原点(0, 0)位于左上角,传感器中心位于(160, 120),如下图所示:

展示 AIM AI 视觉仪分辨率的示意图,坐标 0, 0 位于示意图左上角,320, 0 位于右上角,0, 240 位于左下角,正中心为 160, 120。

以下是所有方法和属性的列表:

操作——显示或隐藏AI视觉摄像头画面。

  • [show_aivision] (#show_aivision) —在机器人屏幕上显示AI 视觉画面。

  • [hide_aivision] (#hide_aivision) —从屏幕隐藏 AI 视觉画面。

  • [tag_detection] (#tag_detection) —打开或关闭AprilTag ID检测。

获取器 — 检测机器人是否持有物体。

  • [get_data] (#get_data) —针对特定特征返回一个包含所检测物体的元组。

  • [has_sports_ball] (#has_sports_ball) —返回机器人是否持有运动球。

  • [has_any_barrel] (#has_any_barrel) —返回机器人是否持有任何类型的桶。

  • [has_blue_barrel] (#has_blue_barrel) —返回机器人是否持有蓝色桶。

  • [has_orange_barrel] (#has_orange_barrel) —返回机器人是否持有橙色桶。

Properties — Object data returned from get_data.

  • [exists] (#exists) —对象是否以布尔值存在于当前检测中。

  • [width] (#width) —检测到的对象的宽度。

  • [height] (#height) —检测到的物体的高度。

  • [centerX] (#centerx) —对象中心的X位置。

  • [centerY] (#centery) —对象中心的Y位置。

  • [bearing] (#bearing) —相对于机器人前部的水平角度。

  • [rotation] (#rotation) —对象的方向。

  • [originX] (#originx) —对象左上角的X位置。

  • [originY] (#originy) —对象左上角的Y位置。

  • [id] (#id) —对象的分类或标记ID。

  • [score] (#score) —AI分类的置信度得分。

  • [type] (#type) —返回对象的类型( AI、Tag、Color或Code )。

构造函数——定义颜色签名和代码。

操作#

show_aivision#

show_aivision 在机器人屏幕上显示 AI 视觉传感器的实时数据画面。该实时画面将覆盖屏幕上的任何其他图像或文本。

Note: The screen will not display any other images or text unless hide_aivision is used to hide the feed.

Usage:
robot.screen.show_aivision()

参数

描述

该方法没有参数。

# Watch the AI Vision Sensor detect AI Classifications
# and AprilTag IDs as you move the robot
robot.screen.show_aivision()

hide_aivision#

hide_aivision 从机器人屏幕上移除 AI 视觉传感器的实时数据画面。

Usage:
robot.screen.hide_aivision()

参数

描述

该方法没有参数。

# View the AI Vision Sensor's feed for five seconds
robot.screen.show_aivision()
wait(5, SECONDS)
robot.screen.hide_aivision()

tag_detection#

tag_detection 启用或禁用AprilTag ID检测,其中状态为布尔值。

传感器可以检测Circle21h7系列中的AprilTag ID 0至36。

用法:
robot.vision.tag_detection(state)

参数

描述

state

值为: True,启用AprilTag ID检测;或 False,禁用AprilTag ID检测。

robot.screen.set_font(PROP30)

# Cut off AprilTag ID detection after 5 seconds
while True:
    if timer.time(SECONDS) > 5:
        robot.vision.tag_detection(False)

    robot.screen.clear_screen()
    robot.screen.set_cursor(3, 1)
    apriltags = robot.vision.get_data(ALL_TAGS)

    if apriltags[0].exists:
        robot.screen.print("AprilTag ID detected!")
    else:
        robot.screen.print("Nothing detected!")

    wait(0.1, SECONDS)

Getters#

get_data#

get_data 将数据从AI视觉传感器帧过滤到单一特征—传感器可以识别的内容的已保存描述,例如预训练对象、AprilTag ID或配置的颜色特征或颜色代码—并返回[元组] (Logic/Variables.md#tuple)。

必须先在 AI Vision 实用程序中配置 颜色签名颜色代码,然后才能使用此方法。

该元组(Logic/Variables.md#tuple)存储对象,按宽度从大到小排序,索引从0开始。每个对象的属性(#properties)可以通过其索引访问。如果没有检测到匹配的对象,则返回空元组。

Usage:
robot.vision.get_data(signature, count)

参数

描述

signature

过滤数据集,仅包含给定特征的数据。可用的特征包括:

  • ALL_VISION - 运动球、球桶、VEX AIM 编程机器人、AprilTag ID、颜色和颜色编码
  • ALL_CARGO - 运动球和球桶
  • ALL_TAGS - 所有 AprilTag ID
  • ALL_COLORS - 所有已配置的颜色特征和颜色编码
  • SPORTS_BALL - 仅运动球
  • BLUE_BARREL - 仅蓝色球桶
  • ORANGE_BARREL - 仅橙色球桶
  • AIM_ROBOT - 所有 VEX AIM 编程机器人
  • TAG0TAG37 - ID 从 0 到 37 的单个 AprilTag
  • NAME - 颜色特征或颜色编码,其中 NAME 是在 AI Vision Utility 中配置的名称。

count

可选。设置可返回的最大对象数,范围为 1 至 24(默认值:8)。

Note: AprilTag IDs 5 through 37 can be obtained by using the printed AprilTag IDs from AIM Printables.

# Move forward if a sports ball is detected
while True:
    ball = robot.vision.get_data(SPORTS_BALL)
    if ball[0].exists:
        robot.move_for(10, 0)
    wait(50, MSEC)

查看数据#

打印 get_data 返回的元组将显示所有检测到的对象的全部属性列表:

  • [exists] (#exists)

  • [type] (#type)

  • [id] (#id)

  • [centerX] (#centerx)

  • [centerY] (#centery)

  • [originX] (#originx)

  • [originY] (#originy)

  • [width] (#width)

  • [height] (#height)

  • [bearing] (#bearing)

  • [rotation] (#rotation)

# Display properties of all detected AprilTag IDs
while True:
    vision_data = robot.vision.get_data(ALL_TAGS)

    if vision_data[0].exists:
        break

    wait(0.25, SECONDS)

print(vision_data)

控制台窗口截图,显示检测到的 AprilTag ID 的调试输出。文本列出了“对象 #0”,其字段包括 exists: True, type: AprilTag ID, id: 2, centerX: 223, centerY: 54, originX: 210, originY: 42, width: 27, height: 23, bearing: 14.1, 和 rotation: 0.0,之后是一个分隔符,然后是“对象 #1”的开头,其字段包括 exists: True, type: AprilTag ID, id: 4, 和 centerX: 122。

AI 分类#

AIM AI视觉传感器可以检测以下AI分类:

ID 号码

AI分类

特征

0

SPORTS_BALL

1

蓝桶

BLUE_BARREL

2

橙色桶

ORANGE_BARREL

3

AIM机器人

AIM_ROBOT

颜色特征#

颜色特征是 AI 视觉传感器可以识别的一种独特颜色。这些特征允许传感器根据颜色来检测和跟踪物体。一旦配置了颜色特征,传感器就可以在其视野中识别具有该特定颜色的物体。颜色特征与 get_data 一起使用,以实时处理并检测彩色物体。

AI 视觉实用程序展示了一个连接的视觉传感器正在检测两个彩色物体。左侧显示实时摄像头画面,左侧为蓝色框,右侧为红色框,每个框都带有白色边框。黑色标签显示其各自的名称、坐标和尺寸。右侧包含颜色签名设置,红色和蓝色框的色调和饱和度范围均有滑块。底部是添加颜色、冻结视频、复制和保存图像的按钮,右下角有一个关闭按钮。

# Display if any objects match the Red_Box signature
while True:
    robot.screen.set_cursor(1, 1)
    robot.screen.clear_row(1)
    # Change to any configured Color Signature
    ai_objects = robot.vision.get_data(Red_Box)
    if ai_objects[0].exists:
        robot.screen.print("Color signature detected!")

颜色代码#

颜色代码是由 2 到 4 个按特定顺序排列的颜色特征组成的结构化模式。这些代码使 AI 视觉传感器能够识别预定义的颜色模式。颜色代码可用于识别复杂物体或为自主导航创建独特的标记。

AI Vision Utility 界面显示一个已连接的视觉传感器正在检测两个相邻的物体,左侧为蓝色框,右侧为红色框,它们被组合成一个标记为 BlueRed 的白色边界框。检测信息包括角度 (A:11°)、坐标 (X:143, Y:103)、宽度 (W:233) 和高度 (H:108)。右侧面板列出了三个颜色特征:Red_Box、Blue_Box 和 BlueRed,并可调整色调和饱和度范围。BlueRed 特征结合了 Blue_Box 和 Red_Box。视频源下方是标有“冻结视频”、“复制图像”、“保存图像”和“关闭”的按钮。

# Display if any objects match the BlueRed code
while True:
    robot.screen.set_cursor(1, 1)
    robot.screen.clear_row(1)
    # Change to any configured Color Code
    ai_objects = robot.vision.get_data(BlueRed)
    if ai_objects[0].exists:
        robot.screen.print("Color code detected!")

has_sports_ball#

has_sports_ball 返回一个布尔值,指示机器人当前是否具有运动球。

  • True — 机器人有一个运动球。

  • False —机器人没有运动球。

Usage:
robot.has_sports_ball()

参数

描述

该方法没有参数。

# Kick when the robot has a sports ball
while True:
    if robot.has_sports_ball():
        robot.kicker.kick(MEDIUM)

    wait(50, MSEC)

has_any_barrel#

has_any_barrel 返回一个布尔值,指示机器人当前是否具有任何类型的桶。

  • True — — 机器人有一个桶。

  • False — 机器人没有桶。

Usage:
robot.has_any_barrel()

参数

描述

该方法没有参数。

# Push a barrel away when detected
while True:
    if robot.has_any_barrel():
        robot.kicker.place()

    wait(50, MSEC)

has_blue_barrel#

has_blue_barrel 返回一个布尔值,指示机器人当前是否具有蓝色桶。

  • True - 机器人有一个蓝色桶。

  • False — 机器人没有蓝色桶。

Usage:
robot.has_blue_barrel()

参数

描述

该方法没有参数。

# Push a blue barrel away when detected
while True:
    if robot.has_blue_barrel():
        robot.kicker.place()

    wait(50, MSEC)

has_orange_barrel#

has_orange_barrel 返回一个布尔值,指示机器人当前是否具有橙色桶。

  • True —机器人有一个橙色的桶。

  • False —机器人没有橙色桶。

Usage:
robot.has_orange_barrel()

参数

描述

该方法没有参数。

# Push an orange barrel away when detected
while True:
    if robot.has_orange_barrel():
        robot.kicker.place()

    wait(50, MSEC)

属性#

在使用 robot.vision.get_data 方法后,存储在元组中的每个对象都包含十二个属性。

.id.score.type 外,所有属性值均描述在调用 robot.vision.get_data 时检测到的物体的位置、大小、朝向或方位角。这些值以像素或度为单位,基于传感器 320×240 像素的分辨率。

! [一个带有橙色条纹的蓝色桶在框架中居中,周围是一个黑色边界框。x和y轴在顶部从左到右标记为0到320 ,在左侧分别从上到下标记为0到240。] (/_static/img/AiVision/VisionSensor-Barrel-Blank.png)

.exists#

.exists 返回一个布尔值,指示索引是否存在于元组中。

  • True — 该索引已存在。

  • False —索引不存在。

# Check if at least two objects are detected
while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)
    ai_objects = robot.vision.get_data(ALL_CARGO)

    if ai_objects[0].exists:
        if ai_objects[1].exists:
            robot.screen.print("At least 2")
        else:
            robot.screen.print("Less than 2")
    wait(0.1, SECONDS)

.width#

.width 返回检测到的对象的宽度,以像素为单位 ,该宽度是1到320之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

带有橙色条纹的蓝色桶位于框架中央,周围环绕着黑色边界框。两条垂直的红色虚线从框架顶部延伸至边界框的左右边缘。两条线之间的双向黑色箭头表示宽度测量值。

# Move towards a Blue Barrel until its width is
# larger than 100 pixels
while True:
    barrel = robot.vision.get_data(BLUE_BARREL)

    if barrel[0].exists:
        if barrel[0].width < 100:
            robot.move_at(0)
    else:
        robot.stop_all_movement()

    wait(50, MSEC)

.height#

.height 返回检测到的对象的高度,以像素为单位,该值是介于1和240之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

! [一个带有橙色条纹的蓝色桶在框架中居中,周围环绕着一个黑色边界框。两条水平红色虚线从框架的左侧延伸到边界框的顶部和底部边缘。这些线条之间的双向黑色箭头表示高度测量。] (/_static/img/AiVision/VisionSensor-Barrel-Height.png)

# Move towards a Blue Barrel until its height is
# larger than 100 pixels
while True:
    barrel = robot.vision.get_data(BLUE_BARREL)

    if barrel[0].exists:
        if barrel[0].height < 100:
            robot.move_at(0)
    else:
        robot.stop_all_movement()

    wait(50, MSEC)

.centerX#

.centerX 返回检测对象中心的x坐标,以像素为单位 ,该坐标是0到320之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

带有橙色条纹的蓝色桶位于框架中央,周围环绕着黑色边界框。一条垂直的红色虚线从框架顶部延伸至边界框的中心,指示中心的 X 坐标。

# Turn slowly until a Blue Barrel is centered in
# front of the robot
robot.set_turn_velocity(30)
robot.turn(RIGHT)

while True:
    barrel = robot.vision.get_data(BLUE_BARREL)

    if barrel[0].exists:
        if 140 < barrel[0].centerX < 180:
            robot.stop_all_movement()

    wait(10,MSEC)

.centerY#

.centerY 返回检测对象中心的y坐标,以像素为单位,该坐标是0到240之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

带有橙色条纹的蓝色桶位于框架中央,周围环绕着黑色边界框。一条水平红色虚线从框架左侧延伸至边界框中心,表示中心的 Y 坐标。

# Move towards a Blue Barrel until its
# center y-coordinate is more than 140 pixels
while True:
    barrel = robot.vision.get_data(BLUE_BARREL)

    if barrel[0].exists:
        if barrel[0].centerY < 140:
            robot.move_at(0)
    else:
        robot.stop_all_movement()

    wait(50, MSEC)

.bearing#

.bearing 返回一个小数点[(float)] (Logic/Variables.md#float) ,表示物体距离AI视觉传感器视图中心左侧或右侧的距离,以度为单位。值为0表示居中,正值表示对象位于右侧,负值表示对象位于左侧。

俯视图显示了一个 VEX AIM 编码机器人,它位于一个圆形底座的中心,底座上有一条垂直参考线和一条指向左侧运动球的红线,标记为 -30 度。 俯视图显示了一个 VEX AIM 编码机器人,它位于一个圆形底座的中心,底座上有一条垂直参考线和一条向右侧运动球倾斜的红线,标有 30 度。
# Turn to keep the Blue Barrel directly in front
robot.set_turn_velocity(40)
while True:
    vision_data = robot.vision.get_data(BLUE_BARREL)

    if vision_data[0].exists:

        if vision_data[0].bearing > 5:
            robot.turn(RIGHT)
        elif vision_data[0].bearing < -5:
            robot.turn(LEFT)
        else:
            robot.stop_all_movement()

    else:
        robot.stop_all_movement()

    wait(0.1, SECONDS)

.rotation#

.rotation 返回AI视觉传感器视平面上对象的方向,以0到359度为单位。当颜色以水平线排列(例如,红-蓝)时,颜色代码为0°。如果颜色旋转,角度会发生变化(例如,排列蓝红色返回180° )。

对于下面的示例,颜色代码已配置为左侧为红色,右侧为蓝色。

在此图像中,将蓝色放在红色上方相当于将原始颜色代码向右旋转 270 度。

相机界面显示一个垂直堆叠的物体,上半部分为蓝色,下半部分为红色,位于画面中央。物体下方的标签为“Red_Blue A:270° CX:185 CY:81 W:93 H:150”,指示物体的名称、旋转角度、中心 X 和 Y 坐标、宽度和高度。网格线和数字轴标记图像尺寸,X 轴范围为 0 到 320,Y 轴范围为 0 到 240。

# Slide left or right depending on how a Color Code (BlueRed)
# is rotated on the vertical plane
while True:
    # Original Color Code is Red to the left, Blue to the right
    code = robot.vision.get_data(BlueRed)

    if code[0].exists:
        # Check if Color Code is now Red on top of Blue
        if 50 < code[0].rotation < 100 :
            robot.move_at(90)

        # Check if Color Code is now Blue on top of Red
        elif 270 < code[0].rotation < 330 :
            robot.move_at(270)

        else:
            robot.stop_all_movement()
    else:
        robot.stop_all_movement()

    wait(50, MSEC)

.originX#

.originX 返回检测对象边界框左上角的x坐标,以像素为单位 ,该坐标是0到320之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

带有橙色条纹的蓝色桶位于框架中央,周围环绕着黑色边界框。一条垂直的红色虚线从框架顶部延伸到边界框的左边缘,表示边界框原点的 X 坐标。

# Display if an Orange Barrel is to the
# left or the right
while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1,1)

    orange_barrel = robot.vision.get_data(ORANGE_BARREL)

    if orange_barrel[0].exists:
        if orange_barrel[0].originX < 160:
            robot.screen.print("To the left!")
        else:
            robot.screen.print("To the right!")

    wait(50, MSEC)

.originY#

.originY 返回检测对象边界框左上角的y坐标,以像素为单位 ,该坐标是0到240之间的整数。

**注:**像素值是相对于传感器坐标系而言的。请参阅引言中的图表以获取参考。

带有橙色条纹的蓝色桶位于框架中央,周围环绕着黑色边界框。一条水平红色虚线从框架左侧延伸至边界框顶部边缘,表示边界框原点的 Y 坐标。

# Display if an Orange Barrel is close or far
# from the robot
while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)

    orange_barrel = robot.vision.get_data(ORANGE_BARREL)

    if orange_barrel[0].exists:
        if orange_barrel[0].originY < 80:
            robot.screen.print("Far")
        else:
            robot.screen.print("Close")

    wait(50, MSEC)

.id#

.id 返回检测到的 AI 分类或 AprilTag ID 作为整数。

对于AprilTag ID , .id 属性表示检测到的AprilTag ID编号,范围为0到37。对于AI分类, .id 属性对应于[AI分类] (#ai-classifications)部分中的预定义ID。

# Move forward when AprilTag ID 1 is detected
while True:
    apriltags = robot.vision.get_data(ALL_TAGS)

    if apriltags[0].exists:
        if apriltags[0].id == 1:
            robot.move_at(0)
    else:
        robot.stop_all_movement()

    wait(50, MSEC)

.score#

.score 将检测到的AI分类的置信度分数返回为1到100之间的整数。

较低的得分表示传感器对检测到的物体把握较小,而较高的得分表示传感器有较高的把握。

# Look confident if an Orange Barrel is detected
while True:
    barrel = robot.vision.get_data(ORANGE_BARREL)

    if barrel[0].exists:
        if barrel[0].score > 95:
            robot.screen.show_emoji(CONFIDENT)
        else:
            robot.screen.hide_emoji()

    wait(50, MSEC)

.type#

.type 返回指示检测到的对象类型的整数。您可以使用类型编号或相应的命名常量来比较此值:

对象类型

包含的对象

AiVision.AI_OBJECT

— 运动球
— 蓝色桶
— 橙色桶

AiVision.TAG_OBJECT

— AprilTag IDs

AiVision.COLOR_OBJECT

— 颜色特征

AiVision.CODE_OBJECT

— 颜色代码

# Display if an AprilTag ID or AI Classification
# is detected
while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)
    vision_data = robot.vision.get_data(ALL_VISION)
    if vision_data[0].exists:
        if vision_data[0].type == AiVision.AI_OBJECT:
            robot.screen.print("AI Object!")
        elif vision_data[0].type == AiVision.TAG_OBJECT:
            robot.screen.print("AprilTag ID!")
    wait(0.1, SECONDS)

# Display a list of all detected objects
while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)
    vision_data = robot.vision.get_data(ALL_VISION)

    if vision_data[0].exists:
        for obj in vision_data:
            if obj.type == AiVision.AI_OBJECT:
                robot.screen.print("- AI Object")
            elif obj.type == AiVision.TAG_OBJECT:
                robot.screen.print("- AprilTag ID")
            robot.screen.next_row()

    wait(0.1, SECONDS)

构造函数#

Creating a Color Signature#

新的颜色特征使用 Colordesc 构造函数创建,然后通过 color_description 方法注册到 AI 视觉传感器。一个 Colordesc 对象定义了传感器最多 7 个可检测颜色特征中的 1 个,但必须通过 color_description 显式设置才能生效。

Colordesc Usage:
Colordesc(index, red, green, blue, hangle, hdsat)

参数

描述

index

1到7之间的整数,表示颜色特征索引。如果两个颜色签名使用相同的索引,则第二个将覆盖第一个。

red

表示颜色红色成分的 0 至 255 之间的整数。

green

表示颜色的绿色成分的 0 至 255 之间的整数。

blue

表示颜色蓝色成分的 0 至 255 之间的整数。

hangle

1 至 40 之间的浮点数,表示色调范围(以度为单位)。

hdsat

表示饱和度范围从 0.10 到 1.00 的浮点数。

color_description Usage:
robot.vision.color_description(object)

参数

描述

object

Colordesc 对象设置为可探测的颜色特征。

# Detect a red object
red_box = Colordesc(1, 207, 19, 25, 10.00, 0.20)
robot.vision.color_description(red_box)

while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)

    red_boxes = robot.vision.get_data(red_box)

    if red_boxes[0].exists:
        robot.screen.print("Red detected!")
    else:
        robot.screen.print("No red detected.")

    wait(0.2, SECONDS)

Creating a Color Code#

新的颜色编码使用 Codedesc 构造函数创建,然后通过 code_description 方法激活。颜色编码将 2 到 4 个现有的 Colordesc 对象组合成一个 AI 视觉传感器可以作为序列检测的单一标识符,但必须通过 code_description 显式设置才能生效。

Codedesc Usage:
Codedesc(index, c1, c2, c3, c4, c5)

参数

描述

index

颜色代码的索引,从1到8。注意:如果创建两个具有相同索引的 Codedesc 对象,则第二个对象将覆盖第一个对象。

c1

代码中的 Colordesc 第一个对象。

c2

代码中的 Colordesc 第二个对象。

c3

可选。第三个 Colordesc 对象。

c4

可选。第四个 Colordesc 对象。

code_description Usage:
robot.vision.code_description(object)

参数

描述

object

要注册为可检测颜色代码的 Codedesc 对象。

# Create Color Signatures
red_box = Colordesc(1, 207, 19, 25, 10.00, 0.20)
purple_box = Colordesc(2, 98, 18, 227, 10.00, 0.20)

robot.vision.color_description(red_box)
robot.vision.color_description(purple_box)

# Detect a red_purple Color Code
red_purple = Codedesc(1, red_box, purple_box)
robot.vision.code_description(red_purple)

while True:
    robot.screen.clear_screen()
    robot.screen.set_cursor(1, 1)

    code_objects = robot.vision.get_data(red_purple)

    if code_objects[0].exists:
        robot.screen.print("Code detected!")
    else:
        robot.screen.print("No code detected.")

    wait(0.2, SECONDS)