5.29. บาร์โค้ดและรหัส Data Matrix

ตระกูลรหัสอีกสองตระกูลทำให้ตัวถอดรหัสของกล้องครบสมบูรณ์ บาร์โค้ดแบบหนึ่งมิติ -- เส้นบนข้างกล่องซีเรียล สายรัดข้อมือในโรงพยาบาล ป้ายขนส่ง -- เป็นสัญลักษณ์ที่เครื่องอ่านได้ที่เก่าแก่ที่สุดที่ยังใช้งานในชีวิตประจำวัน Data Matrix เป็นแบบสองมิติเหมือน QR code แต่หนาแน่นกว่าที่ขนาด payload เดียวกันและมุ่งเน้นการทำเครื่องหมายในอุตสาหกรรม -- เครื่องหมายของผู้ผลิตที่แกะสลักด้วยเลเซอร์บนแผงวงจร ไม่ใช่โปสเตอร์บนผนัง โมดูล image มีตัวถอดรหัสเฉพาะสำหรับแต่ละอย่าง ครอบคลุมแอปพลิเคชันด้านอุตสาหกรรม ค้าปลีก และคลังสินค้าที่รหัส 2D สำหรับผู้บริโภคไม่เคยเข้าถึงได้อย่างแท้จริง

5.29.1. บาร์โค้ด 1D

บาร์โค้ด แบบหนึ่งมิติ เข้ารหัส payload เป็นลำดับแถบแนวตั้งที่มีความกว้างต่างกัน อ่านจากซ้ายไปขวา (หรือจากบนลงล่างสำหรับรหัสแนวตั้ง) ความกว้างจะแบ่งเป็นหนึ่งในชุดค่าเล็ก ๆ และลำดับความกว้างสะกดตัวอักษรใน symbology ที่เครื่องพิมพ์เลือก: ตัวเลขสำหรับรหัสสินค้า UPC ตัวอักษรผสมตัวเลขสำหรับหมายเลขชิ้นส่วนในคลังสินค้า หรือข้อความอิสระสำหรับป้าย Code 128

find_barcodes() สแกนเฟรมหาบาร์โค้ด 1D ใน symbology ที่รองรับทั้งหมดและส่งคืนรายการของออบเจกต์ผลลัพธ์ BarCode:

codes = img.find_barcodes()

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

ตัวถอดรหัสสแกนทั้งแนวนอนและแนวตั้งตลอดเฟรมในการเรียกครั้งเดียว ดังนั้นบาร์โค้ดที่พิมพ์ในมุมใด ๆ จะพบได้ในรอบเดียวโดยไม่ต้องให้แอปพลิเคชันหมุนอินพุต roi จำกัดการค้นหา; ไม่มีพารามิเตอร์การปรับแต่งอื่น -- ตัวถอดรหัสครบในตัว

Symbologies ที่รองรับครอบคลุมตระกูลผู้บริโภคและอุตสาหกรรมทั่วไป ชุดค้าปลีกได้แก่ image.EAN2, image.EAN5, image.EAN8, image.UPCE, image.UPCA, image.EAN13 (รหัสตัวเลขความยาวคงที่บนบรรจุภัณฑ์ผู้บริโภคส่วนใหญ่), image.ISBN10 และ image.ISBN13 (ตระกูลเดียวกันนำมาใช้ใหม่สำหรับหนังสือ) ชุดวัตถุประสงค์ทั่วไปได้แก่ image.I25 (Interleaved 2 of 5 ที่พบบ่อยในป้ายขนส่ง), image.CODABAR (ใช้ในห้องสมุดและธนาคารเลือด), image.CODE39, image.CODE93 และ image.CODE128 (symbologies ตัวอักษรผสมตัวเลขความยาวแปรผันสำหรับข้อความอิสระ) ตระกูลขอบชั้นวาง image.DATABAR (RSS-14) และ image.DATABAR_EXP (RSS-Expanded) ปิดท้ายรายการ

การตรวจจับแต่ละรายการมีคำศัพท์ bounding box -- x, y, w, h, rect, corners -- และ payload ที่ถอดรหัสแล้วเป็นสตริง type คือค่าคงที่ symbology จากรายการข้างต้น ซึ่งแอปพลิเคชันตรวจสอบเมื่อสนใจโดยเฉพาะว่าตระกูลใดถูกถอดรหัส (เช่น ยอมรับเฉพาะ EAN13 สำหรับแอปพลิเคชันเครื่องสแกนร้านขายของชำ)

