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
|
From a48bc1dec5c443b713c3e102258a9cfa610091d8 Mon Sep 17 00:00:00 2001
From: Alessandro Florio <alessandro.florio@tol.info>
Date: Mon, 31 Oct 2022 17:00:24 +0100
Subject: [PATCH] match badly-printed QR codes
recognize QR codes despite smears caused by bad printers
Signed-off-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
---
.../qrcode/detector/QRFinderPatternFinder.cpp | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp b/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp
index 908a7b8..700abd6 100644
--- a/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp
+++ b/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp
@@ -87,11 +87,24 @@ bool FinderPatternFinder::foundPatternCross(int *stateCount)
int moduleSize = (totalModuleSize << 8) / 7;
int maxVariance = moduleSize / 2;
// Allow less than 50% variance from 1-1-3-1-1 proportions
- return ::abs(moduleSize - (stateCount[0] << 8)) < maxVariance &&
+ if ( ::abs(moduleSize - (stateCount[0] << 8)) < maxVariance &&
::abs(moduleSize - (stateCount[1] << 8)) < maxVariance &&
::abs(3.0f * moduleSize - (stateCount[2] << 8)) < 3 * maxVariance &&
::abs(moduleSize - (stateCount[3] << 8)) < maxVariance &&
- ::abs(moduleSize - (stateCount[4] << 8)) < maxVariance;
+ ::abs(moduleSize - (stateCount[4] << 8)) < maxVariance
+ ) {
+ return true;
+ }
+
+ // Proportions are not matched by the pattern. However, a bad print or a blurred frame
+ // may lead to a false negative. Try to check whether there is a valid center and the
+ // two extremities are of similar size, with blacks and whites having matching widths.
+
+ return ::abs(3.0f * moduleSize - (stateCount[2] << 8)) < 3 * maxVariance && // center is 3/7 +- variance
+ ::abs(2.0f * moduleSize - ((stateCount[0] + stateCount[1]) << 8)) < 2 * maxVariance && // left/top is 2/7 +- variance
+ ::abs(2.0f * moduleSize - ((stateCount[3] + stateCount[4]) << 8)) < 2 * maxVariance && // right/bottom is 2/7 +- variance
+ (::abs(stateCount[0] - stateCount[4]) << 8) < maxVariance && // difference between first and last black is < variance
+ (::abs(stateCount[1] - stateCount[3]) << 8) < maxVariance; // difference between whites is < variance
}
float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal)
--
2.47.2
|