Skip to content

Commit c6d3d37

Browse files
committed
Add zxing zbar example
1 parent e46aa7f commit c6d3d37

18 files changed

+338
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ZXing vs. ZBar vs. Dynamsoft Barcode Reader in Python
2+
This repository provides a comparison of barcode recognition performance between three popular barcode scanning libraries: **ZXing**, **ZBar**, and [Dynamsoft Barcode Reader](https://pypi.org/project/dbr/).
3+
4+
## Dataset Download
5+
Download the full dataset from the following link: https://drive.google.com/uc?id=1uThXXH8HiHAw6KlpdgcimBSbrvi0Mksf&export=download
6+
7+
## Installation
8+
9+
To get started, install the required dependencies:
10+
11+
```bash
12+
pip install -r requirements.txt
13+
```
14+
15+
16+
## Usage
17+
1. Obtain a [Dynamsoft Barcode Reader trial license](ttps://www.dynamsoft.com/customer/license/trialLicense) and update the code with the license key in `app.py`.
18+
19+
```python
20+
BarcodeReader.init_license('LICENSE-KEY')
21+
```
22+
23+
2. Run the Python script:
24+
25+
```bash
26+
python app.py
27+
28+
Usage:
29+
python app.py -i <image_file>
30+
python app.py -d <folder_directory>
31+
```
32+
33+
## Benchmark Results
34+
Below is a visual comparison of the barcode recognition rates among ZXing, ZBar, and Dynamsoft Barcode Reader based on the dataset.
35+
36+
![barcode sdk benchmark](https://www.dynamsoft.com/codepool/img/2020/02/benchmark-barcode-sdk.png)
37+
38+
## Blog
39+
[How to Use Python ZXing and Python ZBar on Windows 10](https://www.dynamsoft.com/codepool/python-zxing-zbar-barcode.html)
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import argparse
2+
import pyzbar.pyzbar as zbar
3+
from PIL import Image
4+
import zxingcpp
5+
from dbr import *
6+
import time
7+
import os
8+
import data
9+
import cv2
10+
11+
12+
def zxing_decode(filename):
13+
start = time.time()
14+
img = cv2.imread(filename)
15+
zxing_results = zxingcpp.read_barcodes(img)
16+
elapsed_time = time.time() - start
17+
if zxing_results != None:
18+
for result in zxing_results:
19+
print('ZXing: {}. Elapsed time: {}ms'.format(
20+
result.text, int(elapsed_time * 1000)))
21+
return zxing_results
22+
else:
23+
print('ZXing failed to decode {}'.format(filename))
24+
25+
return None
26+
27+
28+
def zbar_decode(zbar_reader, filename):
29+
start = time.time()
30+
zbar_results = zbar.decode(Image.open(filename))
31+
elapsed_time = time.time() - start
32+
if len(zbar_results) > 0:
33+
for zbar_result in zbar_results:
34+
print('ZBar: {}. Elapsed time: {}ms'.format(
35+
zbar_result.data.decode("utf-8"), int(elapsed_time * 1000)))
36+
37+
return zbar_results
38+
else:
39+
print('ZBar failed to decode {}'.format(filename))
40+
41+
return None
42+
43+
44+
def dbr_decode(dbr_reader, filename):
45+
try:
46+
start = time.time()
47+
dbr_results = dbr_reader.decode_file(filename)
48+
elapsed_time = time.time() - start
49+
50+
if dbr_results != None:
51+
for text_result in dbr_results:
52+
# print(textResult["BarcodeFormatString"])
53+
print('Dynamsoft Barcode Reader: {}. Elapsed time: {}ms'.format(
54+
text_result.barcode_text, int(elapsed_time * 1000)))
55+
56+
return dbr_results
57+
else:
58+
print("DBR failed to decode {}".format(filename))
59+
except Exception as err:
60+
print("DBR failed to decode {}".format(filename))
61+
62+
return None
63+
64+
65+
def dataset(directory=None, zbar_reader=None, dbr_reader=None):
66+
if directory != None:
67+
print(directory)
68+
files = os.listdir(directory)
69+
files = [f for f in files if f.endswith('.jpg') or f.endswith('.png')]
70+
total_count = len(files)
71+
if total_count == 0:
72+
print('No image files')
73+
return
74+
75+
# Create a .xlsx file
76+
datafile = 'benchmark.xlsx'
77+
wb = data.get_workbook(datafile)
78+
index = 2
79+
80+
print('Total count of barcode image files: {}'.format(total_count))
81+
zbar_count = 0
82+
dbr_count = 0
83+
zxing_count = 0
84+
85+
for filename in files:
86+
file_path = os.path.join(directory, filename)
87+
expected_result = filename.split('_')[0]
88+
89+
r1 = ''
90+
r2 = ''
91+
r3 = ''
92+
93+
# ZBar
94+
if zbar_reader != None:
95+
zbar_results = zbar_decode(zbar_reader, file_path)
96+
if zbar_results != None:
97+
for zbar_result in zbar_results:
98+
zbar_text = zbar_result.data.decode("utf-8")
99+
r1 = zbar_text
100+
if r1 == expected_result:
101+
zbar_count += 1
102+
break
103+
else:
104+
print('Fail to decode {}'.format(filename))
105+
106+
# DBR
107+
if dbr_reader != None:
108+
textResults = dbr_decode(dbr_reader, file_path)
109+
if textResults != None:
110+
for textResult in textResults:
111+
r2 = textResult.barcode_text
112+
if r2 == expected_result:
113+
dbr_count += 1
114+
break
115+
else:
116+
print("DBR failed to decode {}".format(filename))
117+
118+
# ZXing
119+
print('ZXing decoding {}'.format(filename))
120+
zxing_results = zxing_decode(file_path)
121+
if zxing_results != None:
122+
for result in zxing_results:
123+
r3 = result.text
124+
if r3 == expected_result:
125+
zxing_count += 1
126+
else:
127+
print('ZXing failed to decode {}'.format(filename))
128+
129+
# Add results to .xlsx file
130+
data.update_row(wb, index, filename, expected_result, r1, r2, r3)
131+
index += 1
132+
133+
# Test
134+
# if index == 9:
135+
# break
136+
137+
r1 = 0
138+
r2 = 0
139+
r3 = 0
140+
if zbar_reader != None:
141+
zbar_rate = zbar_count * 100 / total_count
142+
r1 = '{0:.2f}%'.format(zbar_rate)
143+
print('ZBar recognition rate: {0:.2f}%'.format(zbar_rate))
144+
145+
if dbr_reader != None:
146+
dbr_rate = dbr_count * 100 / total_count
147+
r2 = '{0:.2f}%'.format(dbr_rate)
148+
print('DBR recognition rate: {0:.2f}%'.format(dbr_rate))
149+
150+
zxing_rate = zxing_count * 100 / total_count
151+
r3 = '{0:.2f}%'.format(zxing_rate)
152+
print('ZXing recognition rate: {0:.2f}%'.format(zxing_rate))
153+
154+
data.set_recognition_rate(wb, index, r1, r2, r3)
155+
# Save data to .xlsx file
156+
data.save_workbook(wb, datafile)
157+
158+
159+
def main():
160+
ap = argparse.ArgumentParser()
161+
ap.add_argument("-i", "--image", type=str,
162+
help="path to input image")
163+
ap.add_argument("-d", "--directory", type=str,
164+
help="directory of image folder")
165+
args = vars(ap.parse_args())
166+
167+
image = args["image"]
168+
directory = args["directory"]
169+
if image == None and directory == None:
170+
print('''
171+
Usage:
172+
python app.py -i <image_file>
173+
python app.py -d <folder_directory>
174+
''')
175+
return
176+
177+
# Initialize barcode reader
178+
BarcodeReader.init_license(
179+
'DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==')
180+
dbr_reader = BarcodeReader()
181+
182+
if image != None:
183+
# ZXing
184+
zxing_decode(image)
185+
186+
# ZBar
187+
zbar_decode(zbar, image)
188+
189+
# Dynamsoft Barcode Reader
190+
dbr_decode(dbr_reader, image)
191+
192+
if directory != None:
193+
dataset(directory,
194+
zbar_reader=zbar, dbr_reader=dbr_reader)
195+
196+
197+
if __name__ == "__main__":
198+
main()
5.34 KB
Binary file not shown.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from openpyxl import utils
2+
from openpyxl import Workbook
3+
from openpyxl import load_workbook
4+
from openpyxl.styles import Color, PatternFill
5+
6+
import os
7+
8+
# Define cell color
9+
red = PatternFill(start_color='FFFF0000',
10+
end_color='FFFF0000',
11+
fill_type='solid')
12+
13+
green = PatternFill(start_color='FF00FF00',
14+
end_color='FF00FF00',
15+
fill_type='solid')
16+
17+
yellow = PatternFill(start_color='00FFFF00',
18+
end_color='00FFFF00',
19+
fill_type='solid')
20+
21+
passed = 'Passed'
22+
23+
def get_workbook(wb_name):
24+
if os.path.isfile(wb_name):
25+
wb = load_workbook(wb_name)
26+
else:
27+
wb = Workbook()
28+
ws = wb.active
29+
ws.title = 'Recognition Rate'
30+
ws['A1'] = 'File Name'
31+
# Set column width
32+
ws.column_dimensions[utils.get_column_letter(1)].width = 25
33+
ws['B1'] = 'Expected Results'
34+
ws.column_dimensions[utils.get_column_letter(2)].width = 20
35+
ws['C1'] = 'ZBar'
36+
ws.column_dimensions[utils.get_column_letter(3)].width = 20
37+
ws['D1'] = 'DBR'
38+
ws.column_dimensions[utils.get_column_letter(4)].width = 20
39+
ws['E1'] = 'ZXing'
40+
ws.column_dimensions[utils.get_column_letter(5)].width = 20
41+
return wb
42+
43+
def save_workbook(wb, wb_name):
44+
if wb != None:
45+
wb.save(wb_name)
46+
47+
def append_row(wb, filename=None, expected_results=None, zbar_results=None, dbr_results=None, ZXing_results=None):
48+
ws = wb.active
49+
ws.append([filename, expected_results, zbar_results, dbr_results, ZXing_results])
50+
51+
def update_row(wb, row_index, filename=None, expected_results=None, zbar_results=None, dbr_results=None, ZXing_results=None):
52+
ws = wb.active
53+
row = ws[row_index]
54+
row[0].value = filename
55+
row[1].value = expected_results
56+
if zbar_results != None:
57+
row[2].value = zbar_results
58+
if zbar_results == expected_results:
59+
row[2].fill = green
60+
else:
61+
row[2].fill = red
62+
63+
if dbr_results != None:
64+
row[3].value = dbr_results
65+
if dbr_results == expected_results:
66+
row[3].fill = green
67+
else:
68+
row[3].fill = red
69+
70+
if ZXing_results != None:
71+
row[4].value = ZXing_results
72+
if ZXing_results == expected_results:
73+
row[4].fill = green
74+
else:
75+
row[4].fill = red
76+
77+
def set_recognition_rate(wb, row_index, r1=None, r2=None, r3=None):
78+
ws = wb.active
79+
row = ws[row_index]
80+
row[2].value = r1
81+
row[3].value = r2
82+
row[4].value = r3
83+
84+
85+
# Test
86+
# name = 'data.xlsx'
87+
# wb = get_workbook(name)
88+
# ws = wb.active
89+
# index = 2
90+
# update_row(wb, index, r'D:\python-zxing-zbar-dbr\dataset\20499525_2.jpg', '20499525', '20499525', '20499525', '20499521')
91+
# index += 1
92+
# set_recognition_rate(wb, index, '59.46%', '75.68%', '13.51%')
93+
# save_workbook(wb, name)
94+
95+
96+
97+
351 KB
Loading
617 KB
Loading
613 KB
Loading
448 KB
Loading
2.5 MB
Loading
269 KB
Loading

0 commit comments

Comments
 (0)