Finding AprilTags at a distance

Discussion related to "under the hood" OpenMV topics.
User avatar
Posts: 1935
Joined: Sun May 24, 2015 2:10 pm

Finding AprilTags at a distance

Postby kwagyeman » Tue Jun 05, 2018 2:28 am

By using image pre-filtering you can find apriltags at a distance:

Code: Select all

# Find Small Apriltags
# This script shows off how to use blob tracking as a pre-filter to
# finding Apriltags in the image using blob tracking to find the
# area of where the tag is first and then calling find_apriltags
# on that blob.

# Note, this script works well assuming most parts of the image do not
# pass the thresholding test... otherwise, you don't get a distance
# benefit.

import sensor, image, time, math, omv

# Set the thresholds to find a white object (i.e. tag border)
thresholds = (150, 255)

if omv.board_type() == "H7": sensor.set_framesize(sensor.VGA)
elif omv.board_type() == "M7": sensor.set_framesize(sensor.QVGA)
else: raise Exception("You need a more powerful OpenMV Cam to run this script")
sensor.skip_frames(time = 200) # increase this to let the auto methods run for longer
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()

# The apriltag code supports up to 6 tag families which can be processed at the same time.
# Returned tag objects will have their tag family and id within the tag family.
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

    img = sensor.snapshot()

    # First, we find blobs that may be candidates for tags.
    box_list = []

    # AprilTags may fail due to not having enough ram given the image sie being passed.
    tag_list = []

    for blob in img.find_blobs([thresholds], pixels_threshold=100, area_threshold=100, merge=True):
        # Next we look for a tag in an ROI that's bigger than the blob.
        w = min(max(int(blob.w() * 1.2), 20), 100) # Not too small, not too big.
        h = min(max(int(blob.h() * 1.2), 20), 100) # Not too small, not too big.
        x = min(max(int(blob.x() - (w * 0.1)), 0), img.width()-1)
        y = min(max(int(blob.y() - (h * 0.1)), 0), img.height()-1)

        box_list.append((x, y, w, h)) # We'll draw these later.

        # Since we constrict the roi size apriltags shouldn't run out of ram.
        # But, if it does we handle it...
            tag_list.extend(img.find_apriltags(roi=(x,y,w,h), families=tag_families))
        except (MemoryError, OSError): # Don't catch all exceptions otherwise you can't stop the script.

    for b in box_list:
    # Now print out the found tags
    for tag in tag_list:
        for c in tag.corners():
            img.draw_circle(c[0], c[1], 5)
        print("Tag:",,, tag.rotation(),
Note that there's a bug in the apriltag code related to the minimum roi. Please don't make the ROI too small. It causes crashes if you do.

Return to “Technical Discussion”

Who is online

Users browsing this forum: No registered users and 3 guests