QR Code Reading Benchmark: Dynamsoft vs ZXing vs ZBar vs BoofCV vs OpenCV
QR codes are a critical part of modern applications — from payment systems and ticketing to inventory management and document tracking. As a two-dimensional barcode, a QR code can store significantly more data than a 1D barcode and is decoded from a camera image using image processing algorithms.
Choosing the right QR code reading library matters. Real-world QR codes are often blurred, damaged, curved, or printed with non-standard designs, and not every SDK handles these conditions equally well.

Independent benchmarks for QR code reading libraries are rare. One notable benchmark was produced by the author of the open-source BoofCV computer vision library, who assembled a labeled dataset of QR code images across 16 difficulty categories and tested five open-source libraries against it.
This article extends that benchmark to include commercial SDKs. We test 7 libraries and SDKs — both open-source and commercial — against the same dataset of 536 images containing 1,232 QR codes across 16 categories: blurred, bright_spots, brightness, close, curved, damaged, glare, high_version, lots, monitor, nominal, noncompliant, pathological, perspective, rotations, and shadows.
This article is Part 1 in a 5-Part Series.
- Part 1 - QR Code Reading Benchmark: Dynamsoft vs ZXing vs ZBar vs BoofCV vs OpenCV
- Part 2 - 1D Barcode Scanning Accuracy Benchmark and Comparison
- Part 3 - What are the Best Data Matrix Reading SDKs?
- Part 4 - What are the Best PDF417 Reading SDKs?
- Part 5 - Multiple Barcodes Reading Benchmark and Comparison
Video:
Note: The article has been updated on 06/26/2023. The results in the video may have some slight differences.
Performance Test Tool
All benchmarks were run using an open-source test harness. The source code is available at github.com/tony-xlh/barcode-reading-benchmark.
Test hardware: Intel i5-10400 CPU, 16 GB RAM.
Evaluated Libraries
The following 7 QR code reading libraries and SDKs were evaluated:
- Dynamsoft Barcode Reader (version: 11.4.1000, commercial)
- Commercial SDK A (version: 6.16, Scandit, commercial)
- Commercial SDK B (version: 13.9, Aspose, commercial)
- BoofCV (version: 0.43.1, open-source)
- ZXing (version: 3.5.1, open-source)
- ZBar (version: pyzbar 0.1.9, open-source)
- WeChat QR code detector in OpenCV (version: OpenCV 4.7.0.72, open-source)
Where an SDK supports multiple barcode formats, its runtime settings were restricted to QR codes only to ensure a fair single-format comparison.
Evaluation Metrics
Performance is measured on two dimensions: reading rate (accuracy) and runtime (speed).
The reading rate is the proportion of QR codes in the dataset that were successfully detected:
Reading rate = Detected QR codes / Total QR codes
A QR code is counted as detected if the bounding polygon returned by the library overlaps with the ground-truth bounding polygon by more than 20%:
Here is the simplified code for doing this:
function isDetected(barcodeResult){
for (let j = 0; j < groundTruthList.length; j++) {
const groundTruth = groundTruthList[j];
let percent;
const points1 = getPointsFromBarcodeResultResult(barcodeResult);
const points2 = getPointsFromGroundTruth(groundTruth);
percent = overlappingPercent(points1,points2);
if (percent > 0.20) {
return true;
}
}
return false;
}
The overlapping percent is calculated with the following code:
export function overlappingPercent(pts1:Point[] ,pts2:Point[]) : number {
const rect1 = getRectFromPoints(pts1);
const rect2 = getRectFromPoints(pts2);
let leftRect;
let rightRect;
if (rect1.left<rect2.left) {
leftRect = rect1;
rightRect = rect2;
}else{
leftRect = rect2;
rightRect = rect1;
}
let upperRect;
let lowerRect;
if (rect1.top<rect2.top) {
upperRect = rect1;
lowerRect = rect2;
}else{
upperRect = rect2;
lowerRect = rect1;
}
if (leftRect.right > rightRect.left && upperRect.bottom>lowerRect.top) {
const overlappedX = Math.min(leftRect.right,rightRect.right) - rightRect.left;
const overlappedY = Math.min(upperRect.bottom,lowerRect.bottom) - lowerRect.top;
const overlappedArea = overlappedX * overlappedY;
const area1 = rect1.width * rect1.height;
const area2 = rect2.width * rect2.height;
const smallerArea = Math.min(area1,area2);
return overlappedArea/smallerArea;
}else{
return 0;
}
}
The decoded text is not used as a detection criterion — all libraries achieved 100% text precision on the codes they successfully detected.
Note on ZXing: ZXing only returns the three finder-pattern corner points of a QR code rather than a full polygon. A postprocessing step converts these three points into an equivalent bounding polygon before the overlap calculation.

