Title: Determining ArUco marker type with OpenCV and Python - PyImageSearch

URL Source: https://pyimagesearch.com/2020/12/28/determining-aruco-marker-type-with-opencv-and-python/

Published Time: 2020-12-28T15:00:00+00:00

Markdown Content:
In this tutorial you will learn how to automatically determine ArUco marker type/dictionary with OpenCV and Python.

![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20700%20450'%3E%3C/svg%3E)

Today’s tutorial is the final part of our three-part series on ArUco marker generation and detection:

1.  _[Generating ArUco markers with OpenCV and Python](https://pyimagesearch.com/2020/12/14/generating-aruco-markers-with-opencv-and-python/)_ (tutorial from two weeks ago)
2.  _[Detecting ArUco markers in images and video with OpenCV](https://pyimagesearch.com/2020/12/21/detecting-aruco-markers-with-opencv-and-python/)_ (last week’s post)
3.  _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._**

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

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**

![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20700%20500'%3E%3C/svg%3E)

**Figure 1:** In this example image we have four ArUco markers, but we don’t know what dictionary was used to generate them, so how are we going to actually _detect_ them?

[Two weeks ago we learned how to _generate_ ArUco markers](https://pyimagesearch.com/2020/12/14/generating-aruco-markers-with-opencv-and-python/), and then last week we learned how to [_detect_ them in images and video](https://pyimagesearch.com/2020/12/21/detecting-aruco-markers-with-opencv-and-python/) — **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](https://pyimagesearch.com/2020/12/14/generating-aruco-markers-with-opencv-and-python/).

### **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](https://pyimagesearch.com/2018/09/19/pip-install-opencv/)** — it will have you up and running in a matter of minutes.

### **Having problems configuring your development environment?**

[![Image 4: Screenshot of PyImageSearch Plus and Google Colab Notebook with Jupyter logo overlaid](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20334'%3E%3C/svg%3E)](https://pyimagesearch.com/pyimagesearch-plus/)

**Figure 2:** Having trouble configuring your dev environment? Want access to pre-configured Jupyter Notebooks running on Google Colab? Be sure to join [PyImageSearch Plus](https://pyimagesearch.com/pyimagesearch-plus/) — you’ll be up and running with this tutorial in a matter of minutes.

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](https://pyimagesearch.com/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 `` `guess_aruco_type.py` `` file in your project directory structure, and insert the following code:

\# 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](https://pyimagesearch.com/2020/12/14/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:

1.  Load the `arucoDict` via `cv2.aruco.Dictionary_get`
2.  Instantiate the ArUco detector parameters
3.  Apply `cv2.aruco.detectMarkers` to detect tags for the current `arucoDict` 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'

![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20400'%3E%3C/svg%3E)

**Figure 3:** An example image containing ArUco tags generated with a _5×5_ dictionary. These ArUco tags were generated in [last week’s tutorial](https://pyimagesearch.com/2020/12/21/detecting-aruco-markers-with-opencv-and-python/).

This image contains five example ArUco images (which we generated back in [part 1 of this series on ArUco markers](https://pyimagesearch.com/2020/12/14/generating-aruco-markers-with-opencv-and-python/)).

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:

1.  We know for a _fact_ that these are _5×5_ markers.
2.  We know that the markers detected in this image have IDs _< 50._
3.  However, if there are _more_ markers in other images, we may encounter ArUco _5×5_ markers with values _\> 50._
4.  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'

![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20338%20450'%3E%3C/svg%3E)

**Figure 4:** Recognizing ArUco tag types in an image where I _didn’t_ know what ArUco dictionary was used to generate them.

Here you can see an example image containing a [Pantone color matching card.](https://www.pantone.com/pantone-color-match-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'

![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20544%20400'%3E%3C/svg%3E)

**Figure 5:** OpenCV is able to correctly detect that these are AprilTags (and not ArUco tags).

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? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,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:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, 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_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

**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!_**

![Image 8](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### 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!