5.28. QR-koodit ja AprilTag-merkit

Tähän mennessä käsitellyt tunnistimet – blobit, viivat, ympyrät, suorakulmiot – löytävät geometrisia piirteitä: sijainteja ja ääriviivoja, joita myöhempi vaihe tulkitsee. Loput tunnistimet löytävät symbolisia piirteitä: painettuja kuvioita, joiden visuaalinen rakenne on olemassa nimenomaan hyötykuorman koodaamiseksi. Kamera paikantaa ne, dekooderi lukee bitit, ja takaisin saadaan sijainnin sijasta merkkijono (tai tunniste), jonka symbolin painaja on tarkoituksella valinnut.

Kaksi tällaista perhettä hallitsee pienten kameroiden sovelluksia. QR-koodit kantavat mielivaltaista tekstiä, URL-osoitteita, yhteystietokortteja tai binääristä hyötykuormaa – kuluttajille suunnatut 2D-koodit, joita esiintyy julisteissa, pakkauksissa ja tarttuvissa korteissa. AprilTag-merkit kantavat yksittäisen numeerisen tunnisteen pienestä kiinteästä joukosta, dekoodautuvat nopeasti jopa pitkän matkan päästä ja (kun linssin sisäiset parametrit annetaan) raportoivat 6-DoF-asennon kamerakehyksessä – robotiikkaan suunnatut 2D-koodit, jotka merkitsevät droneja, kalibrointikohteita ja kiintopisteitä. Molemmat tunnistimet palauttavat tulosobjekteja, joilla on sama rajauslaatikkosanasto kuin blob- ja suorakulmiotunnistimilla, mutta hyötykuorma tekee niistä aidosti erilaisia verrattuna kaikkeen tähän mennessä käsiteltyyn.

5.28.1. QR-koodit

find_qrcodes() skannaa kehyksestä QR-koodit ja palauttaa listan QRCode -tulosobjekteja:

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)

Tunnistin ottaa yhden valinnaisen roi -parametrin haun rajaamiseksi. Se tarvitsee harmaasävysyötteen – värikehys muunnetaan sisäisesti ennen dekoodausta.

Jokainen tunnistus kantaa rajauslaatikon (x, y, w, h, rect), neljä tunnistettua kulmaa (corners, projektiivinen nelikulmio, jonka QR-koodin hakukuviot piirtävät) sekä dekoodatun hyötykuorman merkkijonona. Kulmat ovat oikea asia piirrettäväksi tunnistusta merkittäessä – vinosti katsottu QR-koodi ei ole akselien suuntainen, ja rajauslaatikko antaa vain väljän ääriviivan.

Dekooderin metatiedot kattavat kaiken, mitä QR-dekooderi sai matkan varrella selville. version on QR-koodin versio, 1 – 40, joka määrää moduuliruudukon koon (version 1 koodi on 21 moduulia leveä, version 40 koodi 177). ecc_level on virheenkorjaustaso (0 – 3 vastaten L / M / Q / H); korkeammat tasot varaavat enemmän koodisanoja virheenkorjaukseen ja kestävät enemmän vahinkoa vähemmän hyötykuormatilan kustannuksella. mask on maskikuvio (0 – 7), jonka enkooderi valitsi minimoidakseen dekooderin sekaannuksen. data_type on dekooderin raportoima koodaus – numeerinen, aakkosnumeerinen, binääri tai Kanji – ja liput is_numeric / is_alphanumeric / is_binary / is_kanji paljastavat saman arvon ystävällisempinä totuusarvoina.

eci on Extended Channel Interpretation -arvo, joka kertoo, missä tekstikoodauksessa tavut ovat (UTF-8, ISO-8859-1 ja niin edelleen). Mielivaltaisesta painetusta materiaalista peräisin oleva QR-koodi ei välttämättä ole taatusti UTF-8; sovellus, jonka on dekoodattava tavut oikein, tarkistaa eci -arvon ja dekoodaa sen mukaisesti. Erityisesti Kanji-tapaus: MicroPython ei jäsennä Kanji-koodausta, joten is_kanji -hyötykuormaa on käsiteltävä tavutaulukkona ja sovelluksen on dekoodattava se.

