Search in sources :

Example 11 with ResultPoint

use of com.google.zxing.ResultPoint in project zxing by zxing.

the class Detector method detect.

/**
   * <p>Detects a Data Matrix Code in an image.</p>
   *
   * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code
   * @throws NotFoundException if no Data Matrix Code can be found
   */
public DetectorResult detect() throws NotFoundException {
    ResultPoint[] cornerPoints = rectangleDetector.detect();
    ResultPoint pointA = cornerPoints[0];
    ResultPoint pointB = cornerPoints[1];
    ResultPoint pointC = cornerPoints[2];
    ResultPoint pointD = cornerPoints[3];
    // Point A and D are across the diagonal from one another,
    // as are B and C. Figure out which are the solid black lines
    // by counting transitions
    List<ResultPointsAndTransitions> transitions = new ArrayList<>(4);
    transitions.add(transitionsBetween(pointA, pointB));
    transitions.add(transitionsBetween(pointA, pointC));
    transitions.add(transitionsBetween(pointB, pointD));
    transitions.add(transitionsBetween(pointC, pointD));
    Collections.sort(transitions, new ResultPointsAndTransitionsComparator());
    // Sort by number of transitions. First two will be the two solid sides; last two
    // will be the two alternating black/white sides
    ResultPointsAndTransitions lSideOne = transitions.get(0);
    ResultPointsAndTransitions lSideTwo = transitions.get(1);
    // Figure out which point is their intersection by tallying up the number of times we see the
    // endpoints in the four endpoints. One will show up twice.
    Map<ResultPoint, Integer> pointCount = new HashMap<>();
    increment(pointCount, lSideOne.getFrom());
    increment(pointCount, lSideOne.getTo());
    increment(pointCount, lSideTwo.getFrom());
    increment(pointCount, lSideTwo.getTo());
    ResultPoint maybeTopLeft = null;
    ResultPoint bottomLeft = null;
    ResultPoint maybeBottomRight = null;
    for (Map.Entry<ResultPoint, Integer> entry : pointCount.entrySet()) {
        ResultPoint point = entry.getKey();
        Integer value = entry.getValue();
        if (value == 2) {
            // this is definitely the bottom left, then -- end of two L sides
            bottomLeft = point;
        } else {
            // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now
            if (maybeTopLeft == null) {
                maybeTopLeft = point;
            } else {
                maybeBottomRight = point;
            }
        }
    }
    if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null) {
        throw NotFoundException.getNotFoundInstance();
    }
    // Bottom left is correct but top left and bottom right might be switched
    ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };
    // Use the dot product trick to sort them out
    ResultPoint.orderBestPatterns(corners);
    // Now we know which is which:
    ResultPoint bottomRight = corners[0];
    bottomLeft = corners[1];
    ResultPoint topLeft = corners[2];
    // Which point didn't we find in relation to the "L" sides? that's the top right corner
    ResultPoint topRight;
    if (!pointCount.containsKey(pointA)) {
        topRight = pointA;
    } else if (!pointCount.containsKey(pointB)) {
        topRight = pointB;
    } else if (!pointCount.containsKey(pointC)) {
        topRight = pointC;
    } else {
        topRight = pointD;
    }
    // Next determine the dimension by tracing along the top or right side and counting black/white
    // transitions. Since we start inside a black module, we should see a number of transitions
    // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to
    // end on a black module:
    // The top right point is actually the corner of a module, which is one of the two black modules
    // adjacent to the white module at the top right. Tracing to that corner from either the top left
    // or bottom right should work here.
    int dimensionTop = transitionsBetween(topLeft, topRight).getTransitions();
    int dimensionRight = transitionsBetween(bottomRight, topRight).getTransitions();
    if ((dimensionTop & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionTop++;
    }
    dimensionTop += 2;
    if ((dimensionRight & 0x01) == 1) {
        // it can't be odd, so, round... up?
        dimensionRight++;
    }
    dimensionRight += 2;
    BitMatrix bits;
    ResultPoint correctedTopRight;
    // rectangular if the bigger side is at least 7/4 times the other:
    if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {
        // The matrix is rectangular
        correctedTopRight = correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, dimensionTop, dimensionRight);
        if (correctedTopRight == null) {
            correctedTopRight = topRight;
        }
        dimensionTop = transitionsBetween(topLeft, correctedTopRight).getTransitions();
        dimensionRight = transitionsBetween(bottomRight, correctedTopRight).getTransitions();
        if ((dimensionTop & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionTop++;
        }
        if ((dimensionRight & 0x01) == 1) {
            // it can't be odd, so, round... up?
            dimensionRight++;
        }
        bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionTop, dimensionRight);
    } else {
        // The matrix is square
        int dimension = Math.min(dimensionRight, dimensionTop);
        // correct top right point to match the white module
        correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);
        if (correctedTopRight == null) {
            correctedTopRight = topRight;
        }
        // Redetermine the dimension using the corrected top right point
        int dimensionCorrected = Math.max(transitionsBetween(topLeft, correctedTopRight).getTransitions(), transitionsBetween(bottomRight, correctedTopRight).getTransitions());
        dimensionCorrected++;
        if ((dimensionCorrected & 0x01) == 1) {
            dimensionCorrected++;
        }
        bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionCorrected, dimensionCorrected);
    }
    return new DetectorResult(bits, new ResultPoint[] { topLeft, bottomLeft, bottomRight, correctedTopRight });
}
Also used : ResultPoint(com.google.zxing.ResultPoint) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BitMatrix(com.google.zxing.common.BitMatrix) ResultPoint(com.google.zxing.ResultPoint) DetectorResult(com.google.zxing.common.DetectorResult) HashMap(java.util.HashMap) Map(java.util.Map)

