/// <returns> distance between two points /// </returns> public static float distance(ResultPoint pattern1, ResultPoint pattern2) { float xDiff = pattern1.X - pattern2.X; float yDiff = pattern1.Y - pattern2.Y; //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" return (float) Math.Sqrt((double) (xDiff * xDiff + yDiff * yDiff)); }
private GPoint computeCenter(ResultPoint[] resultPoints) { GPoint center = new GPoint(); center.X = Math.Abs(Convert.ToInt32(resultPoints[0].X - (resultPoints[0].X - resultPoints[2].X) * 0.5)); center.Y = Math.Abs(Convert.ToInt32(resultPoints[0].Y - (resultPoints[0].Y - resultPoints[2].Y) * 0.5)); return center; }
public Result(string text, sbyte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format, long timestamp) { this.text = text; this.rawBytes = rawBytes; this.resultPoints = resultPoints; this.format = format; this.resultMetadata = null; this.timestamp = timestamp; }
public void foundPossibleResultPoint (ResultPoint point) { if(point!=null) { //_view.SetArrows(true, true); } else { //_view.SetArrows(false, true); } }
public Result(System.String text, sbyte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format) { if (text == null && rawBytes == null) { throw new System.ArgumentException("Text and bytes are null"); } this.text = text; this.rawBytes = rawBytes; this.resultPoints = resultPoints; this.format = format; this.resultMetadata = null; }
/// <summary> /// <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and /// BC < AC and the angle between BC and BA is less than 180 degrees. /// </summary> public static void orderBestPatterns(ResultPoint[] patterns) { // Find distances between pattern centers float zeroOneDistance = distance(patterns[0], patterns[1]); float oneTwoDistance = distance(patterns[1], patterns[2]); float zeroTwoDistance = distance(patterns[0], patterns[2]); ResultPoint pointA; ResultPoint pointB; ResultPoint pointC; // Assume one closest to other two is B; A and C will just be guesses at first if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) { pointB = patterns[0]; pointA = patterns[1]; pointC = patterns[2]; } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) { pointB = patterns[1]; pointA = patterns[0]; pointC = patterns[2]; } else { pointB = patterns[2]; pointA = patterns[0]; pointC = patterns[1]; } // Use cross product to figure out whether A and C are correct or flipped. // This asks whether BC x BA has a positive z component, which is the arrangement // we want for A, B, C. If it's negative, then we've got it flipped around and // should swap A and C. if (crossProductZ(pointA, pointB, pointC) < 0.0f) { ResultPoint temp = pointA; pointA = pointC; pointC = temp; } patterns[0] = pointA; patterns[1] = pointB; patterns[2] = pointC; }
/// <summary> <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and /// BC < AC and the angle between BC and BA is less than 180 degrees. /// </summary> public static void OrderBestPatterns(ResultPoint[] patterns) { // Find distances between pattern centers float zeroOneDistance = Distance(patterns[0], patterns[1]); float oneTwoDistance = Distance(patterns[1], patterns[2]); float zeroTwoDistance = Distance(patterns[0], patterns[2]); ResultPoint pointA, pointB, pointC; // Assume one closest to other two is B; A and C will just be guesses at first if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) { pointB = patterns[0]; pointA = patterns[1]; pointC = patterns[2]; } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) { pointB = patterns[1]; pointA = patterns[0]; pointC = patterns[2]; } else { pointB = patterns[2]; pointA = patterns[0]; pointC = patterns[1]; } // Use cross product to figure out whether A and C are correct or flipped. // This asks whether BC x BA has a positive z component, which is the arrangement // we want for A, B, C. If it's negative, then we've got it flipped around and // should swap A and C. if (CrossProductZ(pointA, pointB, pointC) < 0.0f) { ResultPoint temp = pointA; pointA = pointC; pointC = temp; } patterns[0] = pointA; patterns[1] = pointB; patterns[2] = pointC; }
/** * <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()); float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.getX(), (int) otherPattern.getY(), (int) pattern.getX(), (int) pattern.getY()); if (Single.IsNaN(moduleSizeEst1)) { return moduleSizeEst2; } if (Single.IsNaN(moduleSizeEst2)) { return moduleSizeEst1; } // Average them, and divide by 7 since we've counted the width of 3 black modules, // and 1 white and 1 black module on either side. Ergo, divide sum by 14. return (moduleSizeEst1 + moduleSizeEst2) / 14.0f; }
/** * <p>Computes an average estimated module size based on estimated derived from the positions * of the three finder patterns.</p> */ private float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft) { // Take the average return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f; }
private static BitMatrix sampleGrid(MonochromeBitmapSource image, ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, ResultPoint alignmentPattern, int dimension) { float dimMinusThree = (float) dimension - 3.5f; float bottomRightX; float bottomRightY; float sourceBottomRightX; float sourceBottomRightY; if (alignmentPattern != null) { bottomRightX = alignmentPattern.getX(); bottomRightY = alignmentPattern.getY(); sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f; } else { // Don't have an alignment pattern, just make up the bottom-right point bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX(); bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY(); sourceBottomRightX = sourceBottomRightY = dimMinusThree; } GridSampler sampler = GridSampler.Instance; return sampler.sampleGrid( image, dimension, 3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree, topLeft.getX(), topLeft.getY(), topRight.getX(), topRight.getY(), bottomRightX, bottomRightY, bottomLeft.getX(), bottomLeft.getY()); }
/** * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position * of the finder patterns and estimated module size.</p> */ private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) { int tltrCentersDimension = round(GenericResultPoint.distance(topLeft, topRight) / moduleSize); int tlblCentersDimension = round(GenericResultPoint.distance(topLeft, bottomLeft) / moduleSize); int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7; switch (dimension & 0x03) { // mod 4 case 0: dimension++; break; // 1? do nothing case 2: dimension--; break; case 3: throw new ReaderException(); } return dimension; }
/// <summary> Returns the z component of the cross product between vectors BC and BA.</summary> private static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) { float bX = pointB.x; float bY = pointB.y; return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX)); }
private double computeRotation(ResultPoint[] resultPoints) { double radians = Math.Atan2((resultPoints[1].Y - resultPoints[2].Y), (resultPoints[1].X - resultPoints[2].X)); double degree = radians * (180 / Math.PI); return -(degree - 180); }
public ResultPointsAndTransitions(ResultPoint from, ResultPoint to, int transitions) { this.from = from; this.to = to; this.transitions = transitions; }
/** * <p>Detects a QR Code in an image, simply.</p> * * @param hints optional hints to detector * @return {@link DetectorResult} encapsulating results of detecting a QR Code * @throws ReaderException if no QR Code can be found */ public DetectorResult detect(System.Collections.Hashtable hints) { 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(hints); FinderPattern topLeft = info.getTopLeft(); FinderPattern topRight = info.getTopRight(); FinderPattern bottomLeft = info.getBottomLeft(); float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft); if (moduleSize < 1.0f) { throw new ReaderException(); } int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize); Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension); int modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7; 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; int estAlignmentX = (int) (topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX())); int estAlignmentY = (int) (topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY())); // Kind of arbitrary -- expand search radius before giving up for (int i = 4; i <= 16; i <<= 1) { try { alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float) i); break; } catch (ReaderException re) { // try next round } } if (alignmentPattern == null) { throw new ReaderException(); } } BitMatrix bits = sampleGrid(image, topLeft, topRight, bottomLeft, alignmentPattern, dimension); ResultPoint[] points; if (alignmentPattern == null) { points = new ResultPoint[]{bottomLeft, topLeft, topRight}; } else { points = new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern}; } return new DetectorResult(bits, points); }
/// <returns> distance between two points </returns> public static float distance(ResultPoint pattern1, ResultPoint pattern2) { return(MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y)); }
//public Result(string text, sbyte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format) // : this(text, rawBytes, resultPoints, format, System.currentTimeMillis()) public Result(string text, sbyte[] rawBytes, ResultPoint[] resultPoints, BarcodeFormat format) : this(text, rawBytes, resultPoints, format, CurrentTimeMillis()) { }
public void addResultPoints(ResultPoint[] newPoints) { ResultPoint[] oldPoints = resultPoints; if (oldPoints == null) { resultPoints = newPoints; } else if (newPoints != null && newPoints.Length > 0) { ResultPoint[] allPoints = new ResultPoint[oldPoints.Length + newPoints.Length]; Array.Copy(oldPoints, 0, allPoints, 0, oldPoints.Length); Array.Copy(newPoints, 0, allPoints, oldPoints.Length, newPoints.Length); resultPoints = allPoints; } }
/// <returns> distance between two points </returns> public static float distance(ResultPoint pattern1, ResultPoint pattern2) { return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y); }
private static BitMatrix sampleGrid(MonochromeBitmapSource image, ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint bottomRight, int dimension) { // We make up the top right point for now, based on the others. // TODO: we actually found a fourth corner above and figured out which of two modules // it was the corner of. We could use that here and adjust for perspective distortion. float topRightX = (bottomRight.getX() - bottomLeft.getX()) + topLeft.getX(); float topRightY = (bottomRight.getY() - bottomLeft.getY()) + topLeft.getY(); // Note that unlike in the QR Code sampler, we didn't find the center of modules, but the // very corners. So there is no 0.5f here; 0.0f is right. GridSampler sampler = GridSampler.Instance; return sampler.sampleGrid( image, dimension, 0.0f, 0.0f, dimension, 0.0f, dimension, dimension, 0.0f, dimension, topLeft.getX(), topLeft.getY(), topRightX, topRightY, bottomRight.getX(), bottomRight.getY(), bottomLeft.getX(), bottomLeft.getY()); }
/** * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm. */ private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to) { // See QR Code Detector, sizeOfBlackWhiteBlackRun() int fromX = (int) from.getX(); int fromY = (int) from.getY(); int toX = (int) to.getX(); int toY = (int) to.getY(); bool steep = Math.Abs(toY - fromY) > Math.Abs(toX - fromX); if (steep) { int temp = fromX; fromX = fromY; fromY = temp; temp = toX; toX = toY; toY = temp; } int dx = Math.Abs(toX - fromX); int dy = Math.Abs(toY - fromY); int error = -dx >> 1; int ystep = fromY < toY ? 1 : -1; int xstep = fromX < toX ? 1 : -1; int transitions = 0; bool inBlack = image.isBlack(steep ? fromY : fromX, steep ? fromX : fromY); for (int x = fromX, y = fromY; x != toX; x += xstep) { bool isBlack = image.isBlack(steep ? y : x, steep ? x : y); if (isBlack == !inBlack) { transitions++; inBlack = isBlack; } error += dy; if (error > 0) { y += ystep; error -= dx; } } return new ResultPointsAndTransitions(from, to, transitions); }
private void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) { canvas.DrawLine(a.X, a.Y, b.X, b.Y, paint); }
/** * Increments the int associated with a key by one. */ private static void increment(System.Collections.Hashtable table, ResultPoint key) { int value = (int) table[key]; table[key] = value.Equals(null) ? intS[1] : intS[value + 1]; //table.put(key, value == null ? intS[1] : intS[value.intValue() + 1]); }