二维码广泛应用于我们的日常生活中。常见的二维码类型有QR Code、PDF417和DataMatrix。二维码可以存储比一维条码更多的数据。它通常需要使用相机捕获,然后用图像处理方法解码。
在现实世界中阅读二维码是很有挑战性的。例如下图中的二维码,它存在损坏、起皱,读取的难度会大大提高。
有许多可以读取二维码的开源和商业的类库或 SDK。我们需要进行基准测试来对它们进行评估以找到适合的SDK。
读取二维码基准测试不多。开源计算机视觉库Boofcv的作者做了一个较为全面的测试。他收集了一个QR图片集,并对它们做了分类。在这个图片集上进行性能测试,评估了五个开源类库。
该数据集有536幅图像,包含1232个二维码,共有16个类别:模糊、亮点、亮度变化、近距离、弯曲、损坏、反光、高版本、多码、屏幕上显示、日常生活中、不标准、缺损、倾斜、旋转和阴影。在本文中,我们将使用此数据集进行QR码的读取基准测试。
性能测试工具
为了运行基准测试,编写了一个性能测试工具。
可以在这里找到它的代码。
测试将在配备 Intel i5-10400 CPU 和 16GB 内存的 PC 设备上运行。
评估的类库
我们将评估 7 个类库和SDK:
- Dynamsoft Barcode Reader (版本:9.6.20,商业软件)
- Commercial SDK A(版本:6.16,商业软件)
- Commercial SDK B(版本:13.9,商业软件)
- BoofCV(版本:0.43.1,开源软件)
- ZXing(版本:3.5.1,开源软件)
- ZBar(版本:pyzbar 0.1.9,开源软件)
- OpenCV中的微信二维码检测器(版本:OpenCV 4.7.0.72,开源软件)
如果SDK支持多种条码格式,则修改其解码设置为仅解码QR码。
评价指标
性能由读取率和运行时间来评估。
通过将检测到的二维码数除以图像中的总二维码数,可以得到读取率。
读取率 = 检测到的二维码数 / 总二维码数
如何判断正确检测到了二维码?如果检测到的二维码的多边形和标注中的多边形区域的存在重叠,则可以判断该结果为正确。
以下是该操作的简要版代码:
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;
}
重叠百分比使用以下代码计算:
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;
}
}
由于所有库都能正确读取二维码的文本,因此这里不考虑二维码文本结果。
注:
ZXing仅返回二维码中位置模式的三个点的坐标。测试时会将三个点转换为多边形。
运行时间使用以下代码计算的:
start_time = time.time()
results = self.reader.decode_bytes(file_bytes)
end_time = time.time()
elapsedTime = int((end_time - start_time) * 1000)
检测结果
不同分类的读取率(百分比):
我们可以看到,Dynamsoft Barcode Reader在大多数类别中排名第一。它在近距离类中排名第二,在透视类中排名第三。
注:某些类别的读取率不是很高,因为里面的一些二维码本来就是不可读。
运行时间结果
平均运行时间(毫秒,按图片):
SDK | 结果 |
---|---|
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 |
结论
我们可以看到,Dynamsoft Barcode Reader的二维码读取率是测试集中最好的,速度也相当不错。如果条件允许,最好选择它作为二维码识别的SDK。
可以在这里浏览具体的测试结果。