TagDetect

Einführung

Die TagDetect-Module laufen intern auf dem rc_visard und ermöglichen es, 2D Barcodes und Marker zu erkennen. Derzeit gibt es TagDetect-Module für QR-Codes und AprilTags. Neben der Erkennung berechnen die Module die Position und Orientierung jedes Markers im 3D-Kamerakoordinatensystem, um diesen beispielsweise mit einem Roboter zu manipulieren oder die Pose der Kamera in Bezug auf den Marker zu berechnen.

Hinweis

Die TagDetect-Module sind optional und benötigen eine separate Lizenz.

Die Markererkennung besteht aus drei Schritten:

  1. Markererkennung auf dem 2D Bildpaar (siehe Markererkennung).
  2. Schätzung der Pose jedes Markers (siehe Posenschätzung).
  3. Wiedererkennung von bisher gesehenen Markern (siehe Marker-Wiedererkennung).

Im Folgenden werden die zwei unterstützten Markertypen näher beschrieben, gefolgt von einem Vergleich.

QR-Code

_images/example_qr_code.png

Abb. 42 Beispiel eines QR-Codes

QR-Codes sind zwei-dimensionale Barcodes, welche beliebige, benutzerspezifizierte Daten enthalten können. Viele Alltagsgeräte, wie beispielsweise Smartphones, unterstützen die Erkennung von QR-Codes. Zusätzlich stehen Online- und Offlinetools zur Verfügung, um QR-Codes zu generieren.

Die „Pixel“ eines QR-Codes werden Module genannt. Das Aussehen und die Auflösung von QR-Codes ändert sich mit der Menge der in ihnen gespeicherten Daten. Während die speziellen Muster in den drei Ecken immer 7 Module breit sind, erhöht sich die Anzahl der Module dazwischen, je mehr Daten gespeichert sind. Der am niedrigsten aufgelöste QR-Code besitzt eine Größe von 21x21 Modulen und kann bis zu 152 Bits speichern.

Auch wenn viele QR-Code-Generatoren speziell designte QR-Codes erzeugen können (bspw. mit einem Logo, mit runden Ecken oder mit Punkten als Module), wird eine zuverlässige Erkennung solcher Marker mit dem TagDetect-Modul nicht garantiert. Gleiches gilt für QR-Codes, welche Zeichen außerhalb des ASCII-Zeichensatzes beinhalten.

AprilTag

_images/apriltag_dim_vis.png

Abb. 43 Ein 16h5 Marker (links) und ein 36h11 Marker (rechts). AprilTags bestehen aus einem obligatorischen weißen (a) und schwarzen (b) Rahmen und einer variablen Menge an Datenmodulen (c).

AprilTags sind ähnlich zu QR-Codes. Sie wurden allerdings speziell zur robusten Identifikation auf weite Entfernungen entwickelt. Wie bei QR-Codes werden die „Pixel“ Module genannt. Abb. 43 veranschaulicht den Aufbau von AprilTags. Sie sind von einem obligatorischen weißen und schwarzen Rahmen umschlossen, welcher jeweils ein Modul breit ist. Innen enthalten sie eine variable Menge an Datenmodulen. Anders als QR-Codes speichern sie keine benutzerdefinierten Informationen, sondern werden durch eine vordefinierte Familie und ID identifiziert. Die Tags in Abb. 43 sind zum Beispiel aus Familie 16h5 bzw. 35h11 und besitzen ID 0 bzw. 11. Alle unterstützten Familien werden in Tab. 23 aufgelistet.

Tab. 23 AprilTag Familien
Familie Anzahl IDs Empfohlen
16h5 30 -
25h7 242 -
25h9 35 o
36h10 2320 o
36h11 587 +

Die Zahl vor dem „h“ jeder Familie bezeichnet die Anzahl der Datenmodule, welche im Marker enthalten sind: Während ein 16h5 Marker 16 (4x4) Datenmodule enthält ((c) in Abb. 43), besteht ein 36h11 Marker aus 36 (6x6) Datenmodulen. Die Zahl hinter dem „h“ bezeichnet den Hamming-Abstand zwischen zwei Markern der Familie. Je höher, desto höher ist die Robustheit, aber desto weniger IDs stehen bei gleicher Anzahl an Datenmodulen zur Verfügung (siehe Tab. 23).

