0
点赞
收藏
分享

微信扫一扫

《响应式 Web 设计:纯 HTML 和 CSS 的实现技巧》


文章目录


引言

  本篇博客介绍OpenMV的 AprilTag 视觉定位。

一、AprilTag简介

  AprilTag是一种非常有用的视觉基准标记系统。可以利用 AprilTag 来获取标签相对摄像机的位置、距离以及坐标。

AprilTag 有非常多种类,叫做 家族(family)。常见的有:

  • TAG16H5 家族,共有 30 30 30 个 AprilTag 标签,编号 ID 分别是从 0 0 0 29 29 29
  • TAG36H11 家族,这个家族的 ID 数量非常多,从 0 0 0 586 586 586

在这里插入图片描述

  不同的 AprilTag 家族,数量和信息不一样。比如TAG16H5 共有 30 个 ID,每个标签图有 4 × 4 4 \times 4 4×4 的方块。对于 TAG36H11 家族来说,方块数量比较多,每个标签图有 6 × 6 6 \times 6 6×6 个方块。

  所以 TAG16H5家族的 AprilTag 标签比TAG36H11家族看的距离更远。因为 TAG36H11的方块数量更多,信息更准确,出错率更少。原因也是因为它的方块的数量多,有 6 × 6 6 \times 6 6×6 个方块,检验信息更多,所以出错率更少,因此一般情况下推荐使用TAG36H11

二、OpenMV与AprilTag的结合

1、AprilTag标签生成

  在OpenMV中,可直接在 IDE 生成 AprilTag 标签,或者也可以直接在网络上下载,生成后可打印出来,贴到物体上进行识别。
在这里插入图片描述

  比如可以打印TAG36H11的标签,这是直接OpenMV生成的,可以贴到的物体上来进行识别。

2、AprilTag标签获取

  将标签打印出来贴到物体上后,在 OpenMV 中就可以得到 AprilTag 标签相对于 OpenMV 相机的坐标和位置,坐标系以 OpenMV 为原点,共返回三个坐标量以及三个旋转量,分别是 AprilTag 标签相对 OpenMV 的坐标 ( T x , T y , T z ) (T_x,T_y,T_z) (Tx,Ty,Tz) 以及 x , y , z x,y,z x,y,z 三个方向的旋转量 ( R x , R y , R z ) (R_x,R_y,R_z) (Rx,Ry,Rz)

  通过三个坐标量以及三个旋转量可确定 AprilTag 相对于 OpenMV 的位置,并且AprilTag 会返回它的 ID,通过 ID 可以确定到底是哪个物体在视野中被识别到。

  AprilTag 的应用非常广泛,比如用在 AR 机器人或相机校准上。

3、AprilTag代码解读

  下面解读 AprilTag 的代码,先看一下这段比较简单的代码:

AprilTags Example1

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # 如果分辨率大得多,会耗尽内存
sensor.skip_frames(30)
sensor.set_auto_gain(False)  # 必须关闭此功能以防止图像流失
sensor.set_auto_whitebal(False)  # 设置白平衡关闭
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(): # 默认为TAG36H11。
        img.draw_rectangle(tag.rect(), color = (255, 0, 0)) # 在识别到的AprilTag 上面画框和十字
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        degress = 180 * tag.rotation() / math.pi # 求 AprilTag 旋转的角度
        print(tag.id(),degress) # 打印 AprilTag 的 ID 以及角度

  看一下 find_apriltags()函数返回的数值

  在 image 库中查找 find_apriltags(),链接如下:

  OpenMV image-机器视觉库

在这里插入图片描述
  find_apriltags()函数,里有几个参数:class image.apriltag

  运行代码效果如下:
在这里插入图片描述

  识别到 ID 为 8 8 8 的 AprilTag 标签,旋转量为 345 ° 345° 345°