Tyypillinen käyttö: kamera lukee QR-koodit kuljettimelta ja raportoi dekoodatun hyötykuorman isäntälaitteelle. Kamera ajaa find_qrcodes() kerran kehystä kohden, käy läpi palautetun listan, valitsee koodit, joiden data_type vastaa sovelluksen odotuksia, ja välittää c.payload UART:n tai USB:n kautta. Rajauslaatikko- ja kulmadata ovat hyödyllisiä IDE:n esikatselussa, mutta eivät ole se, mistä isäntälaite välittää.

5.28.2. AprilTag-merkit

find_apriltags() skannaa kehyksestä AprilTag-merkit ja palauttaa listan AprilTag -tulosobjekteja:

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)

AprilTag-merkit eroavat QR-koodeista suunnittelutavoitteiltaan. QR-koodi on rakennettu koodaamaan mielivaltaista dataa yhteen tiheään symboliin, jonka käyttäjä lukee kerran läheltä. AprilTag on rakennettu koodaamaan pieni tunniste harvaan symboliin, jonka kamera lukee jatkuvasti etäältä, niin suurella virheensietokyvyllä kuin sen perheen Hamming-koodi sallii. Kompromissi näkyy molempiin suuntiin: QR-koodi voi kantaa satoja tavuja mutta se on luettava läheltä; AprilTag kantaa vain muutaman sadan ainutkertaisen tunnisteen mutta luetaan luotettavasti metrien päästä.

families -avainsana ottaa bittimaskin dekoodattavista merkkiperheistä. Saatavilla olevat perheet ovat image.TAG16H5, image.TAG25H9, image.TAG36H10, image.TAG36H11, image.TAGCIRCLE21H7, image.TAGCIRCLE49H12, image.TAGCUSTOM48H12, image.TAGSTANDARD41H12 ja image.TAGSTANDARD52H13. Jokainen perhe tasapainottaa tunnisteiden lukumäärän ja kestävyyden välillä. Nimessä oleva H -luku on pienin Hamming-etäisyys minkä tahansa kahden perheen koodin välillä – kuinka monen bitin on vaihduttava ennen kuin yksi kelvollinen koodi muuttuu toiseksi – TAG16H5 -perheessä on 30 tunnistetta etäisyydellä 5, TAG25H9 -perheessä on 35 tunnistetta etäisyydellä 9, ja TAG36H11 -perheessä (oletus ja yleisin) on 587 tunnistetta etäisyydellä 11. Tunnistin korjaa enintään kaksi bittivirhettä perheestä riippumatta, joten etäisyys ratkaisee, kuinka riskialtis tuo korjaus on: satunnaisen kuvion kohinaisessa kehyksessä tarvitsee osua vain kahden bitin sisään kelvollisesta koodista dekoodautuakseen virheellisenä tunnistuksena, ja suuremman etäisyyden perheet levittävät koodinsa niin paljon harvempaan, että tällaiset törmäykset käyvät harvinaisiksi – syy siihen, miksi TAG36H11 on suositeltu valinta. Tunnistusaika kasvaa käytössä olevien perheiden määrän mukaan, joten sovellus ottaa käyttöön vain sen, mitä se tosiasiassa tulostaa. Bittimaski on perhevakioiden bittikohtainen OR, kun yhdessä kutsussa tarvitaan useita perheitä.

Jokainen tunnistus kantaa rajauslaatikkosanaston – x, y, w, h, rect, area, kokonaisluku- ja alipikselikeskipisteet (cx, cy, cxf, cyf) – sekä neljä tunnistettua kulmaa (corners). Tunnistuskentät seuraavat: id on numeerinen tunniste perheen sisällä (0 – 586 TAG36H11 -perheelle), family on numeerinen perhevakio, ja name on perheen nimi merkkijonona.

Vastaavuuden laatua kuvaavat kentät ovat ne, joita sovellus käyttää tunnistusten suodattamiseen. decision_margin on luottamuspisteytys välillä 0.0 – 1.0; suurempi on parempi, ja tunnistusten suodattaminen ehdolla decision_margin > 0.1 poistaa useimmat virheelliset osumat ilman kustannuksia. hamming laskee bittivirheet, jotka dekooderi hyväksyi tälle merkille – pienempi on parempi, 0 tarkoittaa täydellistä dekoodausta. goodness on historiallinen kuvanlaatumittari, jota nykyinen dekooderi ei enää laske; se on aina 0.0 ja sen voi jättää huomiotta.

