/// <summary> <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will see if this pattern had been /// found on a previous horizontal scan. If so, we consider it confirmed and conclude we have /// found the alignment pattern.</p> /// /// </summary> /// <param name="stateCount">reading state module counts from horizontal scan /// </param> /// <param name="i">row where alignment pattern may be found /// </param> /// <param name="j">end of possible alignment pattern in row /// </param> /// <returns> {@link AlignmentPattern} if we have found the same pattern twice, or null if not /// </returns> private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; float centerJ = centerFromEnd(stateCount, j); //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'" float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal); if (!System.Single.IsNaN(centerI)) { //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'" float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; int max = possibleCenters.Count; for (int index = 0; index < max; index++) { AlignmentPattern center = (AlignmentPattern)possibleCenters[index]; // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) { return(new AlignmentPattern(centerJ, centerI, estimatedModuleSize)); } } // Hadn't found this before; save it ResultPoint point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback.foundPossibleResultPoint(point); } } return(null); }
/// <summary> /// <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will see if this pattern had been /// found on a previous horizontal scan. If so, we consider it confirmed and conclude we have /// found the alignment pattern.</p> /// </summary> /// <param name="stateCount"> reading state module counts from horizontal scan </param> /// <param name="i"> row where alignment pattern may be found </param> /// <param name="j"> end of possible alignment pattern in row </param> /// <returns> <seealso cref="AlignmentPattern"/> if we have found the same pattern twice, or null if not </returns> private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; float centerJ = centerFromEnd(stateCount, j); float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal); if (!float.IsNaN(centerI)) { float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; foreach (AlignmentPattern center in possibleCenters) { // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) { return(center.combineEstimate(centerI, centerJ, estimatedModuleSize)); } } // Hadn't found this before; save it AlignmentPattern point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback.foundPossibleResultPoint(point); } } return(null); }
/** * <p>This is called when a horizontal scan finds a possible alignment pattern. It will * cross check with a vertical scan, and if successful, will see if this pattern had been * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have * found the alignment pattern.</p> * * @param stateCount reading state module counts from horizontal scan * @param i row where alignment pattern may be found * @param j end of possible alignment pattern in row * @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not */ private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; float centerJ = centerFromEnd(stateCount, j); float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal); if (!Single.IsNaN(centerI)) { float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; int max = possibleCenters.Count; for (int index = 0; index < max; index++) { AlignmentPattern center = (AlignmentPattern)possibleCenters[index]; // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) { return(new AlignmentPattern(centerJ, centerI, estimatedModuleSize)); } } // Hadn't found this before; save it possibleCenters.Add(new AlignmentPattern(centerJ, centerI, estimatedModuleSize)); } return(null); }
protected internal virtual DetectorResult processFinderPatternInfo(FinderPatternInfo info) { FinderPattern topLeft = info.TopLeft; FinderPattern topRight = info.TopRight; FinderPattern bottomLeft = info.BottomLeft; float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft); if (moduleSize < 1.0f) { throw ReaderException.Instance; } int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize); Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension); int modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7; AlignmentPattern alignmentPattern = null; // Anything above version 1 has an alignment pattern if (provisionalVersion.AlignmentPatternCenters.Length > 0) { // Guess where a "bottom right" finder pattern would have been float bottomRightX = topRight.X - topLeft.X + bottomLeft.X; float bottomRightY = topRight.Y - topLeft.Y + bottomLeft.Y; // Estimate that alignment pattern is closer by 3 modules // from "bottom right" to known top left location //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'" float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters; //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'" int estAlignmentX = (int)(topLeft.X + correctionToTopLeft * (bottomRightX - topLeft.X)); //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'" int estAlignmentY = (int)(topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y)); // Kind of arbitrary -- expand search radius before giving up for (int i = 4; i <= 16; i <<= 1) { try { //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'" alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i); break; } catch (ReaderException re) { // try next round } } // If we didn't find alignment pattern... well try anyway without it } PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension); BitMatrix bits = sampleGrid(image, transform, 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)); }
/// <summary> <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will see if this pattern had been /// found on a previous horizontal scan. If so, we consider it confirmed and conclude we have /// found the alignment pattern.</p> /// /// </summary> /// <param name="stateCount">reading state module counts from horizontal scan /// </param> /// <param name="i">row where alignment pattern may be found /// </param> /// <param name="j">end of possible alignment pattern in row /// </param> /// <returns> {@link AlignmentPattern} if we have found the same pattern twice, or null if not /// </returns> private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; float centerJ = centerFromEnd(stateCount, j); //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'" float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1], stateCountTotal); if (!System.Single.IsNaN(centerI)) { //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'" float estimatedModuleSize = (float) (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; int max = possibleCenters.Count; for (int index = 0; index < max; index++) { AlignmentPattern center = (AlignmentPattern) possibleCenters[index]; // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) { return new AlignmentPattern(centerJ, centerI, estimatedModuleSize); } } // Hadn't found this before; save it ResultPoint point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback.foundPossibleResultPoint(point); } } return null; }
/// <summary> <p>This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since /// it's pretty performance-critical and so is written to be fast foremost.</p> /// /// </summary> /// <returns> {@link AlignmentPattern} if found /// </returns> /// <throws> ReaderException if not found </throws> internal AlignmentPattern find() { int startX = this.startX; int height = this.height; int maxJ = startX + width; int middleI = startY + (height >> 1); // We are looking for black/white/black modules in 1:1:1 ratio; // this tracks the number of black/white/black modules seen so far int[] stateCount = new int[3]; for (int iGen = 0; iGen < height; iGen++) { // Search from middle outwards int i = middleI + ((iGen & 0x01) == 0?((iGen + 1) >> 1):-((iGen + 1) >> 1)); stateCount[0] = 0; stateCount[1] = 0; stateCount[2] = 0; int j = startX; // Burn off leading white pixels before anything else; if we start in the middle of // a white run, it doesn't make sense to count its length, since we don't know if the // white run continued to the left of the start point while (j < maxJ && !image.get_Renamed(j, i)) { j++; } int currentState = 0; while (j < maxJ) { if (image.get_Renamed(j, i)) { // Black pixel if (currentState == 1) { // Counting black pixels stateCount[currentState]++; } else { // Counting white pixels if (currentState == 2) { // A winner? if (foundPatternCross(stateCount)) { // Yes AlignmentPattern confirmed = handlePossibleCenter(stateCount, i, j); if (confirmed != null) { return(confirmed); } } stateCount[0] = stateCount[2]; stateCount[1] = 1; stateCount[2] = 0; currentState = 1; } else { stateCount[++currentState]++; } } } else { // White pixel if (currentState == 1) { // Counting black pixels currentState++; } stateCount[currentState]++; } j++; } if (foundPatternCross(stateCount)) { AlignmentPattern confirmed = handlePossibleCenter(stateCount, i, maxJ); if (confirmed != null) { return(confirmed); } } } // Hmm, nothing we saw was observed and confirmed twice. If we had // any guess at all, return it. if (!(possibleCenters.Count == 0)) { return((AlignmentPattern)possibleCenters[0]); } throw ReaderException.Instance; }
/// <summary> /// <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will see if this pattern had been /// found on a previous horizontal scan. If so, we consider it confirmed and conclude we have /// found the alignment pattern.</p> /// </summary> /// <param name="stateCount"> reading state module counts from horizontal scan </param> /// <param name="i"> row where alignment pattern may be found </param> /// <param name="j"> end of possible alignment pattern in row </param> /// <returns> <seealso cref="AlignmentPattern"/> if we have found the same pattern twice, or null if not </returns> private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; float centerJ = centerFromEnd(stateCount, j); float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1], stateCountTotal); if (!float.IsNaN(centerI)) { float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; foreach (AlignmentPattern center in possibleCenters) { // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) { return center.combineEstimate(centerI, centerJ, estimatedModuleSize); } } // Hadn't found this before; save it AlignmentPattern point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback.foundPossibleResultPoint(point); } } return null; }
/** * <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)); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: protected final com.google.zxing.common.DetectorResult processFinderPatternInfo(FinderPatternInfo info) throws com.google.zxing.NotFoundException, com.google.zxing.FormatException protected internal DetectorResult processFinderPatternInfo(FinderPatternInfo info) { FinderPattern topLeft = info.TopLeft; FinderPattern topRight = info.TopRight; FinderPattern bottomLeft = info.BottomLeft; float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft); if (moduleSize < 1.0f) { throw NotFoundException.NotFoundInstance; } int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize); Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension); int modulesBetweenFPCenters = provisionalVersion.DimensionForVersion - 7; AlignmentPattern alignmentPattern = null; // Anything above version 1 has an alignment pattern if (provisionalVersion.AlignmentPatternCenters.Length > 0) { // Guess where a "bottom right" finder pattern would have been float bottomRightX = topRight.X - topLeft.X + bottomLeft.X; float bottomRightY = topRight.Y - topLeft.Y + bottomLeft.Y; // 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.X + correctionToTopLeft * (bottomRightX - topLeft.X)); int estAlignmentY = (int)(topLeft.Y + correctionToTopLeft * (bottomRightY - topLeft.Y)); // 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 (NotFoundException re) { // try next round } } // If we didn't find alignment pattern... well try anyway without it } PerspectiveTransform transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension); BitMatrix bits = sampleGrid(image, transform, 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)); }