三、深入理解AprilTag定位

  AprilTag 最常用的功能是 3D 定位,可得到 AprilTag 的空间位置。

  下面解读稍复杂的代码:

  AprilTags Example2

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) 
sensor.skip_frames(30)
sensor.set_auto_gain(False)  
sensor.set_auto_whitebal(False) 
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 # fx 是以x的像素为单位的焦距,一般不需要更改,与OpenMV感光元件的尺寸有关, 2.8 是标配镜头的焦距, 2.8 毫米
f_y = (2.8 / 2.952) * 120 # 3.984 和 2.952 是感光元件OV7725的长宽
c_x = 160 * 0.5 # (image.w * 0.5)  160 和 120 是视野中像素的大小,即QQVGA的分辨率
c_y = 120 * 0.5 # 默认值(image.h * 0.5) #  CXCY 是图像的 XY 中心的位置
# 注意不是 ROI 的中心位置,是整幅图像的中心位置,也就是分辨率的一半

# 定义函数,把弧度转换为角度
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)) # 把识别到的 AprilTag 圈出来
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        
        # 识别到的 AprilTag 的 6 个量
        print_args = (tag.x_translation(), tag.y_translation(), tag.z_translation(), \ # x,y,z 方向的平移变换量
            degrees(tag.x_rotation()), degrees(tag.y_rotation()), degrees(tag.z_rotation())) # x,y,z 方向上的角度
        # 旋转的单位是角度
        print("Tx: %f, Ty %f, Tz %f, Rx %f, Ry %f, Rz %f" % print_args)
    print(clock.fps())

  运行程序,效果如下:

在这里插入图片描述
  串口输出为6个变量, T x , T y , T z T_x, T_y, T_z Tx,Ty,Tz 为空间的 3 3 3 个位置量, R x , R y , R z R_x,R_y,R_z Rx,Ry,Rz 3 3 3 个旋转量。
在这里插入图片描述
首先测试位置量的变化

  • 将标签沿水平方向移动, T x T_x Tx 数值改变
  • 将标签沿竖直方向移动, T y T_y Ty 数值改变
  • 将标签沿靠近摄像头方向移动, T z T_z Tz 数值减小

同样的来看一下其余三个旋转量的变化

  • 将标签俯仰调节, R x R_x Rx 数值改变
  • 将标签水平旋转, R y R_y Ry 数值改变

所以, R x Rx Rx 表征的是 AprilTag 标签沿 x x x 轴方向的旋转角度

  这 6 6 6 个量是表征 AprilTag 在以 OpenMV 为原点时,AprilTag标签相对于 OpenMV摄像头 的 x , y , z x,y,z x,y,z 的距离以及每个轴上旋转的角度。

四、AprilTag坐标与实际距离换算

  通过前面的测量很容易可以得到 T x , T y , T z T_x, T_y, T_z Tx,Ty,Tz 和实际空间的坐标系一致,只是 T x , T y , T z T_x, T_y, T_z Tx,Ty,Tz 和实际坐标系的单位不同。

比如:

  • 20 c m 20cm 20cm 处,得到 T z = − 6.85 T_z =-6.85 Tz=6.85
  • 移动到 30 c m 30cm 30cm 处时,可得到 T z = − 9.89 T_z=-9.89 Tz=9.89

1、比例系数计算

  在 z z z 方向上可得到比例系数 k k k,表征实际距离与 T z T_z Tz 虚拟距离的关系,实际距离等于比例系数 k k k 乘以 T z T_z Tz,即正比例关系:
k z = 实际距离 T z k_z=\frac{实际距离}{T_z} kz=Tz实际距离  在 20 c m 20cm 20cm 处得到 T z = 6.85 T_z=6.85 Tz=6.85,则
k z = 200 m m 6.85 = 29.197 k_z=\frac{200mm}{6.85}=29.197 kz=6.85200mm=29.197  根据得到的 k z k_z kz,容易测得在 z z z 方向的实际距离。

2、实际距离计算

  比如在 T z T_z Tz 的绝对值为 9.89 9.89 9.89 时,可求得实际距离:
