5.29. Barcodes en Data Matrix-codes¶
Twee nog meer codefamilies maken de decoders van de camera compleet. Eendimensionale barcodes – de strepen op de zijkant van een doos cornflakes, een ziekenhuispolsbandje, een verzendlabel – zijn de oudste machineleesbare symbolen die nog dagelijks in gebruik zijn. Data Matrix-codes zijn tweedimensionaal zoals QR Code, maar dichter bij dezelfde payloadgrootte en gericht op industriële markering – het fabrieksmerk dat met laser in een printplaat is geëtst in plaats van de poster aan een muur. De image-module heeft voor elk een speciale decoder, die de industriële, retail- en voorraadtoepassingen bestrijkt die de consumenten-2D-codes nooit helemaal hebben bereikt.
5.29.1. 1D-barcodes¶
Een eendimensionale barcode codeert zijn payload als een reeks verticale balken van wisselende breedtes, van links naar rechts gelezen (of van boven naar beneden voor verticaal georiënteerde codes). De breedtes kwantiseren naar één uit een kleine set waarden, en de reeks breedtes spelt tekens uit in welke symbologie de printer ook koos: numeriek voor een UPC-productcode, alfanumeriek voor een magazijnonderdeelnummer, of willekeurige tekst voor een Code 128-label.
find_barcodes() doorzoekt het frame op 1D-barcodes in een van de ondersteunde symbologieën en geeft een lijst van BarCode-resultaatobjecten terug:
codes = img.find_barcodes()
for c in codes:
img.draw_rectangle(c.rect, color=(0, 255, 0))
print(c.payload, c.type, c.quality)
De decoder scant zowel horizontaal als verticaal over het frame in een enkele aanroep, dus een barcode die onder elke hoek is afgedrukt wordt in één pas gevonden zonder dat de toepassing de invoer hoeft te roteren. roi beperkt het zoeken; er bestaan geen andere afstemparameters – de decoder is op zichzelf staand.
De ondersteunde symbologieën bestrijken de gangbare consumenten- en industriële families. De retailset is image.EAN2, image.EAN5, image.EAN8, image.UPCE, image.UPCA, image.EAN13 (de numerieke codes met vaste lengte op de meeste consumentenverpakkingen), image.ISBN10 en image.ISBN13 (dezelfde families hergebruikt voor boeken). De algemene set is image.I25 (Interleaved 2 of 5, gangbaar in verzendlabels), image.CODABAR (gebruikt in bibliotheken en bloedbanken), image.CODE39, image.CODE93 en image.CODE128 (alfanumerieke symbologieën met variabele lengte voor willekeurige tekst). De schaprandfamilie image.DATABAR (RSS-14) en image.DATABAR_EXP (RSS-Expanded) maken de lijst compleet.
Elke detectie draagt de vocabulaire van het begrenzingsvak – x, y, w, h, rect, corners – en de gedecodeerde payload als een string. type is de symbologieconstante uit de bovenstaande lijst, die een toepassing controleert wanneer het specifiek geeft om welke familie werd gedecodeerd (bijv. alleen EAN13 accepteren voor een toepassing met een kruidenierscanner).
De twee velden die ertoe doen voor filtering zijn rotation en quality. rotation is de hoek van de barcode in het beeldvlak in radialen: de decoder gaat om met willekeurige rotaties, maar downstream-code die de detectie netjes wil weergeven wil mogelijk codes uitfilteren die voorbij een bepaalde drempelwaarde gekanteld terugkomen.
quality is het decodeertal: het aantal scanlijnen dat met succes dezelfde payload heeft gedecodeerd. De decoder loopt over elke rij (en kolom) van het frame die de barcode snijdt, en verhoogt de teller telkens wanneer de decodering slaagt. Een afgedrukte barcode in scherpe focus en goed licht levert een quality in de tientallen op; een gedeeltelijk afgedekte of bevlekte barcode decodeert misschien op slechts één of twee scanlijnen en rapporteert een quality van 1 – 2. Het uitfilteren van detecties onder quality > 5 verwijdert vluchtige misdecoderingen op één enkele scanlijn zonder enige kosten voor de echte detecties.
Een toepassing met 1D-barcodes is klein. Leg een frame vast, roep find_barcodes() aan, doorloop de teruggegeven lijst, filter op c.type en c.quality, en stuur c.payload door via UART of USB naar welke downstream-fase de scan ook logt of aanslaat.
5.29.2. Data Matrix¶
Een Data Matrix-code is een 2D-symbool dat zijn payload codeert als een raster van zwarte en witte cellen, zoals een QR Code dat doet. Het verschilt in twee praktische opzichten van een QR Code: het is kleiner bij dezelfde payloadgrootte (de codering is dichter) en het is gericht op industrieel gebruik in plaats van consumentengebruik (waar QR Code domineert). De patronen die met laser in metalen onderdelen op een fabrieksvloer zijn geëtst, de labels die op behuizingen van geïntegreerde schakelingen zijn afgedrukt, de markeringen op medische injectiespuiten – dat zijn allemaal doorgaans Data Matrices, geen QR Codes.
find_datamatrices() doorzoekt het frame op Data Matrix-codes en geeft een lijst van DataMatrix-resultaatobjecten terug:
codes = img.find_datamatrices()
for c in codes:
img.draw_rectangle(c.rect, color=(0, 255, 0))
print(c.payload, c.rows, c.columns)
roi beperkt het zoeken op de gebruikelijke manier. De enige decoderspecifieke afstemknop is effort, een geheel getal dat bepaalt hoe hard de decoder werkt om een overeenkomst te vinden. Hogere waarden verbeteren de detectie van vage, beschadigde of schuine codes ten koste van de framerate; lagere waarden lopen sneller maar missen mogelijk codes die de hogere inspanning gevonden zou hebben. Waarden onder ongeveer 160 falen in feite om te detecteren; waarden boven ongeveer 240 geven afnemende meeropbrengsten. De standaard van 200 is een redelijke balans voor een heldere afbeelding, en het juiste startpunt voor een nieuwe toepassing is de standaard plus of min 20, afhankelijk van of de doelen schoon (lager) of beschadigd (hoger) zijn.
Elke detectie draagt de vocabulaire van het begrenzingsvak en de vier gedetecteerde hoeken, de gedecodeerde payload, en de rotation in het beeldvlak in radialen. De lay-outmetadata beschrijven de grootte en dichtheid van het symbool dat de decoder las: rows en columns zijn de celtellingen van het datarooster; capacity is het maximale aantal payloadtekens dat het symbool bij die grootte kon dragen; padding is hoeveel van die plekken ongebruikt bleven (capacity - len(payload)).
De lay-outvelden zijn nuttig voor toepassingen die de opmaak van een geëtste markering moeten valideren in plaats van de inhoud ervan. Een systeem voor onderdeelvolging zou kunnen vereisen dat alle markeringen 12-bij-12-codes zijn met ten hoogste twee paddingtekens; een detectie die terugkwam op 8-bij-8 (een kleiner symbool dan de specificatie vereist) of met 10 paddingtekens (grotendeels leeg) wordt gemarkeerd voor hermarkering.
5.29.3. Wanneer kies je welke¶
Waar QR versus AprilTag neerkwam op de aard van de payload (willekeurige data versus kleine ID), komen barcodes versus Data Matrix-codes neer op fysieke dichtheid en bedrijfstak.
Wanneer de toepassing consumentgericht is en de codes al in het veld bestaan – kruidenierswaren, boeken, verzendlabels, bibliotheekboeken – is de juiste detector find_barcodes(). De codes die de toepassing leest werden afgedrukt om door een ander systeem gelezen te worden, en de gestandaardiseerde retailsymbologieën zijn wat dat systeem verwachtte.
Wanneer de toepassing industrieel is en de codes worden afgedrukt voor de toepassing – voorraadvolging op een fabrieksvloer, partijcodes geëtst op onderdelen, traceerbaarheidsmarkeringen op medische apparaten – is de juiste detector find_datamatrices() of find_qrcodes(), afhankelijk van of de toepassing de hogere dichtheid van Data Matrix nodig heeft of de bredere gereedschapsondersteuning van QR.
Een handvol toepassingen mengt alle vier de detectoren in één pijplijn. Een cam voor pakketinspectie zou een pas met find_barcodes() kunnen uitvoeren voor de afgedrukte UPC, een pas met find_qrcodes() voor een verzend-QR-code op dezelfde doos, en een pas met find_datamatrices() voor een geëtste onderdeelcode, alles op hetzelfde vastgelegde frame; de drie resultaatlijsten worden gecorreleerd op positie van het begrenzingsvak en gerapporteerd als één detectierecord. De kosten van elke detector tellen op, dus toepassingen die dit doen versmallen doorgaans elke pas met een passende roi in plaats van het volledige frame te doorzoeken voor elk soort code.