| import cv2 |
| import os |
| import re |
| import numpy as np |
|
|
| try: |
| import zxingcpp |
| _HAS_ZXING = True |
| except ImportError: |
| _HAS_ZXING = False |
|
|
| try: |
| from pyzbar.pyzbar import decode as pyzbar_decode |
| _HAS_PYZBAR = True |
| except ImportError: |
| _HAS_PYZBAR = False |
|
|
| PART_NUMBER_RE = re.compile(r'^0301BAB\d+N$') |
|
|
|
|
| def _filter_chassis(values): |
| for v in values: |
| if not v: |
| continue |
| tokens = v.split() |
| for token in tokens: |
| token = token.strip() |
| if token and not PART_NUMBER_RE.match(token): |
| return token |
| return None |
|
|
|
|
| def _decode_zxing(gray, thresh): |
| values = set() |
| for frame in [gray, thresh]: |
| try: |
| for r in zxingcpp.read_barcodes(frame): |
| text = r.text.strip() |
| if text: |
| values.add(text) |
| except Exception: |
| pass |
| return values |
|
|
|
|
| def _decode_pyzbar(img, thresh): |
| values = set() |
| for frame in [img, thresh]: |
| try: |
| for d in pyzbar_decode(frame): |
| text = d.data.decode("utf-8").strip() |
| if text: |
| values.add(text) |
| except Exception: |
| pass |
| return values |
|
|
|
|
| def scan_barcode(image_path): |
| img = cv2.imread(image_path) |
| if img is None: |
| return None |
|
|
| gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
| _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) |
|
|
| if _HAS_ZXING: |
| values = _decode_zxing(gray, thresh) |
| result = _filter_chassis(values) |
| if result: |
| return result |
|
|
| if _HAS_PYZBAR: |
| values = _decode_pyzbar(img, thresh) |
| result = _filter_chassis(values) |
| if result: |
| return result |
|
|
| return None |
|
|
|
|
| def scan_all_barcodes(barcode_dir): |
| results = {} |
| files = sorted([f for f in os.listdir(barcode_dir) |
| if f.lower().endswith(('.jpg', '.jpeg', '.png'))]) |
|
|
| print(f"Scanning {len(files)} barcode images...") |
| for fname in files: |
| path = os.path.join(barcode_dir, fname) |
| key = os.path.splitext(fname)[0] |
| result = scan_barcode(path) |
| if result: |
| results[key] = result |
| print(f" [OK] {fname} -> {result}") |
| else: |
| results[key] = None |
| print(f" [FAIL] {fname} -> could not decode") |
|
|
| success = sum(1 for v in results.values() if v) |
| print(f"\nBarcode scan: {success}/{len(files)} decoded successfully") |
| return results |
|
|
|
|
| if __name__ == "__main__": |
| import sys |
| if len(sys.argv) < 2: |
| print("Usage: python barcode_scanner.py <barcode_image_or_dir>") |
| else: |
| path = sys.argv[1] |
| if os.path.isdir(path): |
| results = scan_all_barcodes(path) |
| else: |
| result = scan_barcode(path) |
| print(f"Result: {result}") |
|
|