From 0d4ae9fef636c7919a1ab38be319471bb77079fe Mon Sep 17 00:00:00 2001 From: "smparkes@smparkes.net" Date: Tue, 28 Jun 2011 15:59:45 +0000 Subject: [PATCH] Port Java qr detector changes re-port Detector::sizeOfBlackWhiteBlackRunBothWays and Detector::sizeOfBlackWhiteBlackRun to reflect changes from r1820 and earlier. git-svn-id: https://zxing.googlecode.com/svn/trunk@1838 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../src/zxing/qrcode/detector/Detector.cpp | 136 +++++++++--------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/cpp/core/src/zxing/qrcode/detector/Detector.cpp b/cpp/core/src/zxing/qrcode/detector/Detector.cpp index fdab42928..7fc0efe6b 100644 --- a/cpp/core/src/zxing/qrcode/detector/Detector.cpp +++ b/cpp/core/src/zxing/qrcode/detector/Detector.cpp @@ -181,84 +181,92 @@ float Detector::calculateModuleSizeOneWay(Ref pattern, Ref (int)image_->getWidth()) { - scale = (float) (image_->getWidth() - fromX) / (float) (otherToX - fromX); - otherToX = image_->getWidth(); - } - int otherToY = (int) (fromY - (toY - fromY) * scale); + // Now count other way -- don't run off image though of course + float scale = 1.0f; + int otherToX = fromX - (toX - fromX); + if (otherToX < 0) { + scale = (float) fromX / (float) (fromX - otherToX); + otherToX = 0; + } else if (otherToX >= (int)image_->getWidth()) { + scale = (float) (image_->getWidth() - 1 - fromX) / (float) (otherToX - fromX); + otherToX = image_->getWidth() - 1; + } + int otherToY = (int) (fromY - (toY - fromY) * scale); - scale = 1.0f; - if (otherToY < 0) { - scale = (float) fromY / (float) (fromY - otherToY); - otherToY = 0; - } else if (otherToY > (int)image_->getHeight()) { - scale = (float) (image_->getHeight() - fromY) / (float) (otherToY - fromY); - otherToY = image_->getHeight(); - } - otherToX = (int) (fromX + (otherToX - fromX) * scale); + scale = 1.0f; + if (otherToY < 0) { + scale = (float) fromY / (float) (fromY - otherToY); + otherToY = 0; + } else if (otherToY >= (int)image_->getHeight()) { + scale = (float) (image_->getHeight() - 1 - fromY) / (float) (otherToY - fromY); + otherToY = image_->getHeight() - 1; + } + otherToX = (int) (fromX + (otherToX - fromX) * scale); - result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); - return result; + result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); + + // Middle pixel is double-counted this way; subtract 1 + return result - 1.0f; } float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) { - // Mild variant of Bresenham's algorithm; - // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm - bool steep = abs(toY - fromY) > abs(toX - fromX); - if (steep) { - int temp = fromX; - fromX = fromY; - fromY = temp; - temp = toX; - toX = toY; - toY = temp; - } + // Mild variant of Bresenham's algorithm; + // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm + bool steep = abs(toY - fromY) > abs(toX - fromX); + if (steep) { + int temp = fromX; + fromX = fromY; + fromY = temp; + temp = toX; + toX = toY; + toY = temp; + } - int dx = abs(toX - fromX); - int dy = abs(toY - fromY); - int error = -dx >> 1; - int ystep = fromY < toY ? 1 : -1; - int xstep = fromX < toX ? 1 : -1; - int state = 0; // In black pixels, looking for white, first or second time - for (int x = fromX, y = fromY; x != toX; x += xstep) { + int dx = abs(toX - fromX); + int dy = abs(toY - fromY); + int error = -dx >> 1; + int xstep = fromX < toX ? 1 : -1; + int ystep = fromY < toY ? 1 : -1; - int realX = steep ? y : x; - int realY = steep ? x : y; - if (state == 1) { // In white pixels, looking for black - if (image_->get(realX, realY)) { + // In black pixels, looking for white, first or second time. + int state = 0; + // Loop up until x == toX, but not beyond + int xLimit = toX + xstep; + for (int x = fromX, y = fromY; x != xLimit; x += xstep) { + int realX = steep ? y : x; + int realY = steep ? x : y; + + // Does current pixel mean we have moved white to black or vice versa? + if (!(state == 1 ^ image_->get(realX, realY))) { + if (state == 2) { + int diffX = x - fromX; + int diffY = y - fromY; + return (float) sqrt((double) (diffX * diffX + diffY * diffY)); + } state++; } - } else { - if (!image_->get(realX, realY)) { - state++; - } - } - if (state == 3) { // Found black, white, black, and stumbled back onto white; done - int diffX = x - fromX; - int diffY = y - fromY; - if (xstep < 0) { - diffX++; + error += dy; + if (error > 0) { + if (y == toY) { + break; + } + y += ystep; + error -= dx; } - return (float)sqrt((double)(diffX * diffX + diffY * diffY)); } - error += dy; - if (error > 0) { - y += ystep; - error -= dx; + // Found black-white-black; give the benefit of the doubt that the next pixel outside the image + // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a + // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. + if (state == 2) { + int diffX = toX + xstep - fromX; + int diffY = toY - fromY; + return (float) sqrt((double) (diffX * diffX + diffY * diffY)); } - } - int diffX = toX - fromX; - int diffY = toY - fromY; - return (float)sqrt((double)(diffX * diffX + diffY * diffY)); + // else we didn't find even black-white-black; no estimate is really possible + return NAN; } Ref Detector::findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,