# AprilTag speed up with dynamic ROI

I have been using AprilTag tracking with the OpenMV in my work and thought I’d share a simple trick I have been using to increase the frame rate. The idea is that once you have found a tag in one frame, instead of running the algorithm on the whole of the next frame you search only a region of interest defined using the .rect attribute of the found tag:

``````# AprilTags with Dynamic ROI Example
# This script will track a single tag by searching a continuosly redefined (dynamic) ROI
# which gives and improved frame rate relative to searching the entirety of each frame.

import sensor, image, time

#constant factors defining size of Dynamic Region of Interest (ROI)
#a is the x (widthways) factor
a = 0.33
#b is the y (lengthways) factor
b = 0.33

#calculate ROI
def roiCalc(a, b, tag, img):

img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
trec = tag.rect()

#calculate ROI
ROI = trec - int(a * trec)
if ROI < 0:
ROI = 0
ROI = trec - int(b * trec)
if ROI < 0:
ROI = 0
ROI = trec + int(2 * a * trec)
if ROI + ROI > img.width():
ROI = img.width() - ROI
ROI = trec + int(2 * b * trec)
if ROI + ROI > img.height():
ROI = img.height() - ROI

#draw the ROI onto the current frame
img.draw_rectangle(ROI, ROI, ROI, ROI, color= (255, 0, 0))
return(ROI)

#initialise sensor
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)

#initialise ROI, tag found flag and frame counter
ROI = [None, None, None, None]
found = False
i = 0

clock = time.clock()

while(True):

clock.tick()

img = sensor.snapshot()

#if a tag was found in the previous frame (found == True) ...
#an ROI is defined, so search that ROI for the tag
if found:

#reset the found flag
found = False

#for an ROI a region of the image is copied in memory so memory errors
#occur, use a try except block so it doesn't stop running
try:
#search for the tag inside the ROI defined in the previous frame
tags = img.find_apriltags(roi=ROI, families=image.TAG36H11)

except(MemoryError, OSError):
print("Memory Error")
pass

#if a tag found inside the ROI
if len(tags) >= 1:
#tag was found so set flag to true
found = True
#parameters used to redefine the ROI based on the current tag position and size
ROI = roiCalc(a, b, tags, img)
#if no tags found pass
else:
pass

#... otherwise if no tags were found in the previous frame (found == False)
#search the whole of the current frame
else:

#search for the tag in the entire frame (no roi)
tags = img.find_apriltags(families=image.TAG36H11)
if len(tags) >= 1:
found = True
ROI = roiCalc(a, b, tags, img)

#if a tag was not found then print a statement to say so