mirror of https://github.com/status-im/qzxing.git
Applied patch provided by Sergiy Korobov in Ticket #3 "Cannot detect QR code".
This commit is contained in:
parent
b661cc2480
commit
6542fb1d6a
|
@ -47,6 +47,7 @@ protected:
|
|||
bool hasSkipped_;
|
||||
|
||||
Ref<ResultPointCallback> callback_;
|
||||
mutable int crossCheckStateCount[5];
|
||||
|
||||
/** stateCount must be int[5] */
|
||||
static float centerFromEnd(int* stateCount, int end);
|
||||
|
@ -65,6 +66,9 @@ protected:
|
|||
Ref<BitMatrix> getImage();
|
||||
std::vector<Ref<FinderPattern> >& getPossibleCenters();
|
||||
|
||||
bool crossCheckDiagonal(int startI, int centerJ, int maxCount, int originalStateCountTotal) const;
|
||||
int *getCrossCheckStateCount() const;
|
||||
|
||||
public:
|
||||
static float distance(Ref<ResultPoint> p1, Ref<ResultPoint> p2);
|
||||
FinderPatternFinder(Ref<BitMatrix> image, Ref<ResultPointCallback>const&);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <zxing/qrcode/detector/FinderPatternFinder.h>
|
||||
#include <zxing/ReaderException.h>
|
||||
#include <zxing/DecodeHints.h>
|
||||
#include <cstring>
|
||||
|
||||
using std::sort;
|
||||
using std::max;
|
||||
|
@ -106,9 +107,9 @@ bool FinderPatternFinder::foundPatternCross(int* stateCount) {
|
|||
float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal) {
|
||||
|
||||
int maxI = image_->getHeight();
|
||||
int stateCount[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
stateCount[i] = 0;
|
||||
int stateCount[5] = {0};
|
||||
// for (int i = 0; i < 5; i++)
|
||||
// stateCount[i] = 0;
|
||||
|
||||
|
||||
// Start counting up from center
|
||||
|
@ -174,9 +175,9 @@ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, i
|
|||
int originalStateCountTotal) {
|
||||
|
||||
int maxJ = image_->getWidth();
|
||||
int stateCount[5];
|
||||
for (int i = 0; i < 5; i++)
|
||||
stateCount[i] = 0;
|
||||
int stateCount[5] = {0};
|
||||
// for (int i = 0; i < 5; i++)
|
||||
// stateCount[i] = 0;
|
||||
|
||||
int j = startJ;
|
||||
while (j >= 0 && image_->get(j, centerI)) {
|
||||
|
@ -241,7 +242,7 @@ bool FinderPatternFinder::handlePossibleCenter(int* stateCount, size_t i, size_t
|
|||
if (!isnan_z(centerI)) {
|
||||
// Re-cross check
|
||||
centerJ = crossCheckHorizontal((size_t)centerJ, (size_t)centerI, stateCount[2], stateCountTotal);
|
||||
if (!isnan_z(centerJ)) {
|
||||
if (!isnan_z(centerJ) && crossCheckDiagonal((int)centerI, (int)centerJ, stateCount[2], stateCountTotal)) {
|
||||
float estimatedModuleSize = (float)stateCountTotal / 7.0f;
|
||||
bool found = false;
|
||||
size_t max = possibleCenters_.size();
|
||||
|
@ -459,11 +460,7 @@ Ref<FinderPatternInfo> FinderPatternFinder::find(DecodeHints const& hints) {
|
|||
for (size_t i = iSkip - 1; i < maxI && !done; i += iSkip) {
|
||||
// Get a row of black/white values
|
||||
|
||||
stateCount[0] = 0;
|
||||
stateCount[1] = 0;
|
||||
stateCount[2] = 0;
|
||||
stateCount[3] = 0;
|
||||
stateCount[4] = 0;
|
||||
memset(stateCount, 0, sizeof(stateCount));
|
||||
int currentState = 0;
|
||||
for (size_t j = 0; j < maxJ; j++) {
|
||||
if (matrix.get(j, i)) {
|
||||
|
@ -510,11 +507,7 @@ Ref<FinderPatternInfo> FinderPatternFinder::find(DecodeHints const& hints) {
|
|||
}
|
||||
// Clear state to start looking again
|
||||
currentState = 0;
|
||||
stateCount[0] = 0;
|
||||
stateCount[1] = 0;
|
||||
stateCount[2] = 0;
|
||||
stateCount[3] = 0;
|
||||
stateCount[4] = 0;
|
||||
memset(stateCount, 0, sizeof(stateCount));
|
||||
} else { // No, shift counts back by two
|
||||
stateCount[0] = stateCount[2];
|
||||
stateCount[1] = stateCount[3];
|
||||
|
@ -555,5 +548,91 @@ Ref<BitMatrix> FinderPatternFinder::getImage() {
|
|||
}
|
||||
|
||||
vector<Ref<FinderPattern> >& FinderPatternFinder::getPossibleCenters() {
|
||||
return possibleCenters_;
|
||||
return possibleCenters_;
|
||||
}
|
||||
|
||||
bool FinderPatternFinder::crossCheckDiagonal(int startI, int centerJ, int maxCount, int originalStateCountTotal) const
|
||||
{
|
||||
int *stateCount = getCrossCheckStateCount();
|
||||
|
||||
// Start counting up, left from center finding black center mass
|
||||
int i = 0;
|
||||
while (startI >= i && centerJ >= i && image_->get(centerJ - i, startI - i)) {
|
||||
stateCount[2]++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (startI < i || centerJ < i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continue up, left finding white space
|
||||
while (startI >= i && centerJ >= i && !image_->get(centerJ - i, startI - i) &&
|
||||
stateCount[1] <= maxCount) {
|
||||
stateCount[1]++;
|
||||
i++;
|
||||
}
|
||||
|
||||
// If already too many modules in this state or ran off the edge:
|
||||
if (startI < i || centerJ < i || stateCount[1] > maxCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continue up, left finding black border
|
||||
while (startI >= i && centerJ >= i && image_->get(centerJ - i, startI - i) &&
|
||||
stateCount[0] <= maxCount) {
|
||||
stateCount[0]++;
|
||||
i++;
|
||||
}
|
||||
if (stateCount[0] > maxCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int maxI = image_->getHeight();
|
||||
int maxJ = image_->getWidth();
|
||||
|
||||
// Now also count down, right from center
|
||||
i = 1;
|
||||
while (startI + i < maxI && centerJ + i < maxJ && image_->get(centerJ + i, startI + i)) {
|
||||
stateCount[2]++;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Ran off the edge?
|
||||
if (startI + i >= maxI || centerJ + i >= maxJ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (startI + i < maxI && centerJ + i < maxJ && !image_->get(centerJ + i, startI + i) &&
|
||||
stateCount[3] < maxCount) {
|
||||
stateCount[3]++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (startI + i >= maxI || centerJ + i >= maxJ || stateCount[3] >= maxCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (startI + i < maxI && centerJ + i < maxJ && image_->get(centerJ + i, startI + i) &&
|
||||
stateCount[4] < maxCount) {
|
||||
stateCount[4]++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (stateCount[4] >= maxCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we found a finder-pattern-like section, but its size is more than 100% different than
|
||||
// the original, assume it's a false positive
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
|
||||
return
|
||||
abs(stateCountTotal - originalStateCountTotal) < 2 * originalStateCountTotal &&
|
||||
foundPatternCross(stateCount);
|
||||
}
|
||||
|
||||
int *FinderPatternFinder::getCrossCheckStateCount() const
|
||||
{
|
||||
memset(crossCheckStateCount, 0, sizeof(crossCheckStateCount));
|
||||
return crossCheckStateCount;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue