تتبع علامات 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)، والروبوتات، ومعايرة الكاميرا. يمكن طباعة هذه العلامة مباشرةً بطابعة عادية، ويمكن لبرنامج كشف AprilTag حساب الموضع ثلاثي الأبعاد الدقيق والاتجاه والمعرّف (id) بالنسبة للكاميرا. بالنسبة لـ OpenMV، هذا مفيد جدًا! يبدو الشكل كالتالي:

ببساطة، طالما ألصقت هذه العلامة على الهدف، يمكنك التعرف على الموضع ثلاثي الأبعاد والمعرّف الخاص بهذه العلامة على OpenMV.
أنواع AprilTag
تُسمى أنواع AprilTag "عائلات" (families)، وهناك الأنواع التالية:
TAG16H5 → من 0 إلى 29\ TAG25H7 → من 0 إلى 241\ TAG25H9 → من 0 إلى 34\ TAG36H10 → من 0 إلى 2319\ TAG36H11 → من 0 إلى 586\ ARTOOLKIT → من 0 إلى 511\ أي أن هناك 30 عائلة من TAG16H5، لكل منها معرّف خاص بها، من 0 إلى 29.
إذن ما هي الفروق بين العائلات المختلفة؟
على سبيل المثال، المساحة الفعالة لـ TAG16H5 هي 4 × 4 كتل، لذا يمكنها الرؤية من مسافة أبعد مقارنةً بـ TAG36H11 (لأن الأخيرة تحتوي على 6 × 6 كتل). ومع ذلك، معدل الخطأ في TAG16H5 أعلى بكثير من TAG36H11، لأن TAG36H11 تحتوي على معلومات تحقق أكثر، لذا إذا لم يكن هناك سبب آخر، يُنصح باستخدام TAG36H11.
صنع علامة AprilTag
الأمر بسيط جدًا. يمكنك تنزيلها من الإنترنت أو توليدها مباشرةً من OpenMV IDE. اختر العائلة من القائمة Tools - Machine Vision - AprilTag Generate. يُنصح باستخدام TAG36H11.

بعد ذلك، أدخل العدد الذي تحتاج إلى توليده، فمثلاً إذا كنت تحتاج 10، فسيتم توليد صور بمعرّفات من 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 csi, image, time, math
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QQVGA) # we run out of memory if the resolution is much bigger...
csi0.snapshot(frames=30)
csi0.auto_gain(False) # must turn this off to prevent image washout...
csi0.auto_whitebal(False) # must turn this off to prevent image washout...
clock = time.clock()
while(True):
clock.tick()
img = csi0.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)

كما تلاحظ، يمكنك التعرف على المعرّف 0، وزاوية الدوران، والموضع\

التموضع ثلاثي الأبعاد
الشيء الأكثر إثارةً في AprilTag هو وظيفة التموضع ثلاثي الأبعاد، التي يمكنها معرفة الموضع المكاني للعلامة، بإجمالي 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 csi, image, time, math
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QQVGA) # we run out of memory if the resolution is much bigger...
csi0.snapshot(frames=30)
csi0.auto_gain(False) # must turn this off to prevent image washout...
csi0.auto_whitebal(False) # must turn this off to prevent image washout...
clock = time.clock()
# ملاحظة! على عكس find_qrcodes، فإن find_apriltags لا تحتاج إلى تصحيح تشوه الصورة عبر البرمجيات لكي تعمل.
# ملاحظة، وحدة قياس الوضعية (pose) الناتجة هي الراديان، ويمكن تحويلها إلى درجات، لكن وحدة الموضع مرتبطة بالمقياس الذي تستخدمه، ويجب تحويلها بنسبة مكافئة
# 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 = csi0.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 هي كميات الموضع الثلاث في الفضاء، وRx وRy وRz هي كميات الدوران الثلاث.
قراءات إضافية:
- من تطبيق Singtown Lab: كيف يتم تحديد الموقع/قياس المسافة في التعرف على Apriltag؟ ما هي وحدة قياس الإخراج tx وty وtz؟ كيف يمكن الحصول على المسافة الفعلية؟ https://forum.singtown.com/topic/52