Runtime is measured in the Python backend as the wall-clock time of the decode call only, excluding file I/O:
start_time = time.time()
results = self.reader.decode_bytes(file_bytes)
end_time = time.time()
elapsedTime = int((end_time - start_time) * 1000)
Detection Results
The table below shows the reading rate (%) for each library across all 16 image categories. The best result per category is bolded.
| Category | Dynamsoft | BoofCV | ZXing | ZBar | OpenCV WeChat | Commercial SDK A | Commercial SDK B |
|---|---|---|---|---|---|---|---|
| blurred | 66.15 | 38.46 | 21.54 | 35.38 | 46.15 | 33.85 | 36.92 |
| brightness | 81.18 | 78.82 | 52.94 | 50.59 | 23.53 | 52.94 | 51.76 |
| bright_spots | 43.3 | 27.84 | 20.62 | 19.59 | 24.74 | 8.25 | 29.9 |
| close | 95 | 100 | 5 | 12.5 | 67.5 | 22.5 | 25 |
| curved | 70 | 56.67 | 31.67 | 35 | 43.33 | 31.67 | 36.67 |
| damaged * | 51.16 | 16.28 | 20.93 | 25.58 | 30.23 | 27.91 | 27.91 |
| glare | 84.91 | 32.08 | 20.75 | 35.85 | 58.49 | 43.4 | 20.75 |
| high_version * | 97.3 | 40.54 | 5.41 | 27.03 | 18.92 | 78.38 | 35.14 |
| lots * | 100 | 99.76 | 82.86 | 18.1 | 0 | 14.52 | 97.14 |
| monitor | 100 | 82.35 | 0 | 0 | 94.12 | 11.76 | 5.88 |
| nominal | 93.59 | 89.74 | 53.85 | 66.67 | 71.79 | 64.1 | 65.38 |
| noncompliant * | 92.31 | 3.85 | 15.38 | 50 | 76.92 | 61.54 | 11.54 |
| pathological * | 95.65 | 43.48 | 34.78 | 65.22 | 91.3 | 0 | 78.26 |
| perspective | 62.86 | 80 | 37.14 | 42.86 | 42.86 | 65.71 | 34.29 |
| rotations | 99.25 | 96.24 | 42.11 | 48.87 | 32.33 | 99.25 | 69.17 |
| shadows | 100 | 85 | 65 | 90 | 60 | 90 | 95 |
| total average | 83.29 | 60.69 | 31.87 | 38.95 | 48.89 | 44.11 | 45.04 |
- Damaged QR codes are the ones with scratches, dents, etc.
- Pathological QR codes have the markers intentionally corrupted. The markers are designed for the detection of QR Codes.
- The lots category has multiple QR Codes in one image.
- The QR Code symbology ranges from Version 1 to Version 40. The Version Information represents the number of cells (per side) making up the code. More on the QR Code versions.
- Non-compliant QR Codes have customized designs, for example, colors, or a logo at the center.
Dynamsoft Barcode Reader Leads Overall
Dynamsoft Barcode Reader ranks 1st in 14 of 16 categories and achieves a total average reading rate of 83.29% — more than 20 percentage points ahead of the next closest commercial option. In the most challenging categories (blurred, curved, glare, and high-version), it is the only solution to exceed 67%.

It ranks 2nd in the close category (behind BoofCV’s perfect 100%) and 3rd in perspective.
Some categories have inherently low reading rates across all libraries because the source images contain QR codes that are physically unreadable even by human inspection.
Download 30-Day Free Trial SDK
Open-Source Comparison: ZXing vs. ZBar vs. BoofCV vs. OpenCV WeChat
If an open-source solution is required, BoofCV and OpenCV WeChat are the stronger choices. Both are grounded in modern computer vision techniques and are actively maintained, which likely accounts for their advantage over ZXing and ZBar in challenging conditions.
- OpenCV WeChat achieves the highest reading rate for damaged and pathological QR codes among all libraries. Its strong performance on non-compliant QR codes (those with custom colors or center logos) reflects the prevalence of such codes in its WeChat-sourced training data.
- BoofCV is the best open-source option for benchmark categories that exclude noncompliant and pathological codes, and it achieves a perfect 100% on the close category. It is particularly strong in the “lots” category (multiple QR codes per image).
- ZXing and ZBar trail significantly in most real-world conditions and are not recommended for applications where image quality cannot be guaranteed.
Runtime Results
Average decode time per image in milliseconds (lower is better):
| Engine | Result |
|---|---|
| Dynamsoft | 195.01 |
| Commercial SDK A | 1400.43 |
| Commercial SDK B | 346.27 |
| ZXing | 179.57 |
| ZBar | 157.31 |
| BoofCV | 104.95 |
| OpenCV Wechat | 757.71 |
Conclusion
Across 1,232 QR codes spanning 16 real-world difficulty categories, Dynamsoft Barcode Reader achieves the highest overall reading rate (83.29%) while maintaining competitive decode speed (195 ms/image). It is the most robust choice for production applications that must handle challenging QR code conditions.
For teams with an open-source requirement, BoofCV and OpenCV WeChat are the best available options, each excelling in different categories. ZXing and ZBar are viable only for controlled-environment use cases where image quality is consistently high.
The full detailed benchmark results are published at dynamsoft.com/barcode-dataset/benchmark/project/QRCode.
Frequently Asked Questions
Which QR code reading library has the best accuracy? In this benchmark, Dynamsoft Barcode Reader achieved the highest total average reading rate of 83.29% across 16 image categories, outperforming ZXing (31.87%), ZBar (38.95%), BoofCV (60.69%), and OpenCV WeChat (48.89%).
Which open-source QR code library is most accurate? BoofCV (60.69% overall) and OpenCV WeChat (48.89%) significantly outperform ZXing (31.87%) and ZBar (38.95%) on this dataset. The best choice between BoofCV and OpenCV WeChat depends on your category of images: OpenCV WeChat is better for damaged/pathological/non-compliant codes, BoofCV is better for multi-code and close-up scenarios.
Is ZXing still a good QR code scanner? For images captured in controlled, well-lit conditions with undamaged QR codes, ZXing is functional. However, this benchmark shows it ranks last among the open-source libraries in total average reading rate (31.87%), making it a poor choice for real-world deployments.
How was the dataset selected? The dataset was originally assembled by Peter Abeles (BoofCV) and consists of 536 images containing 1,232 QR codes, covering 16 categories of real-world imaging challenges. Ground-truth bounding polygons are provided for each QR code.