Example 12 with ResultPoint

use of com.google.zxing.ResultPoint in project zxing by zxing.

the class GenericMultipleBarcodeReader method translateResultPoints.

private static Result translateResultPoints(Result result, int xOffset, int yOffset) {
    ResultPoint[] oldResultPoints = result.getResultPoints();
    if (oldResultPoints == null) {
        return result;
    }
    ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length];
    for (int i = 0; i < oldResultPoints.length; i++) {
        ResultPoint oldPoint = oldResultPoints[i];
        if (oldPoint != null) {
            newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset);
        }
    }
    Result newResult = new Result(result.getText(), result.getRawBytes(), result.getNumBits(), newResultPoints, result.getBarcodeFormat(), result.getTimestamp());
    newResult.putAllMetadata(result.getResultMetadata());
    return newResult;
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ResultPoint(com.google.zxing.ResultPoint) Result(com.google.zxing.Result)

Example 13 with ResultPoint

use of com.google.zxing.ResultPoint in project zxing by zxing.

the class MonochromeRectangleDetector method detect.

/**
   * <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly
   * white, in an image.</p>
   *
   * @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and
   *  last points are opposed on the diagonal, as are the second and third. The first point will be
   *  the topmost point and the last, the bottommost. The second point will be leftmost and the
   *  third, the rightmost
   * @throws NotFoundException if no Data Matrix Code can be found
   */
public ResultPoint[] detect() throws NotFoundException {
    int height = image.getHeight();
    int width = image.getWidth();
    int halfHeight = height / 2;
    int halfWidth = width / 2;
    int deltaY = Math.max(1, height / (MAX_MODULES * 8));
    int deltaX = Math.max(1, width / (MAX_MODULES * 8));
    int top = 0;
    int bottom = height;
    int left = 0;
    int right = width;
    ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth / 2);
    top = (int) pointA.getY() - 1;
    ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right, halfHeight, 0, top, bottom, halfHeight / 2);
    left = (int) pointB.getX() - 1;
    ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right, halfHeight, 0, top, bottom, halfHeight / 2);
    right = (int) pointC.getX() + 1;
    ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, deltaY, top, bottom, halfWidth / 2);
    bottom = (int) pointD.getY() + 1;
    // Go try to find point A again with better information -- might have been off at first.
    pointA = findCornerFromCenter(halfWidth, 0, left, right, halfHeight, -deltaY, top, bottom, halfWidth / 4);
    return new ResultPoint[] { pointA, pointB, pointC, pointD };
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ResultPoint(com.google.zxing.ResultPoint)

Example 14 with ResultPoint

use of com.google.zxing.ResultPoint in project zxing by zxing.

the class WhiteRectangleDetector method getBlackPointOnSegment.

private ResultPoint getBlackPointOnSegment(float aX, float aY, float bX, float bY) {
    int dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY));
    float xStep = (bX - aX) / dist;
    float yStep = (bY - aY) / dist;
    for (int i = 0; i < dist; i++) {
        int x = MathUtils.round(aX + i * xStep);
        int y = MathUtils.round(aY + i * yStep);
        if (image.get(x, y)) {
            return new ResultPoint(x, y);
        }
    }
    return null;
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ResultPoint(com.google.zxing.ResultPoint)

Example 15 with ResultPoint

use of com.google.zxing.ResultPoint in project zxing by zxing.

the class WhiteRectangleDetector method detect.

/**
   * <p>
   * Detects a candidate barcode-like rectangular region within an image. It
   * starts around the center of the image, increases the size of the candidate
   * region until it finds a white rectangular region.
   * </p>
   *
   * @return {@link ResultPoint}[] describing the corners of the rectangular
   *         region. The first and last points are opposed on the diagonal, as
   *         are the second and third. The first point will be the topmost
   *         point and the last, the bottommost. The second point will be
   *         leftmost and the third, the rightmost
   * @throws NotFoundException if no Data Matrix Code can be found
   */
