学习目标:
在Canmv IDE环境下使用K210学习机器码识别功能,根据识别到的机器码,将机器码位置标记并框出来,打印机器码类别、序列号以及角度等相关数据
机器码:AprilTag
- AprilTag是一个由密歇根大学APRIL Robotics Laboratory开发的视觉基准系统,广泛应用于增强现实(AR)、机器人导航、相机校正等领域。它通过识别特定的二维码标志来确定相机相对于标志的位姿,即使在远距离、低分辨率、不均匀照明或图像扭曲等不利条件下也能实现精确定位
- AprilTag是一种视觉基准系统,专为机器人导航、增强现实和相机校准等应用设计。AprilTag支持多标签检测,可快速计算标签的三维位置和相机的相对姿态。它AprilTag的设计专注于编码简单的数字ID,而不是像二维码那样存储复杂的文本或数据信息,这使得AprilTag在有效载荷上更为精简。这种简化的编码方式有助于提高其在各种视觉干扰下的识别可靠性
- 与二维码相比,AprilTag具有更强的环境适应性和图像识别鲁棒性。它们能够在更远的距离和更不理想的光照条件下被成功检测,包括在图像扭曲或失真的情况下,AprilTag的开源性质和跨平台兼容性使其在研究和工业领域得到广泛应用
学习内容:
1、导入相关库,并初始化摄像头和LCD显示屏
# Find_apriltags - By: Jack - 周四 4月 18 2024
import sensor, image, time, math, lcd
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565) #设置为彩色显示
#sensor.set_framesize(sensor.QQVGA)#160x120
sensor.set_framesize(sensor.QQCIF) # 如果分辨率太高,内存可能会溢出,此处选择最小分辨率可以换取较高的FPS
sensor.set_windowing((64, 64)) #边长必须为8的倍数
sensor.skip_frames(time = 1000) # 在更改设置后,跳过一些帧,等待感光元件变稳定
sensor.set_auto_gain(False) # 关闭图像增益,以防止图像冲洗
sensor.set_auto_whitebal(False) # 关闭图像白平衡,以防止图像冲洗
clock = time.clock()
2、设置要识别的机器码家族成员
# 注释可以禁用族、TAG36H11为默认族
tag_families = 0
tag_families |= image.TAG16H5
tag_families |= image.TAG25H7
tag_families |= image.TAG25H9
tag_families |= image.TAG36H10
tag_families |= image.TAG36H11
tag_families |= image.ARTOOLKIT
3、创建函数将家族名转化成字符串
def family_name(tag): #将家族名识别转换为字符串
if(tag.family() == image.TAG16H5):
return "TAG16H5"
if(tag.family() == image.TAG25H7):
return "TAG25H7"
if(tag.family() == image.TAG25H9):
return "TAG25H9"
if(tag.family() == image.TAG36H10):
return "TAG36H10"
if(tag.family() == image.TAG36H11):
return "TAG36H11"
if(tag.family() == image.ARTOOLKIT):
return "ARTOOLKIT"
4、使用while循环识别摄像头画面中的颜色,调用find_apriltags函数查找图像中的机器码,找到之后框出来并且打印相关信息
while(True):
clock.tick()
img = sensor.snapshot()
#find_apriltags()显示的图像<64,000像素点
#设置图像的大小
#sensor.QQVGA: 160x120 sensor.QQVGA2: 128x160 (用于 lcd 扩展板)
#sensor.HQVGA: 240x160 sensor.QVGA: 320x240
#sensor.VGA: 640x480 (只用于OpenMV Cam M7 的灰度图处理图像,或者彩图采集图像)
#sensor.QQCIF: 88x72 sensor.QCIF: 176x144
#sensor.CIF: 352x288
for tag in img.find_apriltags(families=tag_families): # 遍历识别机器码家族
img.draw_rectangle(tag.rect(), color = (255, 0, 0)) # 在tag.rect()获取到的ROI区域(坐标)上绘制一个矩形
img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0)) # ROI中心画十字
print_args = (family_name(tag), tag.id(), (180 * tag.rotation()) / math.pi)
print("Tag Family %s, Tag ID %d, rotation %f (degrees)" % print_args) # 打印出获取到的机器码接码内容
lcd.display(img)
print(clock.fps()) # 打印帧率
如何获取机器码:
在Canmv IID软件中:工具栏--->机器视觉--->AprilTag生成器--->下载各家族的标签码 |
实验分析:
实时检测结果 |
实时识别出AprilTag机器码,获取机器码的的家族、标签数字信息、检测时机器码与摄像头的角度(摄像头顺时针方向为正)、FPS等数据
实验过程与总结:
实验过程:
- 实验首先导入了必要的库以便于二维码识别。接着并配置了LCD显示屏以实时展示摄像头捕获的图像。设置要识别的机器码家族成员,接着创建函数将家族名转化成字符串,最后通过编写一个循环不断从摄像头读取图像数据,然后使用find_apriltags函数检测图像中的AprilTag机器码。
- 一旦检测到二维码,使用draw_rectangle函数在LCD显示屏上绘制矩形框、使用draw_cross函数在ROI中心绘制十字以标记二维码的位置,并通过终端打印出解码后的二维码机器码信息
总结:
-
在实验中做了对比实验(参考前面案例),灰度/彩色图像显示、显示窗口大小来提升FPS,实验结论如下:
1 、find_apriltags()函数要求显示的图像<64,000像素点、像素边长为8的倍数
2、控制变量使用HQVGA、QQVGA、QQCIF三种分辨率将机器码铺满窗口分别获得的FPS平均值为4、 7、12,我们可以确定在一定范围内减少分辨率可以增大检测速度
3、转换为灰度图像可以略微提升少量FPS,但是会丢失彩色信息(例如彩色框、中心十字标记等)
完整代码展示:
# Find_apriltags - By: Jack - 周四 4月 18 2024
import sensor, image, time, math, lcd
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565) #设置为彩色显示
#sensor.set_framesize(sensor.QQVGA)#160x120
sensor.set_framesize(sensor.QQCIF) # 如果分辨率太高,内存可能会溢出,此处选择最小分辨率可以换取较高的FPS
sensor.set_windowing((64, 64)) #边长必须为8的倍数
sensor.skip_frames(time = 1000) # 在更改设置后,跳过一些帧,等待感光元件变稳定
sensor.set_auto_gain(False) # 关闭图像增益,以防止图像冲洗
sensor.set_auto_whitebal(False) # 关闭图像白平衡,以防止图像冲洗
clock = time.clock()
# 注释可以禁用族、TAG36H11为默认族
tag_families = 0
tag_families |= image.TAG16H5
tag_families |= image.TAG25H7
tag_families |= image.TAG25H9
tag_families |= image.TAG36H10
tag_families |= image.TAG36H11
tag_families |= image.ARTOOLKIT
def family_name(tag): #将家族名识别转换为字符串
if(tag.family() == image.TAG16H5):
return "TAG16H5"
if(tag.family() == image.TAG25H7):
return "TAG25H7"
if(tag.family() == image.TAG25H9):
return "TAG25H9"
if(tag.family() == image.TAG36H10):
return "TAG36H10"
if(tag.family() == image.TAG36H11):
return "TAG36H11"
if(tag.family() == image.ARTOOLKIT):
return "ARTOOLKIT"
while(True):
clock.tick()
img = sensor.snapshot()
#find_apriltags()显示的图像<64,000像素点
#设置图像的大小
#sensor.QQVGA: 160x120 sensor.QQVGA2: 128x160 (用于 lcd 扩展板)
#sensor.HQVGA: 240x160 sensor.QVGA: 320x240
#sensor.VGA: 640x480 (只用于OpenMV Cam M7 的灰度图处理图像,或者彩图采集图像)
#sensor.QQCIF: 88x72 sensor.QCIF: 176x144
#sensor.CIF: 352x288
for tag in img.find_apriltags(families=tag_families): # 遍历识别机器码家族
img.draw_rectangle(tag.rect(), color = (255, 0, 0)) # 在tag.rect()获取到的ROI区域(坐标)上绘制一个矩形
img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0)) # ROI中心画十字
print_args = (family_name(tag), tag.id(), (180 * tag.rotation()) / math.pi)
print("Tag Family %s, Tag ID %d, rotation %f (degrees)" % print_args) # 打印出获取到的机器码接码内容
lcd.display(img)
print(clock.fps()) # 打印帧率