สองฟิลด์ที่สำคัญสำหรับการกรองคือ rotation และ quality rotation คือมุมในระนาบภาพของบาร์โค้ดในหน่วยเรเดียน: ตัวถอดรหัสรับมือกับการหมุนในแนวต่าง ๆ ได้ แต่โค้ดปลายทางที่ต้องการแสดงการตรวจจับอย่างสะอาดตาอาจต้องการกรองรหัสที่ส่งคืนมาในมุมเอียงเกินค่าขีดแบ่งบางค่า

quality คือจำนวนการถอดรหัส: จำนวน scanlines ที่ถอดรหัส payload เดียวกันได้สำเร็จ ตัวถอดรหัสทำงานตลอดทุกแถว (และคอลัมน์) ของเฟรมที่ตัดผ่านบาร์โค้ด และเพิ่มตัวนับทุกครั้งที่การถอดรหัสสำเร็จ บาร์โค้ดที่พิมพ์ชัดเจนและมีแสงสว่างดีจะให้ quality ระดับสิบ; บาร์โค้ดที่ถูกบดบังบางส่วนหรือเลือนลางอาจถอดรหัสได้เพียงหนึ่งหรือสอง scanlines และรายงาน quality เป็น 1 -- 2 การกรองการตรวจจับที่ต่ำกว่า quality > 5 ออกจะตัดการถอดรหัสผิดพลาดแบบ scanline เดียวชั่วคราวโดยไม่มีต้นทุนกับการตรวจจับที่แท้จริง

แอปพลิเคชันบาร์โค้ด 1D นั้นเล็กน้อย ถ่ายเฟรม เรียก find_barcodes() วนซ้ำรายการที่ส่งคืน กรองตาม c.type และ c.quality และส่งต่อ c.payload ผ่าน UART หรือ USB ไปยังขั้นตอนปลายทางที่บันทึกหรือนับการสแกน

5.29.2. Data Matrix

รหัส Data Matrix เป็นสัญลักษณ์ 2D ที่เข้ารหัส payload เป็นตารางเซลล์ดำและขาว เหมือนกับที่ QR code ทำ มันแตกต่างจาก QR code ในสองประเด็นปฏิบัติ: มัน เล็กกว่า ที่ขนาด payload เดียวกัน (การเข้ารหัสหนาแน่นกว่า) และมุ่งเน้นการใช้งาน อุตสาหกรรม ไม่ใช่การใช้งานของผู้บริโภค (ที่ QR code ครองตลาด) รูปแบบที่แกะสลักด้วยเลเซอร์บนชิ้นส่วนโลหะในโรงงาน ป้ายที่พิมพ์บนบรรจุภัณฑ์วงจรรวม เครื่องหมายที่วางบนกระบอกฉีดยา -- ทั้งหมดนั้นมักเป็น Data Matrix ไม่ใช่ QR code

find_datamatrices() สแกนเฟรมหารหัส Data Matrix และส่งคืนรายการของออบเจกต์ผลลัพธ์ DataMatrix:

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 จำกัดการค้นหาตามปกติ ปุ่มปรับแต่งเฉพาะของตัวถอดรหัสคือ effort ซึ่งเป็นจำนวนเต็มที่ควบคุมความพยายามของตัวถอดรหัสในการหาการจับคู่ ค่าที่สูงกว่าปรับปรุงการตรวจจับรหัสที่ลางเลือน เสียหาย หรือเอียงโดยแลกกับอัตราเฟรม; ค่าที่ต่ำกว่าทำงานเร็วกว่าแต่อาจพลาดรหัสที่ความพยายามสูงกว่าจะพบได้ ค่าที่ต่ำกว่าประมาณ 160 แทบจะล้มเหลวในการตรวจจับ; ค่าที่สูงกว่าประมาณ 240 ให้ผลตอบแทนที่ลดลง ค่าเริ่มต้นที่ 200 เป็นการสมดุลที่สมเหตุสมผลสำหรับภาพที่ชัดเจน และจุดเริ่มต้นที่เหมาะสมสำหรับแอปพลิเคชันใหม่คือค่าเริ่มต้นบวกหรือลบ 20 ขึ้นอยู่กับว่าเป้าหมายสะอาด (ต่ำกว่า) หรือเสื่อมสภาพ (สูงกว่า)

