《K230 從熟悉到...》識別機器碼(aprirltag)
- tag id
《廬山派 K230 從熟悉到...》 識別機器碼(AprilTag)
AprilTag是一種基于二維碼的視覺標記系統,最早是由麻省理工學院(MIT)在2008年開發的。AprilTag的設計目標是為機器人視覺系統提供快速、可靠的視覺標記,特別適用于定位和跟蹤應用。相比二維碼和一維碼,AprilTag有著更高的精度和更強的魯棒性。
AprilTag通過在正方形的圖案中使用獨特的黑白圖案來進行信息編碼。與二維碼不同,AprilTag的特點是它通過不同的標記ID來標識不同的標簽,本身還包括誤差修正能力,能夠在一定程度上適應環境噪聲和圖像變形。一個AprilTag一般由一個黑色的邊框和一組內部的二進制編碼區域組成。每個AprilTag的編碼方式是不同的,也就是說每個標記都有唯一的ID。
tag id
import time, os, sysfrom media.sensor import *
from media.display import *
from media.media import *
import time, math, os, gc, syspicture_width = 800
picture_height = 480sensor_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 = 800DISPLAY_HEIGHT = 480
elif DISPLAY_MODE == "HDMI":# HDMI擴展板模式DISPLAY_WIDTH = 1920DISPLAY_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)# 重置攝像頭sensorsensor.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))# 顯示標簽IDimg.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()