5.29. Vonalkódok és Data Matrix kódok

Két további kódcsalád egészíti ki a kamera dekódolóit. Az egydimenziós vonalkódok – a gabonapelyhes doboz oldalán lévő csíkok, egy kórházi karszalag, egy szállítási címke – a legrégebbi gépileg olvasható szimbólumok, amelyek még mindennapi használatban vannak. A Data Matrix kódok a QR-kódokhoz hasonlóan kétdimenziósak, de azonos hasznosadat-méret mellett sűrűbbek, és az ipari jelölésre irányulnak – az áramköri lapra lézerrel maratott gyártói jelölés, nem pedig a falon lévő poszter. Az image modulnak mindegyikhez külön dekódolója van, amelyek lefedik azokat az ipari, kiskereskedelmi és készletkezelési alkalmazásokat, amelyeket a fogyasztói 2D-kódok soha nem értek el igazán.

5.29.1. 1D vonalkódok

Egy egydimenziós vonalkód a hasznos adatot változó szélességű, függőleges sávok sorozataként kódolja, amelyeket balról jobbra (vagy függőlegesen tájolt kódok esetén fentről lefelé) olvasnak le. A szélességek egy kis értékkészlet egyikére kvantálódnak, és a szélességek sorozata olyan karaktereket betűz ki, amilyeneket a nyomtató által választott szimbolika megenged: numerikus egy UPC termékkódhoz, alfanumerikus egy raktári alkatrészszámhoz, vagy tetszőleges szöveg egy Code 128 címkéhez.

A find_barcodes() átvizsgálja a képkockát 1D vonalkódok után a támogatott szimbolikák bármelyikében, és BarCode eredményobjektumok listáját adja vissza:

codes = img.find_barcodes()

for c in codes:
    img.draw_rectangle(c.rect, color=(0, 255, 0))
    print(c.payload, c.type, c.quality)

A dekódoló egyetlen hívásban vízszintesen és függőlegesen is átvizsgálja a képkockát, így a bármilyen szögben nyomtatott vonalkód egyetlen menetben megtalálható anélkül, hogy az alkalmazásnak el kellene forgatnia a bemenetet. A roi korlátozza a keresést; nincsenek más hangolási paraméterek – a dekódoló önállóan működik.

A támogatott szimbolikák lefedik a gyakori fogyasztói és ipari családokat. A kiskereskedelmi készlet a image.EAN2, image.EAN5, image.EAN8, image.UPCE, image.UPCA, image.EAN13 (a legtöbb fogyasztói csomagoláson lévő numerikus, rögzített hosszúságú kódok), image.ISBN10 és image.ISBN13 (ugyanazok a családok könyvekhez újrahasznosítva). Az általános célú készlet a image.I25 (Interleaved 2 of 5, gyakori a szállítási címkéken), a image.CODABAR (könyvtárakban és vérbankokban használt), a image.CODE39, a image.CODE93 és a image.CODE128 (változó hosszúságú alfanumerikus szimbolikák tetszőleges szöveghez). A polcél-családot a image.DATABAR (RSS-14) és a image.DATABAR_EXP (RSS-Expanded) egészíti ki a listán.

Minden észlelés hordozza a határoló doboz szókészletét – x, y, w, h, rect, corners – és a dekódolt payload értéket karakterláncként. A type a fenti listából származó szimbolika-állandó, amelyet egy alkalmazás akkor ellenőriz, amikor kifejezetten az érdekli, melyik családot dekódolta (pl. csak az EAN13 elfogadása egy élelmiszerbolti szkenner alkalmazásnál).

A szűréshez két mező számít: a rotation és a quality. A rotation a vonalkód képsíkon belüli szöge radiánban: a dekódoló megbirkózik a tetszőleges elforgatásokkal, de az észlelést tisztán megjeleníteni kívánó utófeldolgozó kód kiszűrhet bizonyos küszöbértéken túl megdöntve visszaadott kódokat.

A quality a dekódolásszám: azon pásztázósorok száma, amelyek sikeresen dekódolták ugyanazt a hasznos adatot. A dekódoló átfut a képkocka minden során (és oszlopán), amely metszi a vonalkódot, és növeli a számlálót minden alkalommal, amikor a dekódolás sikerül. Egy éles fókuszban és jó megvilágításban nyomtatott vonalkód quality értéke tízes nagyságrendű; egy részben takart vagy elkenődött vonalkód lehet, hogy csak egy-két pásztázósoron dekódolódik, és 1 – 2 quality értéket jelent. A quality > 5 alatti észlelések kiszűrése az átmeneti, egyetlen pásztázósoros hibás dekódolásokat dobja el a valódi észlelések sérülése nélkül.

Egy 1D vonalkód-alkalmazás kicsi. Rögzíts egy képkockát, hívd meg a find_barcodes() metódust, járd be a visszaadott listát, szűrj a c.type és a c.quality alapján, és továbbítsd a c.payload értéket UART-on vagy USB-n keresztül bármilyen utófeldolgozó szakasznak, amely naplózza vagy beolvassa a beolvasott kódot.

