AprilTag标记跟踪

视频教程11 - AprilTag标记追踪:https://singtown.com/learn/49590/
视频教程21 - 追其他物体的小车:https://singtown.com/learn/50041/

AprilTag简介

资料:https://april.eecs.umich.edu/software/apriltag.html

AprilTag是一个视觉基准系统,可用于各种任务,包括AR,机器人和相机校准。这个tag可以直接用打印机打印出来,而AprilTag检测程序可以计算相对于相机的精确3D位置,方向和id。对于OpenMV来说,这个特别有用! 它大概长这个样子:

简单来说,只要把这个tag贴到目标上,就可以在OpenMV上识别出这个标签的3D位置,id。

AprilTag的种类

AprilTag的种类叫家族(family),有下面的几种:

TAG16H5 → 0 to 29
TAG25H7 → 0 to 241
TAG25H9 → 0 to 34
TAG36H10 → 0 to 2319
TAG36H11 → 0 to 586
ARTOOLKIT → 0 to 511
也就是说TAG16H5的家族(family)有30个,每一个都有对应的id,从0~29。

那么不同的家族,有什么区别呢?

比如说TAG16H5的有效区域是4 x 4的方块,那么它比TAG36H11看的更远(因为他有6 x 6个方块)。但是TAG16H5的错误率比TAG36H11高很多,因为TAG36H11的校验信息多,所以,如果没有别的理由,推荐用TAG36H11

制作AprilTag

很简单,你可以在网络上下载,也可以直接从OpenMV的IDE里生成。 在工具——Machine Vision——AprilTag Generate中选择family,推荐使用TAG36H11。

然后,填写需要生成的个数,比如需要10个,就生成id为0~9的图片。

然后选择一下图片存放的文件夹,就可以了。

然后,在该文件夹会生成图片。

最后,把这个图片用打印机打印出来(当然,也可以直接用屏幕,但是可能会反光)。

程序

# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(30)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(): # defaults to TAG36H11 without "families".
        img.draw_rectangle(tag.rect(), color = (255, 0, 0))
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        degress = 180 * tag.rotation() / math.pi
        print(tag.id(),degress)

可以看到,可以识别出id为0,旋转的角度,位置

3D定位

AprilTag最神奇的是3D定位的功能,它可以得知Tag的空间位置,一共有6个自由度,三个位置,三个角度。

# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(30)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
clock = time.clock()

# 注意!与find_qrcodes不同,find_apriltags 不需要软件矫正畸变就可以工作。

# 注意,输出的姿态的单位是弧度,可以转换成角度,但是位置的单位是和你的大小有关,需要等比例换算

# f_x 是x的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/3.984*656,这个值是用毫米为单位的焦距除以x方向的感光元件的长度,乘以x方向的感光元件的像素(OV7725)
# f_y 是y的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/2.952*488,这个值是用毫米为单位的焦距除以y方向的感光元件的长度,乘以y方向的感光元件的像素(OV7725)

# c_x 是图像的x中心位置
# c_y 是图像的y中心位置

f_x = (2.8 / 3.984) * 160 # 默认值
f_y = (2.8 / 2.952) * 120 # 默认值
c_x = 160 * 0.5 # 默认值(image.w * 0.5)
c_y = 120 * 0.5 # 默认值(image.h * 0.5)

def degrees(radians):
    return (180 * radians) / math.pi

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y): # 默认为TAG36H11
        img.draw_rectangle(tag.rect(), color = (255, 0, 0))
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        print_args = (tag.x_translation(), tag.y_translation(), tag.z_translation(), \
            degrees(tag.x_rotation()), degrees(tag.y_rotation()), degrees(tag.z_rotation()))
        # 位置的单位是未知的,旋转的单位是角度
        print("Tx: %f, Ty %f, Tz %f, Rx %f, Ry %f, Rz %f" % print_args)
    print(clock.fps())

在串口输出为6个变量,Tx, Ty, Tz为空间的3个位置量,Rx,Ry,Rz为三个旋转量。

扩展阅读:

  • 来自星瞳实验室APP: Apriltag识别中,怎么定位/测距?输出的tx ty tz的单位是什么?怎么就得到实际的距离了?https://forum.singtown.com/topic/52

results matching ""

    No results matching ""