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 ที่เหมาะสมแทนที่จะค้นหาเฟรมทั้งหมดสำหรับรหัสทุกประเภท