Der Vorteil von Familien mit weniger Datenmodulen (bspw. 16h5 im Vergleich zu 36h11) ist die niedrigere Auflösung der Marker. Jedes Modul ist somit größer, weshalb der Marker auf eine größere Distanz erkannt werden kann. Dies hat allerdings auch Nachteile: Zum einen stehen bei niedrigerer Zahl an Datenmodulen auch weniger IDs zur Verfügung. Wichtiger aber ist, dass die Robustheit der Markererkennung signifikant reduziert wird, da es zu einer höheren Falsch-Positiv-Rate kommt. Dies bedeutet, dass Marker verwechselt werden oder nicht existierende Marker in zufälliger Bildtextur oder im Bildrauschen erkannt werden.

Aus diesen Gründen empfehlen wir die Verwendung der 36h11 Familie und raten ausdrücklich von den Familien 16h5 und 25h7 ab. Letztgenannte Familien sollten nur benutzt werden, wenn eine große Erkennungsdistanz für die Anwendung unbedingt erforderlich ist. Jedoch ist die maximale Erkennungsdistanz nur ca. 25% größer, wenn anstelle der 36h11 Familie die 16h5 Familie verwendet wird.

Vorgenerierte AprilTags können von der AprilTag Projektwebseite (https://april.eecs.umich.edu/software/apriltag.html) heruntergeladen werden. Jede Familie besteht aus mehreren PNGs, welche jeweils einen AprilTag enthalten, und einem PDF, welches jeden AprilTag auf einer eigenen Seite enthält. Jedes Pixel im PNG entspricht dabei einem Modul des AprilTags. Beim Drucken der Marker sollte darauf geachtet werden, den weißen Rand um den AprilTag mit einzuschließen – dieser ist sowohl in den PNGs also auch in den PDFs enthalten (siehe (a) in Abb. 43). Die Marker müssen außerdem ohne Interpolation auf die Druckgröße skaliert werden, sodass die scharfen Kanten erhalten bleiben.

Vergleich

Sowohl QR-Codes als auch AprilTags haben ihre Vor- und Nachteile. Während QR-Codes die Speicherung von benutzerdefinierten Daten erlauben, sind die Marker bei AprilTags vordefiniert und in ihrer Anzahl limitiert. Andererseits haben AprilTags eine niedrigere Auflösung und können daher auf eine größere Distanz erkannt werden. Zusätzlich hilft die durchgängige weiß-zu-schwarz-Kante um jeden AprilTag bei einer präziseren Posenschätzung.

Hinweis

Falls die Speicherung von benutzerdefinierten Daten nicht benötigt wird, sollten AprilTags QR-Codes vorgezogen werden.

Markererkennung

Der erste Schritt der Markererkennung ist die Detektion der Marker auf dem Stereo-Bildpaar. Dieser Schritt benötigt die meiste Zeit und seine Präzision ist entscheidend für die Präzision der finalen Markerpose. Um die Dauer diese Schritts zu kontrollieren, kann der Parameter quality vom Benutzer konfiguriert werden. Er hat ein Herunterskalieren des Stereo-Bildpaares vor der Markererkennung zur Folge. „H“ (High) ergibt die höchste maximale Erkennungssdistanz und Präzision, aber auch die längste Dauer der Erkennung. „L“ (Low) führt zur kleinsten maximalen Erkennungsdistanz und Präzision, aber benötigt auch nur weniger als die halbe Zeit. „M“ (Medium) liegt dazwischen. Es sollte beachtet werden, dass dieser quality-Parameter keine Verbindung zum quality-Parameter des Stereo-Matching hat.

_images/tag_sizes_vis.png

Abb. 44 Visualisierung der Modulgröße \(s\), der Größe eines Markers in Modulen \(r\) und der Größe eines Markers in Metern \(t\) für QR-Codes (links) und AprilTags (rechts)

Die maximale Erkennungsdistanz \(z\) für Qualität „H“ kann mit folgenden Formeln angenähert werden:

\[z = \frac{f s}{p},\]
\[s = \frac{t}{r},\]

wobei \(f\) die Brennweite in Pixeln und \(s\) die Größe jedes Moduls in Metern bezeichnet. \(s\) kann leicht mit letztgenannter Formel berechnet werden, in welcher \(t\) der Markergröße in Metern und \(r\) der Breite des Markers in Modulen entspricht (bei AprilTags ohne den weißen Rahmen). Abb. 44 veranschaulicht diese Variablen. \(p\) bezeichnet die Zahl der Bildpixel pro Modul, welche für eine Erkennung erforderlich sind. Sie unterscheidet sich zwischen QR-Codes und AprilTags. Auch der Winkel des Markers zur Kamera und die Beleuchtung spielen eine Rolle. Ungefähre Werte für eine robuste Erkennung sind:

  • AprilTag: \(p=5\) Pixel/Modul
  • QR-Code: \(p=6\) Pixel/Modul

Die folgenden Tabellen enthalten Beispiele für die maximale Erkennungsdistanz in unterschiedlichen Situationen. Die Brennweite des rc_visard wird dafür mit 1075 Pixeln, die Qualität mit „H“ angenommen.

Tab. 24 Beispiele zur maximalen Erkennungsdistanz für QR-Codes mit einer Breite von \(t=4\) cm
AprilTag Familie Markerbreite Maximale Distanz
36h11 (empfohlen) 8 Module 1.1 m
16h5 6 Module 1.4 m
Tab. 25 Beispiele zur maximalen Erkennungsdistanz für QR-Codes mit einer Breite von \(t=8\) cm
Markerbreite Maximale Distanz
29 Module 0.49 m
21 Module 0.70 m

Posenschätzung

Für jeden erkannten Marker wird dessen Pose im Kamerakoordinatensystem geschätzt. Eine Bedingung dafür ist, dass der Marker vollständig im linken und rechten Bild zu sehen ist. Das Koordinatensystem ist wie unten gezeigt am Marker ausgerichtet.

_images/tag_coord_frames.png

Abb. 45 Koordinatensysteme für AprilTags (links) bzw. QR-Codes (rechts)

Die z-Achse zeigt „in“ den Marker. Es ist zu beachten, dass, auch wenn AprilTags den weißen Rand in ihrer Definition enthalten, der Ursprung des Koordinatensystems trotzdem am Übergang des weißen zum schwarzen Rand liegt. Da AprilTags keine offensichtliche Orientierung haben, liegt der Ursprung in der oberen linken Ecke des vorgenerierten AprilTags.

Während der Posenschätzung wird auch die Größe des Markers geschätzt unter der Annahme, dass der Marker quadratisch ist. Bei QR-Codes bezieht sich die Größe auf den gesamten Marker, bei AprilTags dagegen nur auf den schwarzen Rand, also ohne den äußeren weißen.

Hinweis

Für beste Ergebnisse der Posenschätzung sollte der Marker sorgfältig gedruckt und auf einem steifen und möglichst ebenen Untergrund angebracht werden. Jegliche Verzerrung des Markers oder Unebenheit der Oberfläche verschlechtert die geschätzte Pose.

Achtung

Falls mehrere Marker mit derselben ID im linken oder rechten Bild sichtbar sind, kann es zu einer fehlerhaften Posenschätzung kommen, wenn die Marker gleich orientiert sind und sie ungefähr parallel zu den Bildzeilen angeordnet sind. Die TagDetect-Module versuchen, solche Situationen zu erkennen und verwerfen betroffene Marker. Zusätzlich ist der Benutzer angehalten, die geschätzte Markergröße auf Konsistenz zu prüfen: Eine fehlerhafte Posenschätzung kann daran erkannt werden, dass die geschätzte Größe nicht der realen Größe des Markers entspricht.

Unten stehende Tabellen enthalten grobe Angaben zur Präzision der geschätzten Posen von AprilTags und QR-Codes. Wir unterscheiden zwischen lateraler Präzision (also in x- und y-Richtung) und Präzision in z-Richtung. Es wird angenommen, dass quality auf „H“ gesetzt ist, und dass die Blickrichtung des rc_visard parallel zur Normalen des Markers ist. Die Größe eines Markers hat keinen signifikanten Einfluss auf die Präzision in lateraler und z-Richtung. Im Allgemeinen verbessert ein größerer Marker allerdings die Präzision. Im Bezug auf die Präzision der Rotation, im speziellen um die x- und y-Achsen, übertreffen große Marker kleinere deutlich.

Tab. 26 Ungefähre Präzision der Pose von AprilTags
Distanz rc_visard 65 - lateral rc_visard 65 - z rc_visard 160 - lateral rc_visard 160 - z
0.3 m 0.4 mm 0.9 mm 0.4 mm 0.8 mm
1.0 m 0.7 mm 3.3 mm 0.7 mm 3.3 mm
Tab. 27 Ungefähre Präzision der Pose von QR-Codes
Distanz rc_visard 65 - lateral rc_visard 65 - z rc_visard 160 - lateral rc_visard 160 - z
0.3 m 0.6 mm 2.0 mm 0.6 mm 1.3 mm
1.0 m 2.6 mm 15 mm 2.6 mm 7.9 mm

Marker-Wiedererkennung

Jeder Marker besitzt eine ID: bei AprilTags ist dies die Familie zusammen mit der AprilTag ID, bei QR-Codes die enthaltenen Daten. Diese IDs sind jedoch nicht einzigartig, da mehrere Marker mit derselben ID in einer Szene vorkommen können.

Zur Unterscheidung dieser Marker weisen die TagDetect-Module jedem Marker einen eindeutigen Identifikator zu. Um den Benutzer dabei zu unterstützen, denselben Marker über mehrere Markererkennungsläufe hinweg zu identifizieren, versucht das TagDetect-Modul Marker wiederzuerkennen. Falls erfolgreich, wird einem Marker derselbe Identifikator zugewiesen. Die Marker-Wiedererkennung vergleicht die Positionen der Ecken der Marker in einem statischen Koordinatensystem, um identische Marker wiederzufinden. Marker werden als identisch angenommen, falls sie sich nicht oder nur geringfügig im statischen Koordinatensystem bewegt haben. Damit das statische Koordinatensystem verfügbar ist, muss das Dynamik-Modul angeschaltet sein. Falls dies nicht der Fall ist, wird der Sensor als statisch angenommen. Die Marker-Wiedererkennung funktioniert in diesem Fall nicht über Bewegungen des Sensors hinweg.

Über den max_corner_distance-Parameter kann der Benutzer festlegen, wie weit ein Marker sich zwischen zwei Erkennungsläufen bewegen darf, um als identisch zu gelten. Der Parameter definiert die maximale Distanz zwischen den Ecken zweier Marker, was in Abb. 46 dargestellt ist. Die euklidischen Abstände der vier zusammengehörenden Markerecken in 3D werden berechnet. Falls keiner dieser Abstände den Grenzwert überschreitet, gilt der Marker als wiedererkannt.

_images/tag-re-identification.png

Abb. 46 Vereinfachte Darstellung der Marker-Wiedererkennung. Die euklidischen Abstände zwischen zusammengehörigen Markerecken in 3D werden berechnet (rote Pfeile).

Nach einer bestimmten Anzahl von Markererkennungsläufen werden vorher gesehene Marker verworfen, falls diese in der Zwischenzeit nicht mehr erkannt wurden. Dies kann über den Parameter forget_after_n_detections festgelegt werden.

Schnittstellen

Es gibt auf dem Sensor zwei getrennte Module für die Markererkennung, eines für AprilTag- und eines für QR-Code-Erkennung: rc_april_tag_detect bzw. rc_qr_code_detect. Abgesehen vom Modulnamen teilen beide die gleiche Schnittstellendefinition.

Parameter und Statuswerte

Dieses Softwaremodul bietet folgende Laufzeitparameter.

Tab. 28 Laufzeitparameter des rc_qr_code_detect-Moduls
Name Typ Min. Max. Default Beschreibung
forget_after_n_detections int32 1 1000 30 Anzahl an Markererkennungsläufen nach denen ein vorher gesehener Marker während der Marker-Wiedererkennung verworfen wird
max_corner_distance float64 0.001 0.01 0.005 Maximale Distanz zusammengehöriger Ecken zweier Marker während der Marker-Wiedererkennung
quality string - - H Qualität der Markererkennung (H, M oder L)
use_cached_images bool False True False Benutze das zuletzt empfangene Stereo-Bildpaar anstatt auf ein neues zu warten

Dieses Modul meldet folgende Statuswerte:

Tab. 29 Statuswerte des rc_qr_code_detect-Moduls
Name Beschreibung
state Der aktuelle Zustand der node

Der Parameter state kann folgende Werte annehmen:

Tab. 30 Mögliche Zustände der TagDetect-Module
Zustandsname Beschreibung
IDLE Das Modul ist inaktiv.
RUNNING Das Modul läuft und ist bereit zur Markererkennung.
FATAL Ein fataler Fehler ist aufgetreten.

Services

Die TagDetect-Module implementieren einen Zustandsautomaten, welcher zum Starten und Stoppen genutzt werden kann. Die eigentliche Markererkennung kann mit detect ausgelöst werden.

start

startet das Modul durch einen Übergang von IDLE nach RUNNING.

Wenn das Modul läuft, empfängt es die Bilder der Stereokamera und ist bereit, Marker zu erkennen. Um Rechenressourcen auf dem Sensor zu sparen, sollte das Modul nur laufen, wenn dies nötig ist.

Für diesen Service sind keine Argumente nötig.

Dieser Service liefert folgenden Rückgabewert:

{
  "accepted": "bool",
  "current_state": "string"
}
stop

stoppt das Modul durch einen Übergang zu IDLE.

Dieser Übergang kann auf dem Zustand RUNNING und FATAL durchgeführt werden. Alle Marker-Wiedererkennungs-Informationen werden beim Stoppen gelöscht.

Für diesen Service sind keine Argumente nötig.

Dieser Service liefert folgenden Rückgabewert:

{
  "accepted": "bool",
  "current_state": "string"
}
restart

startet das Modul neu. Wenn im Zustand RUNNING oder FATAL, wird das Modul erst gestoppt und dann wieder gestartet. In IDLE wird das Modul nur gestartet.

Für diesen Service sind keine Argumente nötig.

Dieser Service liefert folgenden Rückgabewert:

{
  "accepted": "bool",
  "current_state": "string"
}
detect

löst eine Markererkennung aus. Abhängig vom use_cached_images-Parameter arbeitet das Modul auf dem zuletzt empfangenen Bildpaar (wenn true) oder wartet auf ein Bildpaar, das nach dem Auslösen des Services aufgenommen wurde (wenn false, dies ist das Standardverhalten). Auch wenn der Parameter auf true steht, arbeitet die Markererkennung niemals mehrmals auf einem Bildpaar.

Es wird empfohlen, detect nur im Zustand RUNNING aufzurufen. Es ist jedoch auch im Zustand IDLE möglich, was zu einem Autostart und -stop des Moduls führt. Dies hat allerdings Nachteile: Erstens dauert der Aufruf deutlich länger, zweitens funktioniert die Marker-Wiedererkennung nicht. Es wird daher ausdrücklich empfohlen, das Modul manuell zu starten, bevor detect aufgerufen wird.

Für diesen Service sind folgende Argumente nötig:

{
  "tags": [
    {
      "id": "string"
    }
  ]
}

Dieser Service liefert folgenden Rückgabewert:

{
  "return_code": {
    "message": "string",
    "value": "int16"
  },
  "tags": [
    {
      "id": "string",
      "instance_id": "string",
      "pose": {
        "orientation": {
          "w": "float64",
          "x": "float64",
          "y": "float64",
          "z": "float64"
        },
        "position": {
          "x": "float64",
          "y": "float64",
          "z": "float64"
        }
      },
      "pose_frame": "string",
      "size": "float64",
      "timestamp": {
        "nsec": "int32",
        "sec": "int32"
      }
    }
  ],
  "timestamp": {
    "nsec": "int32",
    "sec": "int32"
  }
}
Anfrage:

tags bezeichnet die Liste der Marker-IDs, welche erkannt werden sollen. Bei QR-Codes ist die ID gleich den enthaltenen Daten. Bei AprilTags ist es „<Familie>_<ID>“, also beispielsweise „36h11_5“ für Familie 36h11 und ID 5. Natürlich kann das AprilTag-Modul nur zur Erkennung von AprilTags und das QR-Code-Modul nur zur Erkennung von QR-Codes genutzt werden.

Die tags Liste kann auch leer gelassen werden. In diesem Fall werden alle erkannten Marker zurückgegeben. Dieses Feature sollte nur während der Entwicklung einer Applikation oder zur Fehlerbehebung benutzt werden. Wann immer möglich sollten die konkreten Marker-IDs aufgelistet werden, zum einen zur Vermeidung von Fehldetektionen, zum anderen auch um die Markererkennung zu beschleunigen, da nicht benötigte Marker aussortiert werden können.

Bei AprilTags kann der Benutzer nicht nur einzelne Marker, sondern auch eine gesamte Familie spezifizieren, indem die ID auf „<family>“ gesetzt wird, bspw. „36h11“. Dadurch werden alle Marker dieser Familie erkannt. Es ist auch möglich, mehrere Familien oder eine Kombination aus Familien und einzelnen Markern anzugeben. Zum Beispiel kann detect mit „36h11“, „25h9_3“ und „36h10“ zur gleichen Zeit aufgerufen werden.

Antwort:

timestamp wird auf den Zeitstempel des Bildpaares gesetzt, auf dem die Markererkennung gearbeitet hat.

tags enthält alle erkannten Marker. id ist die ID des Markers, vergleichbar zur id in der Anfrage. instance_id ist der zufällige, eindeutige Identifikator eines Markers, welcher von der Marker-Wiedererkennung zugewiesen wird. pose enthält position und orientation. Die Orientierung ist im Quaternionen-Format angegeben. pose_frame bezeichnet das Koordinatensystem, auf welches obige Pose bezogen ist. Es wird immer auf camera gesetzt sein. size wird auf die geschätzte Markergröße gesetzt. Bei AprilTags ist hier der weiße Rahmen nicht enthalten.

return_code beinhaltet in value mögliche Warnungen oder Fehlercodes, welche von einem Wert größer bzw. kleiner als 0 repräsentiert werden. Die zugehörige Fehlermeldung kann in message gefunden werden. Die folgende Tabelle enthält eine Liste von üblichen Codes:

Code Beschreibung
0 Erfolgreich
-1 Ein ungültiges Argument wurde übergeben
-4 Die maximale Wartezeit auf ein Stereo-Bildpaar wurde überschritten
-9 Die Lizenz ist ungültig
-101 Interner Fehler
-102 Ein Rückwärtssprung der Systemzeit trat auf
-200 Ein fataler interner Fehler trat auf
101 Eine Warnung trat während der Markererkennung auf
102 Eine Warnung trat während der Posenschätzung auf
200 Mehrere Warnungen traten auf. Siehe die Auflistung in message
201 Das Modul war nicht im Zustand RUNNING

Marker können vom detect-Ergebnis aus mehreren Gründen ausgeschlossen werden, z.B. falls ein Marker nur in einem der Kamerabilder sichtbar war, oder falls die Posenschätzung fehlschlug. Diese herausgefilterten Marker werden im Log aufgelistet, auf welches wie in Download der Logdateien beschrieben zugegriffen werden kann.

Aufgrund von Änderungen der Systemzeit auf dem Sensor können Zeitsprünge auftreten, sowohl vorwärts als auch rückwärts (siehe Zeitsynchronisierung). Während Vorwärtssprünge keinen Einfluss auf die TagDetect-Module haben, invalidieren Rücksprünge die bereits empfangenen Bilder. Deshalb wird, wenn ein Rücksprung erkannt wird, Fehler -102 beim nächsten detect Aufruf zurückgegeben. Dies geschieht auch, um den Benutzer darauf hinzuweisen, dass die Zeitstempel in der detect Antwort ebenso zurückspringen werden.

save_parameters
Beim Aufruf dieses Services werden die aktuellen Parametereinstellungen des TagDetect-Moduls auf dem rc_visard gespeichert. Das bedeutet, dass diese Werte selbst nach einem Neustart angewandt werden.
reset_defaults
Hiermit werden die Werkseinstellungen der Parameter dieses Moduls wiederhergestellt und angewandt („factory reset“).