实际距离 = k z × T z = 9.89 × 200 6.85 = 288.759 \text{实际距离}=k_z\times T_z=9.89\times \frac{200}{6.85}=288.759 实际距离=kz×Tz=9.89×6.85200=288.759  得到的 288 m m 288mm 288mm 与实际 30 c m 30cm 30cm 距离基本一致。

  同理,可以求得其他 x , y x,y x,y 方向上的 k x , k y k_x,k_y kx,ky,这样就可得到实际空间坐标中 AprilTag 相对 OpenMV 的实际坐标。

  多数情况下不需要求得实际坐标值,在程序运算中,不必知道实际坐标,实际距离可直接通过 T x , T y , T z T_x, T_y, T_z Tx,Ty,Tz 来控制运动。

五、AprilTag与OpenMV摄像头的距离计算

1、距离计算方法

  上面计算的是 AprilTag 在实际空间中的 x , y , z x,y ,z x,y,z 坐标,现在要计算 AprilTag 距离OpenMV 摄像头的实际距离,这个距离粗略等于 T z T_z Tz 方向的距离,但稍微有点误差。根据勾股定理,实际距离等于 T x 2 + T y 2 + T z 2 \sqrt{T_{x}^{2}+T_{y}^{2}+T_{z}^{2}} Tx2+Ty2+Tz2 ,再乘以比例系数 k k k。利用勾股定理算出来的是更为准确的 AprilTag 与 OpenMV 之间的实际距离,可以再计算求一下 k k k
k = 实际距离 T x 2 + T y 2 + T z 2 k=\frac{\text{实际距离}}{\sqrt{T_{x}^{2}+T_{y}^{2}+T_{z}^{2}}} k=Tx2+Ty2+Tz2 实际距离可求得实际距离的比例系数 k k k k z k_z kz 基本一致,所以实际距离为
实际距离 = k × T x 2 + T y 2 + T z 2 \text{实际距离}=k\times \sqrt{T_{x}^{2}+T_{y}^{2}+T_{z}^{2}} 实际距离=k×Tx2+Ty2+Tz2

2、简化计算

  可直接粗略等于 z z z 方向的实际距离 k z × T z k_z\times T_z kz×Tz。得到 T x , T y , T z T_x, T_y, T_z Tx,Ty,Tz 以及 R x , R y , R z R_x,R_y,R_z Rx,Ry,Rz 后,就可以很轻松的知道 AprilTag 相对于 OpenMV 的位置坐标以及距离。

  这就是 Apriltag 最重要的应用。

六、总结

  本篇博客深入探讨了OpenMV与AprilTag视觉定位技术。AprilTag是一种高精度的视觉基准标记系统,通过其在摄像机视野中的位置、距离和坐标,能够实现精确的3D定位。AprilTag有多种家族,如TAG16H5和TAG36H11,它们在识别距离、精度等方面有所不同。OpenMV作为一个微控制器,可以直接在IDE中生成AprilTag标签,并将其应用于各种视觉定位任务。

  通过简单的示例代码,我们了解了如何使用OpenMV的image库来识别AprilTag,并获取其相对于摄像机的坐标和旋转角度。这些信息可以用于确定AprilTag在实际空间中的位置,并通过计算得到实际距离和方向。

  在深入的代码示例中,我们看到了如何通过设置焦距和图像中心点,来更准确地计算AprilTag的位置和旋转量。这些信息可以用于精确控制机器人的运动,或者在增强现实应用中定位虚拟物体。

  总的来说,OpenMV与AprilTag的结合为机器视觉和机器人定位提供了一个强大的工具。通过这些技术,可以实现精确的3D定位和控制,为各种应用提供支持。

参考资料

  1、OpenMV中文参考手册

  2、星瞳科技OpenMV视频教程11-AprilTag标记追踪

  3、[星瞳科技]OpenMV图像处理的方法(六):AprilTag标记跟踪


举报

相关推荐

0 条评论