File size: 2,876 Bytes
b42373a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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}")