public ResultPoint[] detect() throws NotFoundException {
    int left = leftInit;
    int right = rightInit;
    int up = upInit;
    int down = downInit;
    boolean sizeExceeded = false;
    boolean aBlackPointFoundOnBorder = true;
    boolean atLeastOneBlackPointFoundOnBorder = false;
    boolean atLeastOneBlackPointFoundOnRight = false;
    boolean atLeastOneBlackPointFoundOnBottom = false;
    boolean atLeastOneBlackPointFoundOnLeft = false;
    boolean atLeastOneBlackPointFoundOnTop = false;
    while (aBlackPointFoundOnBorder) {
        aBlackPointFoundOnBorder = false;
        // .....
        // .   |
        // .....
        boolean rightBorderNotWhite = true;
        while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) {
            rightBorderNotWhite = containsBlackPoint(up, down, right, false);
            if (rightBorderNotWhite) {
                right++;
                aBlackPointFoundOnBorder = true;
                atLeastOneBlackPointFoundOnRight = true;
            } else if (!atLeastOneBlackPointFoundOnRight) {
                right++;
            }
        }
        if (right >= width) {
            sizeExceeded = true;
            break;
        }
        // .....
        // .   .
        // .___.
        boolean bottomBorderNotWhite = true;
        while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) {
            bottomBorderNotWhite = containsBlackPoint(left, right, down, true);
            if (bottomBorderNotWhite) {
                down++;
                aBlackPointFoundOnBorder = true;
                atLeastOneBlackPointFoundOnBottom = true;
            } else if (!atLeastOneBlackPointFoundOnBottom) {
                down++;
            }
        }
        if (down >= height) {
            sizeExceeded = true;
            break;
        }
        // .....
        // |   .
        // .....
        boolean leftBorderNotWhite = true;
        while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
            leftBorderNotWhite = containsBlackPoint(up, down, left, false);
            if (leftBorderNotWhite) {
                left--;
                aBlackPointFoundOnBorder = true;
                atLeastOneBlackPointFoundOnLeft = true;
            } else if (!atLeastOneBlackPointFoundOnLeft) {
                left--;
            }
        }
        if (left < 0) {
            sizeExceeded = true;
            break;
        }
        // .___.
        // .   .
        // .....
        boolean topBorderNotWhite = true;
        while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
            topBorderNotWhite = containsBlackPoint(left, right, up, true);
            if (topBorderNotWhite) {
                up--;
                aBlackPointFoundOnBorder = true;
                atLeastOneBlackPointFoundOnTop = true;
            } else if (!atLeastOneBlackPointFoundOnTop) {
                up--;
            }
        }
        if (up < 0) {
            sizeExceeded = true;
            break;
        }
        if (aBlackPointFoundOnBorder) {
            atLeastOneBlackPointFoundOnBorder = true;
        }
    }
    if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
        int maxSize = right - left;
        ResultPoint z = null;
        for (int i = 1; z == null && i < maxSize; i++) {
            z = getBlackPointOnSegment(left, down - i, left + i, down);
        }
        if (z == null) {
            throw NotFoundException.getNotFoundInstance();
        }
        ResultPoint t = null;
        //go down right
        for (int i = 1; t == null && i < maxSize; i++) {
            t = getBlackPointOnSegment(left, up + i, left + i, up);
        }
        if (t == null) {
            throw NotFoundException.getNotFoundInstance();
        }
        ResultPoint x = null;
        //go down left
        for (int i = 1; x == null && i < maxSize; i++) {
            x = getBlackPointOnSegment(right, up + i, right - i, up);
        }
        if (x == null) {
            throw NotFoundException.getNotFoundInstance();
        }
        ResultPoint y = null;
        //go up left
        for (int i = 1; y == null && i < maxSize; i++) {
            y = getBlackPointOnSegment(right, down - i, right - i, down);
        }
        if (y == null) {
            throw NotFoundException.getNotFoundInstance();
        }
        return centerEdges(y, z, x, t);
    } else {
        throw NotFoundException.getNotFoundInstance();
    }
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ResultPoint(com.google.zxing.ResultPoint)

Aggregations

ResultPoint (com.google.zxing.ResultPoint)252 Result (com.google.zxing.Result)77 Paint (android.graphics.Paint)45 Rect (android.graphics.Rect)24 BitMatrix (com.google.zxing.common.BitMatrix)22 DecoderResult (com.google.zxing.common.DecoderResult)22 NotFoundException (com.google.zxing.NotFoundException)21 DetectorResult (com.google.zxing.common.DetectorResult)20 ArrayList (java.util.ArrayList)20 ReaderException (com.google.zxing.ReaderException)16 SuppressLint (android.annotation.SuppressLint)13 ResultPointCallback (com.google.zxing.ResultPointCallback)12 Canvas (android.graphics.Canvas)10 ResultMetadataType (com.google.zxing.ResultMetadataType)8 BitArray (com.google.zxing.common.BitArray)8 QRCodeDecoderMetaData (com.google.zxing.qrcode.decoder.QRCodeDecoderMetaData)8 BarcodeFormat (com.google.zxing.BarcodeFormat)5 FormatException (com.google.zxing.FormatException)4 Decoder (com.google.zxing.aztec.decoder.Decoder)4 Detector (com.google.zxing.aztec.detector.Detector)4