การตรวจจับแต่ละรายการมีคำศัพท์ bounding box และมุมสี่มุมที่ตรวจจับได้ payload ที่ถอดรหัสแล้ว และ rotation ในระนาบภาพในหน่วยเรเดียน เมตาดาตาเค้าโครง อธิบายขนาดและความหนาแน่นของสัญลักษณ์ที่ตัวถอดรหัสอ่าน: rows และ columns คือจำนวนเซลล์ของตารางข้อมูล; capacity คือจำนวนตัวอักษร payload สูงสุดที่สัญลักษณ์นั้นสามารถบรรจุได้ที่ขนาดนั้น; padding คือจำนวนช่องที่ไม่ได้ใช้ (capacity - len(payload))

ฟิลด์เค้าโครงมีประโยชน์สำหรับแอปพลิเคชันที่ต้องตรวจสอบ รูปแบบ ของเครื่องหมายที่แกะสลักไว้ ไม่ใช่เนื้อหา ระบบติดตามชิ้นส่วนอาจกำหนดให้เครื่องหมายทั้งหมดต้องเป็นรหัส 12x12 โดยมี padding ไม่เกินสองตัวอักษร; การตรวจจับที่ส่งคืนมาที่ 8x8 (สัญลักษณ์ที่เล็กกว่าที่สเปคกำหนด) หรือมี padding 10 ตัวอักษร (ว่างส่วนใหญ่) จะถูกตั้งค่าสถานะให้ทำเครื่องหมายใหม่

5.29.3. จะเลือกอะไรเมื่อไหร่

ที่ QR code เทียบกับ AprilTag ขึ้นอยู่กับ ชนิด payload (ข้อมูลตามอำเภอใจ เทียบกับ ID เล็ก ๆ) บาร์โค้ดเทียบกับรหัส Data Matrix ขึ้นอยู่กับ ความหนาแน่นทางกายภาพ และ อุตสาหกรรม

เมื่อแอปพลิเคชันหันหน้าสู่ผู้บริโภคและรหัสมีอยู่แล้วในสนาม -- ของชำ หนังสือ ป้ายขนส่ง หนังสือห้องสมุด -- ตัวตรวจจับที่ถูกต้องคือ find_barcodes() รหัสที่แอปพลิเคชันกำลังอ่านถูกพิมพ์ให้ระบบอื่นอ่าน และ symbologies ค้าปลีกมาตรฐานคือสิ่งที่ระบบนั้นคาดหวัง

เมื่อแอปพลิเคชันเป็นอุตสาหกรรมและรหัส กำลังถูกพิมพ์สำหรับแอปพลิเคชัน -- การติดตามสินค้าคงคลังบนพื้นโรงงาน รหัสล็อตที่แกะสลักบนชิ้นส่วน เครื่องหมายการติดตามย้อนกลับบนอุปกรณ์การแพทย์ -- ตัวตรวจจับที่ถูกต้องคือ find_datamatrices() หรือ find_qrcodes() ขึ้นอยู่กับว่าแอปพลิเคชันต้องการความหนาแน่นที่สูงกว่าของ Data Matrix หรือการสนับสนุนเครื่องมือที่กว้างกว่าของ QR

แอปพลิเคชันจำนวนน้อยผสมตัวตรวจจับทั้งสี่เข้าด้วยกันในไปป์ไลน์เดียว กล้องตรวจสอบแพ็คเกจอาจรันรอบ find_barcodes() สำหรับ UPC ที่พิมพ์ รอบ find_qrcodes() สำหรับ QR code ขนส่งบนกล่องเดียวกัน และรอบ find_datamatrices() สำหรับรหัสชิ้นส่วนที่แกะสลัก ทั้งหมดบนเฟรมที่ถ่ายเดียวกัน; รายการผลลัพธ์ทั้งสามถูกเชื่อมโยงตามตำแหน่ง bounding box และรายงานเป็นระเบียนการตรวจจับเดียว ต้นทุนของตัวตรวจจับแต่ละตัวสะสม ดังนั้นแอปพลิเคชันที่ทำเช่นนี้มักจะจำกัดแต่ละรอบด้วย roi ที่เหมาะสมแทนที่จะค้นหาเฟรมทั้งหมดสำหรับรหัสทุกประเภท