From 359551d6e760f56e45848b258b24fbe1c4e18bdf Mon Sep 17 00:00:00 2001 From: srowen Date: Fri, 14 Oct 2011 07:47:05 +0000 Subject: [PATCH] Minor tightening and some new constants (no algo changes) git-svn-id: https://zxing.googlecode.com/svn/trunk@1969 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../google/zxing/common/HybridBinarizer.java | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/core/src/com/google/zxing/common/HybridBinarizer.java b/core/src/com/google/zxing/common/HybridBinarizer.java index d1a94d188..3fcce238f 100644 --- a/core/src/com/google/zxing/common/HybridBinarizer.java +++ b/core/src/com/google/zxing/common/HybridBinarizer.java @@ -41,9 +41,12 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels. // So this is the smallest dimension in each axis we can accept. - private static final int MINIMUM_DIMENSION = 40; + private static final int BLOCK_SIZE_POWER = 3; + private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER; + private static final int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; + private static final int MINIMUM_DIMENSION = BLOCK_SIZE * 5; - private BitMatrix matrix = null; + private BitMatrix matrix; public HybridBinarizer(LuminanceSource source) { super(source); @@ -61,12 +64,12 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { byte[] luminances = source.getMatrix(); int width = source.getWidth(); int height = source.getHeight(); - int subWidth = width >> 3; - if ((width & 0x07) != 0) { + int subWidth = width >> BLOCK_SIZE_POWER; + if ((width & BLOCK_SIZE_MASK) != 0) { subWidth++; } - int subHeight = height >> 3; - if ((height & 0x07) != 0) { + int subHeight = height >> BLOCK_SIZE_POWER; + if ((height & BLOCK_SIZE_MASK) != 0) { subHeight++; } int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height); @@ -88,17 +91,22 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { // For each 8x8 block in the image, calculate the average black point using a 5x5 grid // of the blocks around it. Also handles the corner cases (fractional blocks are computed based // on the last 8 pixels in the row/column which are also used in the previous block). - private static void calculateThresholdForBlock(byte[] luminances, int subWidth, int subHeight, - int width, int height, int[][] blackPoints, BitMatrix matrix) { + private static void calculateThresholdForBlock(byte[] luminances, + int subWidth, + int subHeight, + int width, + int height, + int[][] blackPoints, + BitMatrix matrix) { for (int y = 0; y < subHeight; y++) { - int yoffset = y << 3; - if ((yoffset + 8) >= height) { - yoffset = height - 8; + int yoffset = y << BLOCK_SIZE_POWER; + if ((yoffset + BLOCK_SIZE) >= height) { + yoffset = height - BLOCK_SIZE; } for (int x = 0; x < subWidth; x++) { - int xoffset = x << 3; - if ((xoffset + 8) >= width) { - xoffset = width - 8; + int xoffset = x << BLOCK_SIZE_POWER; + if ((xoffset + BLOCK_SIZE) >= width) { + xoffset = width - BLOCK_SIZE; } int left = x > 1 ? x : 2; left = left < subWidth - 2 ? left : subWidth - 3; @@ -107,11 +115,7 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { int sum = 0; for (int z = -2; z <= 2; z++) { int[] blackRow = blackPoints[top + z]; - sum += blackRow[left - 2]; - sum += blackRow[left - 1]; - sum += blackRow[left]; - sum += blackRow[left + 1]; - sum += blackRow[left + 2]; + sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2]; } int average = sum / 25; threshold8x8Block(luminances, xoffset, yoffset, average, width, matrix); @@ -120,13 +124,15 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { } // Applies a single threshold to an 8x8 block of pixels. - private static void threshold8x8Block(byte[] luminances, int xoffset, int yoffset, int threshold, - int stride, BitMatrix matrix) { - for (int y = 0; y < 8; y++) { - int offset = (yoffset + y) * stride + xoffset; - for (int x = 0; x < 8; x++) { - int pixel = luminances[offset + x] & 0xff; - if (pixel < threshold) { + private static void threshold8x8Block(byte[] luminances, + int xoffset, + int yoffset, + int threshold, + int stride, + BitMatrix matrix) { + for (int y = 0, offset = yoffset * stride + xoffset; y < BLOCK_SIZE; y++, offset += stride) { + for (int x = 0; x < BLOCK_SIZE; x++) { + if ((luminances[offset + x] & 0xFF) < threshold) { matrix.set(xoffset + x, yoffset + y); } } @@ -134,26 +140,28 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { } // Calculates a single black point for each 8x8 block of pixels and saves it away. - private static int[][] calculateBlackPoints(byte[] luminances, int subWidth, int subHeight, - int width, int height) { + private static int[][] calculateBlackPoints(byte[] luminances, + int subWidth, + int subHeight, + int width, + int height) { int[][] blackPoints = new int[subHeight][subWidth]; for (int y = 0; y < subHeight; y++) { - int yoffset = y << 3; - if ((yoffset + 8) >= height) { - yoffset = height - 8; + int yoffset = y << BLOCK_SIZE_POWER; + if ((yoffset + BLOCK_SIZE) >= height) { + yoffset = height - BLOCK_SIZE; } for (int x = 0; x < subWidth; x++) { - int xoffset = x << 3; - if ((xoffset + 8) >= width) { - xoffset = width - 8; + int xoffset = x << BLOCK_SIZE_POWER; + if ((xoffset + BLOCK_SIZE) >= width) { + xoffset = width - BLOCK_SIZE; } int sum = 0; - int min = 255; + int min = 0xFF; int max = 0; - for (int yy = 0; yy < 8; yy++) { - int offset = (yoffset + yy) * width + xoffset; - for (int xx = 0; xx < 8; xx++) { - int pixel = luminances[offset + xx] & 0xff; + for (int yy = 0, offset = yoffset * width + xoffset; yy < BLOCK_SIZE; yy++, offset += width) { + for (int xx = 0; xx < BLOCK_SIZE; xx++) { + int pixel = luminances[offset + xx] & 0xFF; sum += pixel; if (pixel < min) { min = pixel;