Search in sources :

Example 1 with DetectorResult

use of com.google.zxing.common.DetectorResult 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 2 with DetectorResult

use of com.google.zxing.common.DetectorResult in project zxing by zxing.

the class DataMatrixReader method decode.

@Override
public Result decode(BinaryBitmap image, Map<DecodeHintType, ?> hints) throws NotFoundException, ChecksumException, FormatException {
    DecoderResult decoderResult;
    ResultPoint[] points;
    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
        BitMatrix bits = extractPureBits(image.getBlackMatrix());
        decoderResult = decoder.decode(bits);
        points = NO_POINTS;
    } else {
        DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
        decoderResult = decoder.decode(detectorResult.getBits());
        points = detectorResult.getPoints();
    }
    Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATA_MATRIX);
    List<byte[]> byteSegments = decoderResult.getByteSegments();
    if (byteSegments != null) {
        result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
    }
    String ecLevel = decoderResult.getECLevel();
    if (ecLevel != null) {
        result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
    }
    return result;
}
Also used : ResultPoint(com.google.zxing.ResultPoint) Detector(com.google.zxing.datamatrix.detector.Detector) DecoderResult(com.google.zxing.common.DecoderResult) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) Result(com.google.zxing.Result) DetectorResult(com.google.zxing.common.DetectorResult) DecoderResult(com.google.zxing.common.DecoderResult)

Example 3 with DetectorResult

use of com.google.zxing.common.DetectorResult in project zxing by zxing.

the class QRCodeMultiReader method decodeMultiple.

@Override
public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType, ?> hints) throws NotFoundException {
    List<Result> results = new ArrayList<>();
    DetectorResult[] detectorResults = new MultiDetector(image.getBlackMatrix()).detectMulti(hints);
    for (DetectorResult detectorResult : detectorResults) {
        try {
            DecoderResult decoderResult = getDecoder().decode(detectorResult.getBits(), hints);
            ResultPoint[] points = detectorResult.getPoints();
            // If the code was mirrored: swap the bottom-left and the top-right points.
            if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) {
                ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points);
            }
            Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
            List<byte[]> byteSegments = decoderResult.getByteSegments();
            if (byteSegments != null) {
                result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
            }
            String ecLevel = decoderResult.getECLevel();
            if (ecLevel != null) {
                result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
            }
            if (decoderResult.hasStructuredAppend()) {
                result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber());
                result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity());
            }
            results.add(result);
        } catch (ReaderException re) {
        // ignore and continue 
        }
    }
    if (results.isEmpty()) {
        return EMPTY_RESULT_ARRAY;
    } else {
        results = processStructuredAppend(results);
        return results.toArray(new Result[results.size()]);
    }
}
Also used : ResultPoint(com.google.zxing.ResultPoint) ArrayList(java.util.ArrayList) Result(com.google.zxing.Result) DetectorResult(com.google.zxing.common.DetectorResult) DecoderResult(com.google.zxing.common.DecoderResult) ReaderException(com.google.zxing.ReaderException) DecoderResult(com.google.zxing.common.DecoderResult) DetectorResult(com.google.zxing.common.DetectorResult) MultiDetector(com.google.zxing.multi.qrcode.detector.MultiDetector) QRCodeDecoderMetaData(com.google.zxing.qrcode.decoder.QRCodeDecoderMetaData)

Example 4 with DetectorResult

use of com.google.zxing.common.DetectorResult in project zxing by zxing.

the class MultiDetector method detectMulti.

public DetectorResult[] detectMulti(Map<DecodeHintType, ?> hints) throws NotFoundException {
    BitMatrix image = getImage();
    ResultPointCallback resultPointCallback = hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
    MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);
    FinderPatternInfo[] infos = finder.findMulti(hints);
    if (infos.length == 0) {
        throw NotFoundException.getNotFoundInstance();
    }
    List<DetectorResult> result = new ArrayList<>();
    for (FinderPatternInfo info : infos) {
        try {
            result.add(processFinderPatternInfo(info));
        } catch (ReaderException e) {
        // ignore
        }
    }
    if (result.isEmpty()) {
        return EMPTY_DETECTOR_RESULTS;
    } else {
        return result.toArray(new DetectorResult[result.size()]);
    }
}
Also used : ResultPointCallback(com.google.zxing.ResultPointCallback) ArrayList(java.util.ArrayList) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) FinderPatternInfo(com.google.zxing.qrcode.detector.FinderPatternInfo) ReaderException(com.google.zxing.ReaderException)

Example 5 with DetectorResult

use of com.google.zxing.common.DetectorResult in project weex-example by KalicyZhou.

the class MultiDetector method detectMulti.

public DetectorResult[] detectMulti(Map<DecodeHintType, ?> hints) throws NotFoundException {
    BitMatrix image = getImage();
    ResultPointCallback resultPointCallback = hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
    MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);
    FinderPatternInfo[] infos = finder.findMulti(hints);
    if (infos.length == 0) {
        throw NotFoundException.getNotFoundInstance();
    }
    List<DetectorResult> result = new ArrayList<>();
    for (FinderPatternInfo info : infos) {
        try {
            result.add(processFinderPatternInfo(info));
        } catch (ReaderException e) {
        // ignore
        }
    }
    if (result.isEmpty()) {
        return EMPTY_DETECTOR_RESULTS;
    } else {
        return result.toArray(new DetectorResult[result.size()]);
    }
}
Also used : ResultPointCallback(com.google.zxing.ResultPointCallback) ArrayList(java.util.ArrayList) DetectorResult(com.google.zxing.common.DetectorResult) BitMatrix(com.google.zxing.common.BitMatrix) FinderPatternInfo(com.google.zxing.qrcode.detector.FinderPatternInfo) ReaderException(com.google.zxing.ReaderException)

Aggregations

DetectorResult (com.google.zxing.common.DetectorResult)25 BitMatrix (com.google.zxing.common.BitMatrix)21 ResultPoint (com.google.zxing.ResultPoint)20 DecoderResult (com.google.zxing.common.DecoderResult)13 Result (com.google.zxing.Result)12 ArrayList (java.util.ArrayList)12 ReaderException (com.google.zxing.ReaderException)8 QRCodeDecoderMetaData (com.google.zxing.qrcode.decoder.QRCodeDecoderMetaData)8 NotFoundException (com.google.zxing.NotFoundException)5 Detector (com.google.zxing.qrcode.detector.Detector)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 ResultPointCallback (com.google.zxing.ResultPointCallback)4 PerspectiveTransform (com.google.zxing.common.PerspectiveTransform)4 Detector (com.google.zxing.datamatrix.detector.Detector)4 MultiDetector (com.google.zxing.multi.qrcode.detector.MultiDetector)4 Version (com.google.zxing.qrcode.decoder.Version)4 FinderPatternInfo (com.google.zxing.qrcode.detector.FinderPatternInfo)4 ChecksumException (com.google.zxing.ChecksumException)1 DecodeHintType (com.google.zxing.DecodeHintType)1