5.28. QR kódy a AprilTagy¶
Dosavadní detektory – bloby, čáry, kružnice, obdélníky – hledají geometrické příznaky: pozice a obrysy, které interpretuje až navazující fáze. Zbývající detektory hledají symbolické příznaky: vytištěné vzory, jejichž vizuální struktura existuje konkrétně proto, aby zakódovala nějaká data. Kamera je lokalizuje, dekodér přečte bity a to, co se vrátí, není pozice, ale řetězec (nebo ID), které tvůrce symbolu zvolil záměrně.
Dvě takové skupiny dominují aplikacím s malými kamerami. QR kódy nesou libovolný text, URL, kontaktní karty nebo binární data – spotřebitelsky orientované 2D kódy, které se objevují na plakátech, obalech a palubních lístcích. AprilTagy nesou jediné číselné ID z malé pevné množiny, dekódují se rychle i z velké vzdálenosti a (jsou-li dodány vnitřní parametry objektivu) hlásí pózu se 6 stupni volnosti v souřadnicích kamery – 2D kódy orientované na robotiku, které značí drony, kalibrační terče a fiduciální značky. Oba detektory vracejí výsledkové objekty se stejným slovníkem ohraničujícího rámečku, jaký používají detektory blobů a obdélníků, ale obsah jejich dat je činí skutečně odlišnými od všeho, co bylo dosud probráno.
5.28.1. QR kódy¶
find_qrcodes() prohledá snímek a hledá QR kódy a vrátí seznam výsledkových objektů QRCode:
codes = img.find_qrcodes()
for c in codes:
img.draw_rectangle(c.rect, color=(0, 255, 0))
for corner in c.corners:
img.draw_circle((corner[0], corner[1], 4),
color=(0, 255, 0))
print(c.payload)
Detektor přijímá jediný volitelný argument roi pro omezení vyhledávání. Potřebuje vstup ve stupních šedi – barevný snímek je před dekódováním interně převeden.
Každá detekce nese ohraničující rámeček (x, y, w, h, rect), čtyři nalezené rohy (corners, projektivní čtyřúhelník, který vykreslují vyhledávací vzory QR kódu) a dekódovaná data jako řetězec. Rohy jsou to správné, co kreslit při anotování detekce – QR kód viděný mimo osu není zarovnaný s osami a ohraničující rámeček dává jen volný obrys.
Metadata dekodéru pokrývají vše, co se dekodér QR kódu cestou dozvěděl. version je verze QR kódu, 1 – 40, která určuje velikost mřížky modulů (kód verze 1 je široký 21 modulů, kód verze 40 je široký 177). ecc_level je úroveň korekce chyb (0 – 3 pro L / M / Q / H); vyšší úrovně vyhrazují více kódových slov pro korekci chyb a přežijí větší poškození za cenu menšího prostoru pro data. mask je maskovací vzor (0 – 7), který kodér zvolil, aby minimalizoval zmatení dekodéru. data_type je kódování, které dekodér ohlásil – numerické, alfanumerické, binární nebo Kanji – a příznaky is_numeric / is_alphanumeric / is_binary / is_kanji zpřístupňují stejnou hodnotu jako přívětivější booleovské hodnoty.
eci je hodnota Extended Channel Interpretation, která identifikuje textové kódování, v němž jsou bajty (UTF-8, ISO-8859-1 a tak dále). U QR kódu z libovolného tištěného materiálu nemusí být zaručeno UTF-8; aplikace, která potřebuje dekódovat bajty správně, zkontroluje eci a dekóduje odpovídajícím způsobem. Zejména případ Kanji: MicroPython neparsuje kódování Kanji, takže s daty is_kanji se musí zacházet jako s polem bajtů a dekódovat je musí aplikace.
Typické použití: kamera čte QR kódy z dopravníku a hlásí dekódovaná data hostiteli. Kamera spustí find_qrcodes() jednou za snímek, projde vrácený seznam, vybere kódy, jejichž data_type odpovídá tomu, co aplikace očekává, a přepošle c.payload přes UART nebo USB. Data ohraničujícího rámečku a rohů jsou užitečná pro náhled v IDE, ale nejsou tím, co hostitele zajímá.
5.28.2. AprilTagy¶
find_apriltags() prohledá snímek a hledá AprilTagy a vrátí seznam výsledkových objektů AprilTag:
tags = img.find_apriltags(families=image.TAG36H11)
for t in tags:
img.draw_rectangle(t.rect, color=(0, 255, 0))
img.draw_cross(t.cx, t.cy, color=(0, 255, 0))
print(t.id, t.decision_margin)
AprilTagy se od QR kódů liší svými návrhovými cíli. QR kód je vytvořen tak, aby zakódoval libovolná data do jediného hustého symbolu, který uživatel přečte jednou zblízka. AprilTag je vytvořen tak, aby zakódoval malé ID do řídkého symbolu, který kamera čte nepřetržitě z dálky, s tak velkou tolerancí chyb, jakou umožňuje Hammingův kód jeho rodiny. Tento kompromis se projevuje v obou směrech: QR kód může nést stovky bajtů, ale musí být čten zblízka; AprilTag nese jen několik stovek jedinečných ID, ale čte se spolehlivě z metrů daleko.
Klíčové slovo families přijímá bitovou masku rodin tagů k dekódování. Dostupné rodiny jsou image.TAG16H5, image.TAG25H9, image.TAG36H10, image.TAG36H11, image.TAGCIRCLE21H7, image.TAGCIRCLE49H12, image.TAGCUSTOM48H12, image.TAGSTANDARD41H12 a image.TAGSTANDARD52H13. Každá rodina představuje kompromis mezi počtem ID a robustností. Číslo H v názvu je minimální Hammingova vzdálenost mezi libovolnými dvěma kódy v rodině – kolik bitů se musí změnit, než se z jednoho platného kódu stane jiný – TAG16H5 má 30 ID při vzdálenosti 5, TAG25H9 má 35 ID při vzdálenosti 9 a TAG36H11 (výchozí a nejběžnější) má 587 ID při vzdálenosti 11. Detektor opravuje až dvě bitové chyby bez ohledu na rodinu, takže vzdálenost rozhoduje o tom, jak riskantní tato oprava je: náhodný vzor v zašuměném snímku stačí, aby se dostal do vzdálenosti dvou bitů od platného kódu, a dekóduje se jako falešná detekce, a rodiny s vyšší vzdáleností rozkládají své kódy mnohem řidčeji, takže takové kolize se stávají vzácnými – proto je TAG36H11 doporučenou volbou. Doba detekce roste s počtem povolených rodin, takže aplikace povoluje jen to, co skutečně tiskne. Bitová maska je bitový OR konstant rodin, když je v jednom volání potřeba více rodin.
Každá detekce nese slovník ohraničujícího rámečku – x, y, w, h, rect, area, celočíselné a subpixelové těžiště (cx, cy, cxf, cyf) – a čtyři nalezené rohy (corners). Následují identifikační pole: id je číselné ID v rámci rodiny (0 – 586 pro TAG36H11), family je číselná konstanta rodiny a name je název rodiny jako řetězec.
Pole kvality shody jsou to, co aplikace používá k filtrování detekcí. decision_margin je skóre spolehlivosti 0.0 – 1.0; vyšší je lepší a odfiltrování detekcí pod decision_margin > 0.1 zbaví bez nákladů většiny falešných nálezů. hamming počítá bitové chyby, které dekodér pro tento tag přijal – nižší je lepší, 0 znamená dokonalé dekódování. goodness je historická metrika kvality obrazu, kterou současný dekodér již nepočítá; je vždy 0.0 a lze ji ignorovat.
5.28.3. Póza z vnitřních parametrů¶
Přelomovou funkcí find_apriltags(), tou, která ospravedlňuje AprilTagy jako fiduciální značku volby v robotice, je, že metoda dokáže obnovit pózu tagu se 6 stupni volnosti v souřadnicích kamery přímo z nalezených rohů a malé sady kalibračních vnitřních parametrů. Vnitřní parametry jsou ohnisková vzdálenost kamery v ose X a Y v pixelech (fx, fy) a optický střed v pixelech (cx, cy), přičemž všechny čtyři aplikace jednou změří kalibračním postupem a poté je natvrdo zakóduje.
Když jsou vnitřní parametry dodány, vrácený objekt AprilTag naplní svá pole x_translation, y_translation, z_translation pozicí tagu vzhledem ke kameře a x_rotation, y_rotation, z_rotation (a duplicitní rotation pro symetrii) orientací tagu. Bez vnitřních parametrů je všech šest polí 0.0 a aplikace je zodpovědná za jakýkoli odhad pózy, který potřebuje.
Translační pole jsou hlášena v šířkách tagu: dekodér považuje tag za 1 jednotku široký, takže aplikace vynásobí každou translaci fyzickou šířkou vytištěného tagu, aby získala metrické vzdálenosti. Tag vytištěný o šířce 100 mm a hlásící z_translation = 8.3 je 830 mm od kamery; stejný tag vytištěný o šířce 50 mm ve stejné vzdálenosti by hlásil z_translation = 16.6. Rotační pole jsou v radiánech a nepotřebují žádné škálování.
Odhad pózy je základem pro širokou škálu robotických aplikací: dokování robota k nabíjecí stanici označené tagem, sledování vytištěné trasy s navigačními body, obnovení vlastní pózy kamery z více známých tagů v prostředí. Kamera, která zná vnitřní parametry, vidí tag a má pro tag pozici v reálném světě, má stejným výpočtem i pozici sebe sama v reálném světě.
5.28.4. Kdy zvolit který¶
QR kódy a AprilTagy řeší různé problémy. Volba mezi nimi se odvíjí od toho, co vytištěný symbol nese.
Když aplikace potřebuje vytištěným symbolem nést libovolná data – URL, řetězec sériového čísla, kontaktní záznam – je QR kód tou správnou volbou. Stovky bajtů se vejdou do kódu skromné velikosti, kódování je veřejné a podporované na každém smartphonu a dekodér si poradí s rotací, mírným poškozením a šikmými úhly.
Když aplikace potřebuje malé ID čtené nepřetržitě z dálky s volitelnou pózou – fiduciální značku na pohybujícím se robotovi, kalibrační terč v místnosti, dokovací značku na nabíjecí stanici – je AprilTag tou správnou volbou. Stovky ID jsou pro daný účel více než dostatečné, Hammingův kód se zotaví z bitových chyb, které by porazily QR kód, a odhad pózy je zdarma, jakmile jsou vnitřní parametry zkalibrovány.
Některé aplikace používají obojí: AprilTag značí známé místo a přidružený QR kód (vytištěný vedle) nese metadata o tom, co toto místo znamená. Oba detektory běží na stejném snímku nezávisle a aplikace koreluje jejich ohraničující rámečky, aby přiřadila každý tag k jeho doprovodnému kódu.