5.28.3. Asento sisäisistä parametreista

find_apriltags() -menetelmän mullistava ominaisuus, se joka oikeuttaa AprilTag-merkit ensisijaiseksi robotiikan kiintopistevalinnaksi, on se, että menetelmä voi palauttaa merkin 6-DoF-asennon kamerakehyksessä suoraan tunnistetuista kulmista ja pienestä joukosta kalibroinnin sisäisiä parametreja. Sisäiset parametrit ovat kameran X- ja Y-polttovälit pikseleinä (fx, fy) ja optinen keskipiste pikseleinä (cx, cy), jotka kaikki neljä sovellus mittaa kerran kalibrointimenettelyllä ja koodaa sen jälkeen kiinteästi.

Kun sisäiset parametrit annetaan, palautettu AprilTag täyttää kentät x_translation, y_translation, z_translation merkin sijainnilla suhteessa kameraan, ja kentät x_rotation, y_rotation, z_rotation (sekä symmetrian vuoksi kaksoiskenttä rotation) merkin orientaatiolla. Ilman sisäisiä parametreja kaikki kuusi kenttää ovat 0.0 ja sovellus on vastuussa tarvitsemastaan asennon arvioinnista.

Siirtymäkentät raportoidaan merkin leveyksinä: dekooderi käsittelee merkkiä 1 yksikön levyisenä, joten sovellus kertoo kunkin siirtymän painetun merkin fyysisellä leveydellä saadakseen metriset etäisyydet. Merkki, joka on painettu 100 mm leveäksi ja joka raportoi z_translation = 8.3, on 830 mm:n päässä kamerasta; sama merkki painettuna 50 mm leveäksi samalla etäisyydellä raportoisi z_translation = 16.6. Kiertokentät ovat radiaaneina eivätkä tarvitse skaalausta.

Asennon arvio on perusta laajalle joukolle robotiikkasovelluksia: robotin telakointi merkillä merkittyyn latausasemaan, painetun reittipistejäljen seuraaminen, kameran oman asennon palauttaminen useista ympäristön tunnetuista merkeistä. Kameralla, joka tuntee sisäiset parametrit, näkee merkin ja jolla on merkille tosielämän sijainti, on samalla laskutoimituksella tosielämän sijainti itselleen.

5.28.4. Milloin valita kumpi

QR-koodit ja AprilTag-merkit ratkaisevat erilaisia ongelmia. Valinta niiden välillä riippuu siitä, mitä painettu symboli kantaa.

Kun sovelluksen on kannettava mielivaltaista dataa painetun symbolin kautta – URL-osoite, sarjanumeromerkkijono, yhteystietue – QR-koodi on oikea valinta. Satoja tavuja mahtuu kohtuullisen kokoiseen koodiin, koodaus on julkinen ja tuettu jokaisessa älypuhelimessa, ja dekooderi selviää kierrosta, kohtuullisesta vahingosta ja vinoista kulmista.

Kun sovellus tarvitsee pienen tunnisteen, joka luetaan jatkuvasti etäältä valinnaisen asennon kanssa – kiintopiste liikkuvassa robotissa, kalibrointikohde huoneessa, telakointimerkki latausasemassa – AprilTag on oikea valinta. Sadat tunnisteet riittävät käyttötarkoitukseen mainiosti, Hamming-koodi palautuu bittivirheistä, jotka kaataisivat QR-koodin, ja asennon arvio tulee ilmaiseksi, kun sisäiset parametrit on kalibroitu.

Jotkin sovellukset käyttävät molempia: AprilTag merkitsee tunnetun sijainnin ja siihen liittyvä QR-koodi (painettuna sen viereen) kantaa metatiedot siitä, mitä tuo sijainti tarkoittaa. Kaksi tunnistinta ajetaan toisistaan riippumatta samalle kehykselle, ja sovellus korreloi niiden rajauslaatikot yhdistääkseen kunkin merkin sen toverikoodiin.