From 00d0e8d8d0a4e8df06672d196cd410950ab0f685 Mon Sep 17 00:00:00 2001 From: favoritas37 Date: Fri, 18 Mar 2016 21:01:48 +0200 Subject: [PATCH] refactoring in qzxing.cpp to remove uneeded references --- src/CameraImageWrapper.cpp | 39 --- src/CameraImageWrapper.h | 2 - src/qzxing.cpp | 12 +- src/zxing/zxing/BinaryBitmap.cpp | 38 +-- src/zxing/zxing/BinaryBitmap.h | 2 +- src/zxing/zxing/LuminanceSource.cpp | 7 +- src/zxing/zxing/LuminanceSource.h | 2 + .../zxing/common/GlobalHistogramBinarizer.cpp | 289 +++++++++--------- .../qrcode/detector/QRFinderPatternFinder.cpp | 23 +- 9 files changed, 193 insertions(+), 221 deletions(-) diff --git a/src/CameraImageWrapper.cpp b/src/CameraImageWrapper.cpp index 75f8670..026cfb5 100644 --- a/src/CameraImageWrapper.cpp +++ b/src/CameraImageWrapper.cpp @@ -157,45 +157,6 @@ ArrayRef CameraImageWrapper::getMatrixP() const return arr; } -QImage *CameraImageWrapper::sharpen(const QImage *origin) -{ - QImage * newImage = new QImage(* origin); - - int kernel [3][3]= {{0,-1,0}, - {-1,5,-1}, - {0,-1,0}}; - int kernelSize = 3; - int sumKernel = 1; - int r,g,b; - QColor color; - - for(int x=kernelSize/2; xwidth()-(kernelSize/2); x++){ - for(int y=kernelSize/2; yheight()-(kernelSize/2); y++){ - - r = 0; - g = 0; - b = 0; - - for(int i = -kernelSize/2; i<= kernelSize/2; i++){ - for(int j = -kernelSize/2; j<= kernelSize/2; j++){ - color = QColor(origin->pixel(x+i, y+j)); - r += color.red()*kernel[kernelSize/2+i][kernelSize/2+j]; - g += color.green()*kernel[kernelSize/2+i][kernelSize/2+j]; - b += color.blue()*kernel[kernelSize/2+i][kernelSize/2+j]; - } - } - - r = qBound(0, r/sumKernel, 255); - g = qBound(0, g/sumKernel, 255); - b = qBound(0, b/sumKernel, 255); - - newImage->setPixel(x,y, qRgb(r,g,b)); - - } - } - return newImage; -} - unsigned int CameraImageWrapper::gray(unsigned int r, unsigned int g, unsigned int b) { //values based on http://entropymine.com/imageworsener/grayscale/ diff --git a/src/CameraImageWrapper.h b/src/CameraImageWrapper.h index 400dd88..9e37b5b 100644 --- a/src/CameraImageWrapper.h +++ b/src/CameraImageWrapper.h @@ -34,8 +34,6 @@ private: ArrayRef getMatrixP() const; QImage* grayScaleImage(const QImage *origin); - QImage* sharpen(const QImage *origin); - unsigned int gray(unsigned int r, unsigned int g, unsigned int b); QImage* image; diff --git a/src/qzxing.cpp b/src/qzxing.cpp index bc7ae0e..1f0c262 100644 --- a/src/qzxing.cpp +++ b/src/qzxing.cpp @@ -198,25 +198,21 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo try { Ref imageRef(ciw); - GlobalHistogramBinarizer *binz = new GlobalHistogramBinarizer(imageRef); - - Ref bz(binz); - BinaryBitmap *bb = new BinaryBitmap(bz); - - Ref ref(bb); + Ref binz( new GlobalHistogramBinarizer(imageRef) ); + Ref bb( new BinaryBitmap(binz) ); DecodeHints hints((int)enabledDecoders); bool hasSucceded = false; try { - res = decoder->decode(ref, hints); + res = decoder->decode(bb, hints); hasSucceded = true; }catch(zxing::Exception &e){} if(!hasSucceded) { hints.setTryHarder(true); - res = decoder->decode(ref, hints); + res = decoder->decode(bb, hints); } QString string = QString(res->getText()->getText().c_str()); diff --git a/src/zxing/zxing/BinaryBitmap.cpp b/src/zxing/zxing/BinaryBitmap.cpp index bb67a93..955d7e1 100644 --- a/src/zxing/zxing/BinaryBitmap.cpp +++ b/src/zxing/zxing/BinaryBitmap.cpp @@ -22,49 +22,53 @@ using zxing::BitArray; using zxing::BitMatrix; using zxing::LuminanceSource; using zxing::BinaryBitmap; - + // VC++ using zxing::Binarizer; BinaryBitmap::BinaryBitmap(Ref binarizer) : binarizer_(binarizer) { } - + BinaryBitmap::~BinaryBitmap() { } - + Ref BinaryBitmap::getBlackRow(int y, Ref row) { - return binarizer_->getBlackRow(y, row); + return binarizer_->getBlackRow(y, row); } - + Ref BinaryBitmap::getBlackMatrix() { - return binarizer_->getBlackMatrix(); + return binarizer_->getBlackMatrix(); } - + int BinaryBitmap::getWidth() const { - return getLuminanceSource()->getWidth(); + return getLuminanceSource()->getWidth(); } - + int BinaryBitmap::getHeight() const { - return getLuminanceSource()->getHeight(); + return getLuminanceSource()->getHeight(); } - + Ref BinaryBitmap::getLuminanceSource() const { - return binarizer_->getLuminanceSource(); + return binarizer_->getLuminanceSource(); } - bool BinaryBitmap::isCropSupported() const { - return getLuminanceSource()->isCropSupported(); + return getLuminanceSource()->isCropSupported(); } Ref BinaryBitmap::crop(int left, int top, int width, int height) { - return Ref (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height)))); + return Ref (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height)))); } bool BinaryBitmap::isRotateSupported() const { - return getLuminanceSource()->isRotateSupported(); + return getLuminanceSource()->isRotateSupported(); } Ref BinaryBitmap::rotateCounterClockwise() { - return Ref (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise()))); + return Ref (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise()))); +} + +Ref BinaryBitmap::rotateCounterClockwise45() +{ + return Ref (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise45()))); } diff --git a/src/zxing/zxing/BinaryBitmap.h b/src/zxing/zxing/BinaryBitmap.h index 41efa39..00012ee 100644 --- a/src/zxing/zxing/BinaryBitmap.h +++ b/src/zxing/zxing/BinaryBitmap.h @@ -45,10 +45,10 @@ namespace zxing { bool isRotateSupported() const; Ref rotateCounterClockwise(); + Ref rotateCounterClockwise45(); bool isCropSupported() const; Ref crop(int left, int top, int width, int height); - }; } diff --git a/src/zxing/zxing/LuminanceSource.cpp b/src/zxing/zxing/LuminanceSource.cpp index 3c92fc4..4323614 100644 --- a/src/zxing/zxing/LuminanceSource.cpp +++ b/src/zxing/zxing/LuminanceSource.cpp @@ -43,7 +43,12 @@ bool LuminanceSource::isRotateSupported() const { } Ref LuminanceSource::rotateCounterClockwise() const { - throw IllegalArgumentException("This luminance source does not support rotation."); + throw IllegalArgumentException("This luminance source does not support rotation."); +} + +Ref LuminanceSource::rotateCounterClockwise45() const +{ + throw IllegalArgumentException("This luminance source does not support rotation 45."); } LuminanceSource::operator std::string() const { diff --git a/src/zxing/zxing/LuminanceSource.h b/src/zxing/zxing/LuminanceSource.h index aec23b0..10efc20 100644 --- a/src/zxing/zxing/LuminanceSource.h +++ b/src/zxing/zxing/LuminanceSource.h @@ -51,6 +51,8 @@ class LuminanceSource : public Counted { virtual Ref rotateCounterClockwise() const; + virtual Ref rotateCounterClockwise45() const; + operator std::string () const; }; diff --git a/src/zxing/zxing/common/GlobalHistogramBinarizer.cpp b/src/zxing/zxing/common/GlobalHistogramBinarizer.cpp index 49edbf7..ecbccd6 100644 --- a/src/zxing/zxing/common/GlobalHistogramBinarizer.cpp +++ b/src/zxing/zxing/common/GlobalHistogramBinarizer.cpp @@ -33,180 +33,181 @@ using zxing::BitMatrix; using zxing::LuminanceSource; namespace { - const int LUMINANCE_BITS = 5; - const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; - const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; - const ArrayRef EMPTY (0); +const int LUMINANCE_BITS = 5; +const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; +const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; +const ArrayRef EMPTY (0); } GlobalHistogramBinarizer::GlobalHistogramBinarizer(Ref source) - : Binarizer(source), luminances(EMPTY), buckets(LUMINANCE_BUCKETS) {} + : Binarizer(source), luminances(EMPTY), buckets(LUMINANCE_BUCKETS) {} GlobalHistogramBinarizer::~GlobalHistogramBinarizer() {} void GlobalHistogramBinarizer::initArrays(int luminanceSize) { - if (luminances->size() < luminanceSize) { - luminances = ArrayRef(luminanceSize); - } - for (int x = 0; x < LUMINANCE_BUCKETS; x++) { - buckets[x] = 0; - } + if (luminances->size() < luminanceSize) { + luminances = ArrayRef(luminanceSize); + } +// for (int x = 0; x < LUMINANCE_BUCKETS; x++) { +// buckets[x] = 0; +// } + memset(&buckets[0], 0, sizeof(int) * LUMINANCE_BUCKETS); } Ref GlobalHistogramBinarizer::getBlackRow(int y, Ref row) { - // std::cerr << "gbr " << y << std::endl; - LuminanceSource& source = *getLuminanceSource(); - int width = source.getWidth(); - if (row == NULL || static_cast(row->getSize()) < width) { - row = new BitArray(width); - } else { - row->clear(); - } - - initArrays(width); - ArrayRef localLuminances = source.getRow(y, luminances); - if (false) { - std::cerr << "gbr " << y << " r "; - for(int i=0, e=localLuminances->size(); i < e; ++i) { - std::cerr << 0+localLuminances[i] << " "; + // std::cerr << "gbr " << y << std::endl; + LuminanceSource& source = *getLuminanceSource(); + int width = source.getWidth(); + if (row == NULL || static_cast(row->getSize()) < width) { + row = new BitArray(width); + } else { + row->clear(); } - std::cerr << std::endl; - } - ArrayRef localBuckets = buckets; - for (int x = 0; x < width; x++) { - int pixel = localLuminances[x] & 0xff; - localBuckets[pixel >> LUMINANCE_SHIFT]++; - } - int blackPoint = estimateBlackPoint(localBuckets); - // std::cerr << "gbr bp " << y << " " << blackPoint << std::endl; - int left = localLuminances[0] & 0xff; - int center = localLuminances[1] & 0xff; - for (int x = 1; x < width - 1; x++) { - int right = localLuminances[x + 1] & 0xff; - // A simple -1 4 -1 box filter with a weight of 2. - int luminance = ((center << 2) - left - right) >> 1; - if (luminance < blackPoint) { - row->set(x); + initArrays(width); + ArrayRef localLuminances = source.getRow(y, luminances); + if (false) { + std::cerr << "gbr " << y << " r "; + for(int i=0, e=localLuminances->size(); i < e; ++i) { + std::cerr << 0+localLuminances[i] << " "; + } + std::cerr << std::endl; } - left = center; - center = right; - } - return row; -} - -Ref GlobalHistogramBinarizer::getBlackMatrix() { - LuminanceSource& source = *getLuminanceSource(); - int width = source.getWidth(); - int height = source.getHeight(); - Ref matrix(new BitMatrix(width, height)); - - // Quickly calculates the histogram by sampling four rows from the image. - // This proved to be more robust on the blackbox tests than sampling a - // diagonal as we used to do. - initArrays(width); - ArrayRef localBuckets = buckets; - for (int y = 1; y < 5; y++) { - int row = height * y / 5; - ArrayRef localLuminances = source.getRow(row, luminances); - int right = (width << 2) / 5; - for (int x = width / 5; x < right; x++) { - int pixel = localLuminances[x] & 0xff; - localBuckets[pixel >> LUMINANCE_SHIFT]++; - } - } - - int blackPoint = estimateBlackPoint(localBuckets); - - ArrayRef localLuminances = source.getMatrix(); - for (int y = 0; y < height; y++) { - int offset = y * width; + ArrayRef localBuckets = buckets; for (int x = 0; x < width; x++) { - int pixel = localLuminances[offset + x] & 0xff; - if (pixel < blackPoint) { - matrix->set(x, y); - } + int pixel = localLuminances[x] & 0xff; + localBuckets[pixel >> LUMINANCE_SHIFT]++; } - } - - return matrix; + int blackPoint = estimateBlackPoint(localBuckets); + // std::cerr << "gbr bp " << y << " " << blackPoint << std::endl; + + int left = localLuminances[0] & 0xff; + int center = localLuminances[1] & 0xff; + for (int x = 1; x < width - 1; x++) { + int right = localLuminances[x + 1] & 0xff; + // A simple -1 4 -1 box filter with a weight of 2. + int luminance = ((center << 2) - left - right) >> 1; + if (luminance < blackPoint) { + row->set(x); + } + left = center; + center = right; + } + return row; +} + +Ref GlobalHistogramBinarizer::getBlackMatrix() { + LuminanceSource& source = *getLuminanceSource(); + int width = source.getWidth(); + int height = source.getHeight(); + Ref matrix(new BitMatrix(width, height)); + + // Quickly calculates the histogram by sampling four rows from the image. + // This proved to be more robust on the blackbox tests than sampling a + // diagonal as we used to do. + initArrays(width); + ArrayRef localBuckets = buckets; + for (int y = 1; y < 5; y++) { + int row = height * y / 5; + ArrayRef localLuminances = source.getRow(row, luminances); + int right = (width << 2) / 5; + for (int x = width / 5; x < right; x++) { + int pixel = localLuminances[x] & 0xff; + localBuckets[pixel >> LUMINANCE_SHIFT]++; + } + } + + int blackPoint = estimateBlackPoint(localBuckets); + + ArrayRef localLuminances = source.getMatrix(); + for (int y = 0; y < height; y++) { + int offset = y * width; + for (int x = 0; x < width; x++) { + int pixel = localLuminances[offset + x] & 0xff; + if (pixel < blackPoint) { + matrix->set(x, y); + } + } + } + + return matrix; } using namespace std; int GlobalHistogramBinarizer::estimateBlackPoint(ArrayRef const& buckets) { - // Find tallest peak in histogram - int numBuckets = buckets->size(); - int maxBucketCount = 0; - int firstPeak = 0; - int firstPeakSize = 0; - if (false) { + // Find tallest peak in histogram + int numBuckets = buckets->size(); + int maxBucketCount = 0; + int firstPeak = 0; + int firstPeakSize = 0; + if (false) { + for (int x = 0; x < numBuckets; x++) { + cerr << buckets[x] << " "; + } + cerr << endl; + } for (int x = 0; x < numBuckets; x++) { - cerr << buckets[x] << " "; + if (buckets[x] > firstPeakSize) { + firstPeak = x; + firstPeakSize = buckets[x]; + } + if (buckets[x] > maxBucketCount) { + maxBucketCount = buckets[x]; + } } - cerr << endl; - } - for (int x = 0; x < numBuckets; x++) { - if (buckets[x] > firstPeakSize) { - firstPeak = x; - firstPeakSize = buckets[x]; + + // Find second-tallest peak -- well, another peak that is tall and not + // so close to the first one + int secondPeak = 0; + int secondPeakScore = 0; + for (int x = 0; x < numBuckets; x++) { + int distanceToBiggest = x - firstPeak; + // Encourage more distant second peaks by multiplying by square of distance + int score = buckets[x] * distanceToBiggest * distanceToBiggest; + if (score > secondPeakScore) { + secondPeak = x; + secondPeakScore = score; + } } - if (buckets[x] > maxBucketCount) { - maxBucketCount = buckets[x]; + + if (firstPeak > secondPeak) { + int temp = firstPeak; + firstPeak = secondPeak; + secondPeak = temp; } - } - // Find second-tallest peak -- well, another peak that is tall and not - // so close to the first one - int secondPeak = 0; - int secondPeakScore = 0; - for (int x = 0; x < numBuckets; x++) { - int distanceToBiggest = x - firstPeak; - // Encourage more distant second peaks by multiplying by square of distance - int score = buckets[x] * distanceToBiggest * distanceToBiggest; - if (score > secondPeakScore) { - secondPeak = x; - secondPeakScore = score; + // Kind of arbitrary; if the two peaks are very close, then we figure there is + // so little dynamic range in the image, that discriminating black and white + // is too error-prone. + // Decoding the image/line is either pointless, or may in some cases lead to + // a false positive for 1D formats, which are relatively lenient. + // We arbitrarily say "close" is + // "<= 1/16 of the total histogram buckets apart" + // std::cerr << "! " << secondPeak << " " << firstPeak << " " << numBuckets << std::endl; + if (secondPeak - firstPeak <= numBuckets >> 4) { + throw NotFoundException(); } - } - if (firstPeak > secondPeak) { - int temp = firstPeak; - firstPeak = secondPeak; - secondPeak = temp; - } - - // Kind of arbitrary; if the two peaks are very close, then we figure there is - // so little dynamic range in the image, that discriminating black and white - // is too error-prone. - // Decoding the image/line is either pointless, or may in some cases lead to - // a false positive for 1D formats, which are relatively lenient. - // We arbitrarily say "close" is - // "<= 1/16 of the total histogram buckets apart" - // std::cerr << "! " << secondPeak << " " << firstPeak << " " << numBuckets << std::endl; - if (secondPeak - firstPeak <= numBuckets >> 4) { - throw NotFoundException(); - } - - // Find a valley between them that is low and closer to the white peak - int bestValley = secondPeak - 1; - int bestValleyScore = -1; - for (int x = secondPeak - 1; x > firstPeak; x--) { - int fromFirst = x - firstPeak; - // Favor a "valley" that is not too close to either peak -- especially not - // the black peak -- and that has a low value of course - int score = fromFirst * fromFirst * (secondPeak - x) * - (maxBucketCount - buckets[x]); - if (score > bestValleyScore) { - bestValley = x; - bestValleyScore = score; + // Find a valley between them that is low and closer to the white peak + int bestValley = secondPeak - 1; + int bestValleyScore = -1; + for (int x = secondPeak - 1; x > firstPeak; x--) { + int fromFirst = x - firstPeak; + // Favor a "valley" that is not too close to either peak -- especially not + // the black peak -- and that has a low value of course + int score = fromFirst * fromFirst * (secondPeak - x) * + (maxBucketCount - buckets[x]); + if (score > bestValleyScore) { + bestValley = x; + bestValleyScore = score; + } } - } - // std::cerr << "bps " << (bestValley << LUMINANCE_SHIFT) << std::endl; - return bestValley << LUMINANCE_SHIFT; + // std::cerr << "bps " << (bestValley << LUMINANCE_SHIFT) << std::endl; + return bestValley << LUMINANCE_SHIFT; } Ref GlobalHistogramBinarizer::createBinarizer(Ref source) { - return Ref (new GlobalHistogramBinarizer(source)); + return Ref (new GlobalHistogramBinarizer(source)); } diff --git a/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp b/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp index ada5248..e1eda2f 100644 --- a/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp +++ b/src/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp @@ -107,9 +107,7 @@ 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] = {0}; -// for (int i = 0; i < 5; i++) -// stateCount[i] = 0; + int *stateCount = getCrossCheckStateCount(); // Start counting up from center @@ -175,9 +173,7 @@ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, i int originalStateCountTotal) { int maxJ = image_->getWidth(); - int stateCount[5] = {0}; -// for (int i = 0; i < 5; i++) -// stateCount[i] = 0; + int *stateCount = getCrossCheckStateCount(); int j = startJ; while (j >= 0 && image_->get(j, centerI)) { @@ -312,7 +308,7 @@ bool FinderPatternFinder::haveMultiplyConfirmedCenters() { // and that we need to keep looking. We detect this by asking if the estimated module sizes // vary too much. We arbitrarily say that when the total deviation from average exceeds // 5% of the total module size estimates, it's too much. - float average = totalModuleSize / max; + float average = totalModuleSize / (float)max; float totalDeviation = 0.0f; for (size_t i = 0; i < max; i++) { Ref pattern = possibleCenters_[i]; @@ -536,8 +532,17 @@ Ref FinderPatternFinder::find(DecodeHints const& hints) { } } - vector > patternInfo = selectBestPatterns(); - patternInfo = orderBestPatterns(patternInfo); + vector< Ref > patternInfo = selectBestPatterns(); + vector< Ref > patternInfoResPoints; + + for(size_t i=0; i(patternInfo[i])); + + ResultPoint::orderBestPatterns(patternInfoResPoints); + + patternInfo.clear(); + for(size_t i=0; i(static_cast( &*patternInfoResPoints[i] ))); Ref result(new FinderPatternInfo(patternInfo)); return result;