package com.google.zxing.qrcode.detector;
+import com.google.zxing.BlackPointEstimationMethod;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
this.image = image;
}
- /**
- * <p>Detects a QR Code in an image, simply.</p>
- *
- * @return {@link DetectorResult} encapsulating results of detecting a QR Code
- * @throws ReaderException if no QR Code can be found
- */
+ /**
+ * <p>Detects a QR Code in an image, simply.</p>
+ *
+ * @return {@link DetectorResult} encapsulating results of detecting a QR Code
+ * @throws ReaderException if no QR Code can be found
+ */
public DetectorResult detect() throws ReaderException {
MonochromeBitmapSource image = this.image;
+ if (!BlackPointEstimationMethod.TWO_D_SAMPLING.equals(image.getLastEstimationMethod())) {
+ image.estimateBlackPoint(BlackPointEstimationMethod.TWO_D_SAMPLING, 0);
+ }
FinderPatternFinder finder = new FinderPatternFinder(image);
FinderPatternInfo info = finder.find();
Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
int modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;
- // Guess where a "bottom right" finder pattern would have been
- float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
- float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
-
AlignmentPattern alignmentPattern = null;
// Anything above version 1 has an alignment pattern
if (provisionalVersion.getAlignmentPatternCenters().length > 0) {
+ // Guess where a "bottom right" finder pattern would have been
+ float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
+ float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
+
// Estimate that alignment pattern is closer by 3 modules
// from "bottom right" to known top left location
float correctionToTopLeft = 1.0f - 3.0f / (float) modulesBetweenFPCenters;
GridSampler sampler = GridSampler.getInstance();
BitMatrix bits = sampler.sampleGrid(image, topLeft, topRight, bottomLeft, alignmentPattern, dimension);
- /*
- try {
- BufferedImage outImage =
- new BufferedImage(dimension,
- dimension,
- BufferedImage.TYPE_BYTE_BINARY);
- for (int i = 0; i < dimension; i++) {
- for (int j = 0; j < dimension; j++) {
- if (bits.get(i, j)) {
- outImage.setRGB(j, i, 0xFF000000);
- } else {
- outImage.setRGB(j, i, 0xFFFFFFFF);
- }
- }
- }
- ImageIO.write(outImage, "PNG", new File("/tmp/out.png"));
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- */
-
ResultPoint[] points;
if (alignmentPattern == null) {
- points = new ResultPoint[] { bottomLeft, topLeft, topRight };
+ points = new ResultPoint[]{bottomLeft, topLeft, topRight};
} else {
- points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern };
+ points = new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern};
}
return new DetectorResult(bits, points);
}
case 0:
dimension++;
break;
- // 1? do nothing
+ // 1? do nothing
case 2:
dimension--;
break;
private float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft) {
// Take the average
return (calculateModuleSizeOneWay(topLeft, topRight) +
- calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
+ calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
}
- /**
- * <p>Estimates module size based on two finder patterns -- it uses
- * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
- * width of each, measuring along the axis between their centers.</p>
- */
+ /**
+ * <p>Estimates module size based on two finder patterns -- it uses
+ * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
+ * width of each, measuring along the axis between their centers.</p>
+ */
private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern) {
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.getX(),
- (int) pattern.getY(),
- (int) otherPattern.getX(),
- (int) otherPattern.getY());
+ (int) pattern.getY(),
+ (int) otherPattern.getX(),
+ (int) otherPattern.getY());
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.getX(),
- (int) otherPattern.getY(),
- (int) pattern.getX(),
- (int) pattern.getY());
+ (int) otherPattern.getY(),
+ (int) pattern.getX(),
+ (int) pattern.getY());
if (Float.isNaN(moduleSizeEst1)) {
return moduleSizeEst2;
}
* of another point (another finder pattern center), and in the opposite direction too.</p>
*/
private float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {
+
float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
- result += sizeOfBlackWhiteBlackRun(fromX, fromY, fromX - (toX - fromX), fromY - (toY - fromY));
+
+ // Now count other way -- don't run off image though of course
+ int otherToX = fromX - (toX - fromX);
+ if (otherToX < 0) {
+ // "to" should the be the first value not included, so, the first value off
+ // the edge is -1
+ otherToX = -1;
+ } else if (otherToX >= image.getWidth()) {
+ otherToX = image.getWidth();
+ }
+ int otherToY = fromY - (toY - fromY);
+ if (otherToY < 0) {
+ otherToY = -1;
+ } else if (otherToY >= image.getHeight()) {
+ otherToY = image.getHeight();
+ }
+ result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
return result - 1.0f; // -1 because we counted the middle pixel twice
}
error -= dx;
}
}
- // Hmm, couldn't find all of what we wanted -- don't know
- return Float.NaN;
+ int diffX = toX - fromX;
+ int diffY = toY - fromY;
+ return (float) Math.sqrt((double) (diffX * diffX + diffY * diffY));
}
/**