5.29.2. Data Matrix

Egy Data Matrix kód egy 2D szimbólum, amely a hasznos adatát fekete és fehér cellák rácsaként kódolja, ahogyan azt egy QR-kód teszi. Két gyakorlati szempontból különbözik a QR-kódtól: azonos hasznosadat-méret mellett kisebb (a kódolás sűrűbb), és inkább ipari használatra, mintsem fogyasztói használatra irányul (ahol a QR-kódok dominálnak). A gyári padlón fémalkatrészekbe lézerrel maratott minták, az integrált áramköri tokokra nyomtatott címkék, az orvosi fecskendőkre helyezett jelölések – mindezek jellemzően Data Matrix kódok, nem QR-kódok.

A find_datamatrices() átvizsgálja a képkockát Data Matrix kódok után, és DataMatrix eredményobjektumok listáját adja vissza:

codes = img.find_datamatrices()

for c in codes:
    img.draw_rectangle(c.rect, color=(0, 255, 0))
    print(c.payload, c.rows, c.columns)

A roi a szokásos módon korlátozza a keresést. Az egyetlen dekódoló-specifikus hangolási szabályozó az effort, egy egész szám, amely azt vezérli, milyen keményen dolgozik a dekódoló, hogy egyezést találjon. A magasabb értékek javítják a halvány, sérült vagy ferde kódok észlelését a képkockasebesség rovására; az alacsonyabb értékek gyorsabban futnak, de elmulaszthatnak olyan kódokat, amelyeket a magasabb erőfeszítés megtalált volna. A nagyjából 160 alatti értékek gyakorlatilag nem észlelnek; a nagyjából 240 feletti értékek egyre kevesebbet javítanak. A 200-as alapérték ésszerű egyensúly egy tiszta képhez, és egy új alkalmazás megfelelő kiindulópontja az alapérték plusz vagy mínusz 20, attól függően, hogy a célok tiszták (alacsonyabb) vagy sérültek (magasabb).

Minden észlelés hordozza a határoló doboz szókészletét és a négy észlelt sarkot, a dekódolt payload értéket, valamint a képsíkon belüli rotation értéket radiánban. Az elrendezés-metaadatok leírják a dekódoló által beolvasott szimbólum méretét és sűrűségét: a rows és a columns az adatrács cellaszáma; a capacity az adott méreten a szimbólum által hordozható hasznosadat-karakterek maximális száma; a padding az, hogy hány ilyen hely maradt kihasználatlan (capacity - len(payload)).

Az elrendezési mezők hasznosak azoknak az alkalmazásoknak, amelyeknek egy maratott jelölés formátumát kell érvényesíteniük, nem pedig a tartalmát. Egy alkatrészkövető rendszer megkövetelheti, hogy minden jelölés 12x12-es kód legyen, legfeljebb két kitöltőkarakterrel; egy olyan észlelés, amely 8x8-asként jött vissza (a specifikáció által megköveteltnél kisebb szimbólum), vagy 10 kitöltőkarakterrel (többségében üres), újrajelölésre lesz megjelölve.

5.29.3. Mikor melyiket válaszd

Ahol a QR kontra AprilTag a hasznos adat típusán múlt (tetszőleges adat kontra kis azonosító), ott a vonalkódok kontra Data Matrix kódok a fizikai sűrűségen és az iparágon múlnak.

Amikor az alkalmazás fogyasztóknak szól, és a kódok már léteznek a terepen – élelmiszerek, könyvek, szállítási címkék, könyvtári könyvek –, akkor a megfelelő detektor a find_barcodes(). Azokat a kódokat, amelyeket az alkalmazás olvas, egy másik rendszer számára nyomtatták, hogy az olvassa, és a szabványosított kiskereskedelmi szimbolikák azok, amelyeket az a rendszer várt.

Amikor az alkalmazás ipari, és a kódokat az alkalmazás számára nyomtatják – készletkövetés egy gyári padlón, alkatrészekbe maratott tételszámok, orvostechnikai eszközökön lévő nyomon követhetőségi jelölések –, akkor a megfelelő detektor a find_datamatrices() vagy a find_qrcodes(), attól függően, hogy az alkalmazásnak a Data Matrix nagyobb sűrűségére vagy a QR szélesebb eszköztámogatására van-e szüksége.

Néhány alkalmazás mind a négy detektort egyetlen folyamatban keveri. Egy csomagellenőrző kamera futtathat egy find_barcodes() menetet a nyomtatott UPC-hez, egy find_qrcodes() menetet ugyanazon a dobozon lévő szállítási QR-kódhoz, és egy find_datamatrices() menetet egy maratott alkatrészkódhoz, mindezt ugyanazon a rögzített képkockán; a három eredménylistát a határoló doboz pozíciója alapján korrelálják, és egyetlen észlelési rekordként jelentik. Minden detektor költsége hozzáadódik, így az ezt végző alkalmazások jellemzően egy megfelelő roi paraméterrel szűkítik le az egyes meneteket, ahelyett, hogy minden kódfajtáért átvizsgálnák a teljes képkockát.