In this tutorial you will learn how to automatically determine ArUco marker type/dictionary with OpenCV and Python.
Today’s tutorial is the final part of our three-part series on ArUco marker generation and detection:
- Generating ArUco markers with OpenCV and Python (tutorial from two weeks ago)
- Detecting ArUco markers in images and video with OpenCV (last week’s post)
- Automatically determining ArUco marker type with OpenCV and Python (today’s tutorial)
So far in this series, we’ve learned how to generate and detect ArUco markers; however, these methods hinge on the fact that we already know what type of ArUco dictionary was used to generate the markers.
That raises the question:
What if you didn’t know the ArUco dictionary used to generate markers?
Without knowing the ArUco dictionary used, you won’t be able to detect them in your images/video.
When that happens you need a method that can automatically determine the ArUco marker type in an image — and that’s exactly what I’ll be showing you how to do today.
To learn how to automatically determine ArUco marker type/dictionary with OpenCV, just keep reading.
Looking for the source code to this post?
Jump Right To The Downloads SectionDetermining ArUco marker type with OpenCV and Python
In the first part of this tutorial, you will learn about the various types of ArUco markers and AprilTags.
From there, you’ll implement a Python script that can automatically detect if any type of ArUco dictionary exists in an image or video stream, thereby allowing you to reliably detect ArUco markers even if you don’t know what ArUco dictionary was used to generate them!
We’ll then review the results of our work and discuss next steps (hint: we’ll be doing some augmented reality starting next week).
Types of ArUco and AprilTag markers
Two weeks ago we learned how to generate ArUco markers, and then last week we learned how to detect them in images and video — but what happens if we don’t already know the ArUco dictionary we’re using?
Such a situation can arise when you’re developing a computer vision application where you did not generate the ArUco markers yourself. Instead, these markers may have been generated by another person or organization (or maybe you just need a general purpose algorithm to detect any ArUco type in an image or video stream).
When such a situation arises, you need to be able to automatically infer ArUco dictionary type.
At the time of this writing, the OpenCV library can detect 21 different types of AruCo/AprilTag markers.
The following snippet of code shows the unique variable identifier assigned to each type of marker dictionary:
# define names of each possible ArUco tag OpenCV supports ARUCO_DICT = { "DICT_4X4_50": cv2.aruco.DICT_4X4_50, "DICT_4X4_100": cv2.aruco.DICT_4X4_100, "DICT_4X4_250": cv2.aruco.DICT_4X4_250, "DICT_4X4_1000": cv2.aruco.DICT_4X4_1000, "DICT_5X5_50": cv2.aruco.DICT_5X5_50, "DICT_5X5_100": cv2.aruco.DICT_5X5_100, "DICT_5X5_250": cv2.aruco.DICT_5X5_250, "DICT_5X5_1000": cv2.aruco.DICT_5X5_1000, "DICT_6X6_50": cv2.aruco.DICT_6X6_50, "DICT_6X6_100": cv2.aruco.DICT_6X6_100, "DICT_6X6_250": cv2.aruco.DICT_6X6_250, "DICT_6X6_1000": cv2.aruco.DICT_6X6_1000, "DICT_7X7_50": cv2.aruco.DICT_7X7_50, "DICT_7X7_100": cv2.aruco.DICT_7X7_100, "DICT_7X7_250": cv2.aruco.DICT_7X7_250, "DICT_7X7_1000": cv2.aruco.DICT_7X7_1000, "DICT_ARUCO_ORIGINAL": cv2.aruco.DICT_ARUCO_ORIGINAL, "DICT_APRILTAG_16h5": cv2.aruco.DICT_APRILTAG_16h5, "DICT_APRILTAG_25h9": cv2.aruco.DICT_APRILTAG_25h9, "DICT_APRILTAG_36h10": cv2.aruco.DICT_APRILTAG_36h10, "DICT_APRILTAG_36h11": cv2.aruco.DICT_APRILTAG_36h11 }
In the remainder of this tutorial, you will learn how to automatically check whether any of these ArUco types exists in an input image.
To learn more about these ArUco types, please refer to this post.
Configuring your development environment
In order to generate and detect ArUco markers, you need to have the OpenCV library installed.
Luckily, OpenCV is pip-installable:
$ pip install opencv-contrib-python
If you need help configuring your development environment for OpenCV, I highly recommend that you read my pip install opencv guide — it will have you up and running in a matter of minutes.
Having problems configuring your development environment?
All that said, are you:
- Short on time?
- Learning on your employer’s administratively locked system?
- Wanting to skip the hassle of fighting with the command line, package managers, and virtual environments?
- Ready to run the code right now on your Windows, macOS, or Linux system?
Then join PyImageSearch Plus today!
Gain access to Jupyter Notebooks for this tutorial and other PyImageSearch guides that are pre-configured to run on Google Colab’s ecosystem right in your web browser! No installation required.
And best of all, these Jupyter Notebooks will run on Windows, macOS, and Linux!
Project structure
Start by using the “Downloads” section of this tutorial to download the source code and example images.
From there, let’s inspect the directory structure of our project:
$ tree . --dirsfirst . ├── images │ ├── example_01.png │ ├── example_02.png │ └── example_03.png └── guess_aruco_type.py 1 directory, 4 files
We have a single Python script today, guess_aruco_type.py
.
This script will examine the examples in the images/
directory and, with no prior knowledge of the ArUco tags in these images, will automatically determine the ArUco tag type.
Such a script is extremely useful when you’re tasked with finding ArUco tags in images/video streams but aren’t sure what ArUco dictionary was used to generate these tags.
Implementing our ArUco/AprilTag marker type identifier
The method we’ll implement for our automatic AruCo/AprilTag type identifier is a bit of a hack, but my feeling is that a hack is just a heuristic that works in practice.
Sometimes it’s OK to ditch the elegance and instead just get the damn solution — this script is an example of such a situation.
Open up the
file in your project directory structure, and insert the following code:guess_aruco_type.py
# import the necessary packages import argparse import imutils import cv2 # construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="path to input image containing ArUCo tag") args = vars(ap.parse_args())
We import our required command line arguments on Lines 2-4 and then parse our command line arguments.
Only a single command line argument is required here, --image
, which is the path to our input image.
With the command line arguments parsed, we can move on to defining our ARUCO_DICT
dictionary, which provides the names and unique variable identifiers for each of the ArUco dictionaries that OpenCV supports:
# define names of each possible ArUco tag OpenCV supports ARUCO_DICT = { "DICT_4X4_50": cv2.aruco.DICT_4X4_50, "DICT_4X4_100": cv2.aruco.DICT_4X4_100, "DICT_4X4_250": cv2.aruco.DICT_4X4_250, "DICT_4X4_1000": cv2.aruco.DICT_4X4_1000, "DICT_5X5_50": cv2.aruco.DICT_5X5_50, "DICT_5X5_100": cv2.aruco.DICT_5X5_100, "DICT_5X5_250": cv2.aruco.DICT_5X5_250, "DICT_5X5_1000": cv2.aruco.DICT_5X5_1000, "DICT_6X6_50": cv2.aruco.DICT_6X6_50, "DICT_6X6_100": cv2.aruco.DICT_6X6_100, "DICT_6X6_250": cv2.aruco.DICT_6X6_250, "DICT_6X6_1000": cv2.aruco.DICT_6X6_1000, "DICT_7X7_50": cv2.aruco.DICT_7X7_50, "DICT_7X7_100": cv2.aruco.DICT_7X7_100, "DICT_7X7_250": cv2.aruco.DICT_7X7_250, "DICT_7X7_1000": cv2.aruco.DICT_7X7_1000, "DICT_ARUCO_ORIGINAL": cv2.aruco.DICT_ARUCO_ORIGINAL, "DICT_APRILTAG_16h5": cv2.aruco.DICT_APRILTAG_16h5, "DICT_APRILTAG_25h9": cv2.aruco.DICT_APRILTAG_25h9, "DICT_APRILTAG_36h10": cv2.aruco.DICT_APRILTAG_36h10, "DICT_APRILTAG_36h11": cv2.aruco.DICT_APRILTAG_36h11 }
I covered the types of ArUco dictionaries, including their name conventions in my previous tutorial Generating ArUco markers with OpenCV and Python.
If you would like more information on ArUco dictionaries please refer there; otherwise, simply understand that this dictionary lists out all possible ArUco tags that OpenCV can detect.
We’ll exhaustively loop over this dictionary, load the ArUco detector for each entry, and then apply the detector to our input image.
If we get a hit for a specific tag type, then we know that ArUco tag exists in the image.
Speaking of which, let’s implement that logic now:
# load the input image from disk and resize it print("[INFO] loading image...") image = cv2.imread(args["image"]) image = imutils.resize(image, width=600) # loop over the types of ArUco dictionaries for (arucoName, arucoDict) in ARUCO_DICT.items(): # load the ArUCo dictionary, grab the ArUCo parameters, and # attempt to detect the markers for the current dictionary arucoDict = cv2.aruco.Dictionary_get(arucoDict) arucoParams = cv2.aruco.DetectorParameters_create() (corners, ids, rejected) = cv2.aruco.detectMarkers( image, arucoDict, parameters=arucoParams) # if at least one ArUco marker was detected display the ArUco # name to our terminal if len(corners) > 0: print("[INFO] detected {} markers for '{}'".format( len(corners), arucoName))
Lines 39 and 40 load our input --image
from disk and resize it.
From there we loop over all possible ArUco dictionaries that OpenCV supports on Line 43.
For each ArUco dictionary we:
- Load the
arucoDict
viacv2.aruco.Dictionary_get
- Instantiate the ArUco detector parameters
- Apply
cv2.aruco.detectMarkers
to detect tags for the currentarucoDict
in the input image
If the length of the resulting corners
list is greater than zero (Line 53), then we know the current arucoDict
had been used to (potentially) generate the ArUco tags in our input image.
In that case we log the number of tags found in the image along with the name of the ArUco dictionary to our terminal so we can investigate further after running the script.
Like I said, there isn’t much “elegance” to this script — it’s a downright hack. But that’s OK. Sometimes all you need is a good hack to unblock you and keep you moving forward on your project.
ArUco marker type identification results
Let’s put our ArUco marker type identifier to work!
Make sure you use the “Downloads” section of this tutorial to download the source code and example images to this post.
From there, pop open a terminal, and execute the following command:
$ python guess_aruco_type.py --image images/example_01.png [INFO] loading image... [INFO] detected 2 markers for 'DICT_5X5_50' [INFO] detected 5 markers for 'DICT_5X5_100' [INFO] detected 5 markers for 'DICT_5X5_250' [INFO] detected 5 markers for 'DICT_5X5_1000'
This image contains five example ArUco images (which we generated back in part 1 of this series on ArUco markers).
The ArUco markers belong to the 5×5 class and either have IDs up to 50, 100, 250, or 1000, respectively. These results imply that:
- We know for a fact that these are 5×5 markers.
- We know that the markers detected in this image have IDs < 50.
- However, if there are more markers in other images, we may encounter ArUco 5×5 markers with values > 50.
- If we’re working with just this image, then it’s safe to assume
DICT_5X5_50
, but if we have more images, keep investigating and find the smallest ArUco dictionary that fits all unique IDs into it.
Let’s try another example image:
$ python guess_aruco_type.py --image images/example_02.png [INFO] loading image... [INFO] detected 1 markers for 'DICT_4X4_50' [INFO] detected 1 markers for 'DICT_4X4_100' [INFO] detected 1 markers for 'DICT_4X4_250' [INFO] detected 1 markers for 'DICT_4X4_1000' [INFO] detected 4 markers for 'DICT_ARUCO_ORIGINAL'
Here you can see an example image containing a Pantone color matching card. OpenCV (incorrectly) thinks that these markers might be of the 4×4 class, but if you zoom in on the example image, you’ll see that that’s not true, since these are actually 6×6 markers with an additional bit of padding surrounding the marker.
Furthermore, since only one marker was detected for the 4×4 class, and since there are four total markers in the image, we can therefore deduce that these must be DICT_ARUCO_ORIGINAL
.
We’ll look at one final image, this one containing containing AprilTags:
$ python guess_aruco_type.py --image images/example_03.png [INFO] loading image... [INFO] detected 3 markers for 'DICT_APRILTAG_36h11'
Here OpenCV can infer that we are most certainly looking at AprilTags.
I hope you enjoyed this series of tutorials on ArUco markers and AprilTags!
In the next few weeks, we’ll start looking at practical, real-world applications of ArUco markers, including how to incorporate them into our own computer vision and image processing pipelines.
What's next? I recommend PyImageSearch University.
30+ total classes • 39h 44m video • Last updated: 12/2021
★★★★★ 4.84 (128 Ratings) • 3,000+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 30+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 30+ Certificates of Completion
- ✓ 39h 44m on-demand video
- ✓ Brand new courses released every month, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 500+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
Summary
In this tutorial you learned how to automatically determine ArUco marker type, even if you don’t know what ArUco dictionary was originally used!
Our method is a bit of a hack, as it requires us to exhaustively loop over all possible ArUco dictionaries and then attempt to detect that specific ArUco dictionary in the input image.
That said, our hack works, so it’s hard to argue with it.
Keep in mind that there’s nothing wrong with a “hack.” As I like to say, hack is just a heuristic that works.
Starting next week you’ll get to see real-world examples of applying ArUco detection, including augmented reality.
To download the source code to this post (and be notified when future tutorials are published here on PyImageSearch), simply enter your email address in the form below!
Download the Source Code and FREE 17-page Resource Guide
Enter your email address below to get a .zip of the code and a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!
Comment section
Hey, Adrian Rosebrock here, author and creator of PyImageSearch. While I love hearing from readers, a couple years ago I made the tough decision to no longer offer 1:1 help over blog post comments.
At the time I was receiving 200+ emails per day and another 100+ blog post comments. I simply did not have the time to moderate and respond to them all, and the sheer volume of requests was taking a toll on me.
Instead, my goal is to do the most good for the computer vision, deep learning, and OpenCV community at large by focusing my time on authoring high-quality blog posts, tutorials, and books/courses.
If you need help learning computer vision and deep learning, I suggest you refer to my full catalog of books and courses — they have helped tens of thousands of developers, students, and researchers just like yourself learn Computer Vision, Deep Learning, and OpenCV.
Click here to browse my full catalog.