《K230 从熟悉到...》识别机器码(AprilTag)

时间:2025-04-05 09:07:49
import time, os, sys from media.sensor import * from media.display import * from media.media import * import time, math, os, gc, sys picture_width = 800 picture_height = 480 sensor_id = 2 sensor = None # 显示模式选择:可以是 "VIRT"、"LCD" 或 "HDMI" DISPLAY_MODE = "LCD" # 根据模式设置显示宽高 if DISPLAY_MODE == "VIRT": # 虚拟显示器模式 DISPLAY_WIDTH = ALIGN_UP(1920, 16) DISPLAY_HEIGHT = 1080 elif DISPLAY_MODE == "LCD": # 3.1寸屏幕模式 DISPLAY_WIDTH = 800 DISPLAY_HEIGHT = 480 elif DISPLAY_MODE == "HDMI": # HDMI扩展板模式 DISPLAY_WIDTH = 1920 DISPLAY_HEIGHT = 1080 else: raise ValueError("未知的 DISPLAY_MODE,请选择 'VIRT', 'LCD' 或 'HDMI'") # 注意!与find_qrcodes不同,find_apriltags方法无需对图像进行镜像校正。 # apriltag代码支持最多6个标签族,可以同时处理多个标签。 # 返回的标签对象将包含标签族和标签族内的标签ID。 tag_families = 0 tag_families |= image.TAG16H5 # comment out to disable this family #tag_families |= image.TAG25H7 # comment out to disable this family #tag_families |= image.TAG25H9 # comment out to disable this family #tag_families |= image.TAG36H10 # comment out to disable this family #tag_families |= image.TAG36H11 # comment out to disable this family (default family) #tag_families |= image.ARTOOLKIT # comment out to disable this family # 标签族之间有什么区别?例如,TAG16H5标签族是一个4x4的正方形标签, # 这意味着它可以在较远的距离检测到,而TAG36H11标签族是6x6的正方形标签。 # 然而,较低的H值(H5相比H11)意味着4x4标签的误识别率要比6x6标签高得多。 # 所以,除非有特定需要,否则使用默认的TAG36H11标签族。 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" try: # 构造一个具有默认配置的摄像头对象 sensor = Sensor(id=sensor_id) # 重置摄像头sensor sensor.reset() # 无需进行镜像翻转 # 设置水平镜像 # sensor.set_hmirror(False) # 设置垂直翻转 # sensor.set_vflip(False) # 设置通道0的输出尺寸 sensor.set_framesize(width=picture_width, height=picture_height, chn=CAM_CHN_ID_0) # 设置通道0的输出像素格式为GRAYSCALE(灰度) sensor.set_pixformat(Sensor.GRAYSCALE, chn=CAM_CHN_ID_0) #sensor.set_pixformat(Sensor.RGB565, chn=CAM_CHN_ID_0) # 根据模式初始化显示器 if DISPLAY_MODE == "VIRT": Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, fps=60) elif DISPLAY_MODE == "LCD": Display.init(Display.ST7701, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True) elif DISPLAY_MODE == "HDMI": Display.init(Display.LT9611, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True) # 初始化媒体管理器 MediaManager.init() # 启动传感器 sensor.run() # 创建一个FPS计时器,用于实时计算每秒帧数 fps = time.clock() while True: os.exitpoint() # 更新FPS计时 fps.tick() # 捕获通道0的图像 img = sensor.snapshot(chn=CAM_CHN_ID_0) # 查找并处理AprilTag标签 for tag in img.find_apriltags(families=tag_families): # 在图像中绘制标签的矩形框 img.draw_rectangle([v for v in tag.rect()], color=(255, 0, 0)) # 在标签中心绘制十字 img.draw_cross(tag.cx(), tag.cy(), color=(0, 255, 0)) # 显示标签ID img.draw_string_advanced(tag.cx(), tag.cy(), 32, str(tag.id())) print_args = (family_name(tag), tag.id(), (180 * tag.rotation()) / math.pi) print("Tag Family %s, Tag ID %d, rotation %f (degrees)" % print_args) if tag.id() == 3: print("啦~啦~la la") # 显示捕获的图像,中心对齐,居中显示 Display.show_image(img, x=int((DISPLAY_WIDTH - picture_width) / 2), y=int((DISPLAY_HEIGHT - picture_height) / 2)) gc.collect() print(fps.fps()) except KeyboardInterrupt as e: print("用户停止: ", e) except BaseException as e: print(f"异常: {e}") finally: # 停止传感器运行 if isinstance(sensor, Sensor): sensor.stop() # 反初始化显示模块 Display.deinit() os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) time.sleep_ms(100) # 释放媒体缓冲区 MediaManager.deinit()