예제 #1
0
        /// <returns> true iff we have found at least 3 finder patterns that have been detected
        /// at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the
        /// candidates is "pretty similar"
        /// </returns>
        private bool haveMultiplyConfirmedCenters()
        {
            int   confirmedCount  = 0;
            float totalModuleSize = 0.0f;
            int   max             = possibleCenters.Count;

            for (int i = 0; i < max; i++)
            {
                FinderPattern pattern = (FinderPattern)possibleCenters[i];
                if (pattern.Count >= CENTER_QUORUM)
                {
                    confirmedCount++;
                    totalModuleSize += pattern.EstimatedModuleSize;
                }
            }
            if (confirmedCount < 3)
            {
                return(false);
            }
            // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
            // and that we need to keep looking. We detect this by asking if the estimated module sizes
            // vary too much. We arbitrarily say that when the total deviation from average exceeds
            // 5% of the total module size estimates, it's too much.
            //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 average        = totalModuleSize / (float)max;
            float totalDeviation = 0.0f;

            for (int i = 0; i < max; i++)
            {
                FinderPattern pattern = (FinderPattern)possibleCenters[i];
                totalDeviation += System.Math.Abs(pattern.EstimatedModuleSize - average);
            }
            return(totalDeviation <= 0.05f * totalModuleSize);
        }
예제 #2
0
        /// <returns> the 3 best <seealso cref="FinderPattern"/>s from our list of candidates. The "best" are
        ///         those that have been detected at least <seealso cref="#CENTER_QUORUM"/> times, and whose module
        ///         size differs from the average among those patterns the least </returns>
        /// <exception cref="NotFoundException"> if 3 such finder patterns do not exist </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private FinderPattern[] selectBestPatterns() throws com.google.zxing.NotFoundException
        private FinderPattern[] selectBestPatterns()
        {
            int startSize = possibleCenters.Count;

            if (startSize < 3)
            {
                // Couldn't find enough finder patterns
                throw NotFoundException.NotFoundInstance;
            }

            // Filter outlier possibilities whose module size is too different
            if (startSize > 3)
            {
                // But we can only afford to do so if we have at least 4 possibilities to choose from
                float totalModuleSize = 0.0f;
                float square          = 0.0f;
                foreach (FinderPattern center in possibleCenters)
                {
                    float size = center.EstimatedModuleSize;
                    totalModuleSize += size;
                    square          += size * size;
                }
                float average = totalModuleSize / (float)startSize;
                float stdDev  = (float)Math.Sqrt(square / startSize - average * average);

                possibleCenters.Sort(new FurthestFromAverageComparator(average));

                float limit = Math.Max(0.2f * average, stdDev);

                for (int i = 0; i < possibleCenters.Count && possibleCenters.Count > 3; i++)
                {
                    FinderPattern pattern = possibleCenters[i];
                    if (Math.Abs(pattern.EstimatedModuleSize - average) > limit)
                    {
                        possibleCenters.RemoveAt(i);
                        i--;
                    }
                }
            }

            if (possibleCenters.Count > 3)
            {
                // Throw away all but those first size candidate points we found.

                float totalModuleSize = 0.0f;
                foreach (FinderPattern possibleCenter in possibleCenters)
                {
                    totalModuleSize += possibleCenter.EstimatedModuleSize;
                }

                float average = totalModuleSize / (float)possibleCenters.Count;

                possibleCenters.Sort(new CenterComparator(average));

                //possibleCenters.subList(3, possibleCenters.Count).clear();
                possibleCenters.RemoveRange(3, possibleCenters.Count - 3);
            }

            return(new FinderPattern[] { possibleCenters[0], possibleCenters[1], possibleCenters[2] });
        }
예제 #3
0
        /// <returns> number of rows we could safely skip during scanning, based on the first
        /// two finder patterns that have been located. In some cases their position will
        /// allow us to infer that the third pattern must lie below a certain point farther
        /// down in the image.
        /// </returns>
        private int findRowSkip()
        {
            int max = possibleCenters.Count;

            if (max <= 1)
            {
                return(0);
            }
            FinderPattern firstConfirmedCenter = null;

            for (int i = 0; i < max; i++)
            {
                FinderPattern center = (FinderPattern)possibleCenters[i];
                if (center.Count >= CENTER_QUORUM)
                {
                    if (firstConfirmedCenter == null)
                    {
                        firstConfirmedCenter = center;
                    }
                    else
                    {
                        // We have two confirmed centers
                        // How far down can we skip before resuming looking for the next
                        // pattern? In the worst case, only the difference between the
                        // difference in the x / y coordinates of the two centers.
                        // This is the case where you find top left last.
                        hasSkipped = true;
                        //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((int)(System.Math.Abs(firstConfirmedCenter.X - center.X) - System.Math.Abs(firstConfirmedCenter.Y - center.Y)) / 2);
                    }
                }
            }
            return(0);
        }
예제 #4
0
        /// <returns> number of rows we could safely skip during scanning, based on the first
        ///         two finder patterns that have been located. In some cases their position will
        ///         allow us to infer that the third pattern must lie below a certain point farther
        ///         down in the image. </returns>
        private int findRowSkip()
        {
            int max = possibleCenters.Count;

            if (max <= 1)
            {
                return(0);
            }
            FinderPattern firstConfirmedCenter = null;

            foreach (FinderPattern center in possibleCenters)
            {
                if (center.Count >= CENTER_QUORUM)
                {
                    if (firstConfirmedCenter == null)
                    {
                        firstConfirmedCenter = center;
                    }
                    else
                    {
                        // We have two confirmed centers
                        // How far down can we skip before resuming looking for the next
                        // pattern? In the worst case, only the difference between the
                        // difference in the x / y coordinates of the two centers.
                        // This is the case where you find top left last.
                        hasSkipped = true;
                        return((int)(Math.Abs(firstConfirmedCenter.X - center.X) - Math.Abs(firstConfirmedCenter.Y - center.Y)) / 2);
                    }
                }
            }
            return(0);
        }
예제 #5
0
        /**
         * @return true iff we have found at least 3 finder patterns that have been detected
         *         at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the
         *         candidates is "pretty similar"
         */
        private bool haveMulitplyConfirmedCenters()
        {
            int   confirmedCount  = 0;
            float totalModuleSize = 0.0f;
            int   max             = possibleCenters.Count;

            for (int i = 0; i < max; i++)
            {
                FinderPattern pattern = (FinderPattern)possibleCenters[i];
                if (pattern.getCount() >= CENTER_QUORUM)
                {
                    confirmedCount++;
                    totalModuleSize += pattern.getEstimatedModuleSize();
                }
            }
            if (confirmedCount < 3)
            {
                return(false);
            }
            // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
            // and that we need to keep looking. We detect this by asking if the estimated module sizes
            // vary too much. We arbitrarily say that when the total deviation from average exceeds
            // 15% of the total module size estimates, it's too much.
            float average        = totalModuleSize / max;
            float totalDeviation = 0.0f;

            for (int i = 0; i < max; i++)
            {
                FinderPattern pattern = (FinderPattern)possibleCenters[i];
                totalDeviation += Math.Abs(pattern.getEstimatedModuleSize() - average);
            }
            return(totalDeviation <= 0.15f * totalModuleSize);
        }
예제 #6
0
        /// <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, ah, cross-cross-check
        /// with another horizontal scan. This is needed primarily to locate the real horizontal
        /// center of the pattern in cases of extreme skew.</p>
        ///
        /// <p>If that succeeds the finder pattern location is added to a list that tracks
        /// the number of times each location has been nearly-matched as a finder pattern.
        /// Each additional find is more evidence that the location is in fact a finder
        /// pattern center
        ///
        /// </summary>
        /// <param name="stateCount">reading state module counts from horizontal scan
        /// </param>
        /// <param name="i">row where finder pattern may be found
        /// </param>
        /// <param name="j">end of possible finder pattern in row
        /// </param>
        /// <returns> true if a finder pattern candidate was found this time
        /// </returns>
        protected internal virtual bool handlePossibleCenter(int[] stateCount, int i, int j)
        {
            int   stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
            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, stateCount[2], stateCountTotal);

            if (!System.Single.IsNaN(centerI))
            {
                // Re-cross check
                //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'"
                centerJ = crossCheckHorizontal((int)centerJ, (int)centerI, stateCount[2], stateCountTotal);
                if (!System.Single.IsNaN(centerJ))
                {
                    //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)stateCountTotal / 7.0f;
                    bool  found = false;
                    int   max   = possibleCenters.Count;
                    for (int index = 0; index < max; index++)
                    {
                        FinderPattern center = (FinderPattern)possibleCenters[index];
                        // Look for about the same center and module size:
                        if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
                        {
                            center.incrementCount();
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        ResultPoint point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
                        possibleCenters.Add(point);
                        if (resultPointCallback != null)
                        {
                            resultPointCallback.foundPossibleResultPoint(point);
                        }
                    }
                    return(true);
                }
            }
            return(false);
        }
예제 #7
0
        /// <returns> the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
        /// those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
        /// size differs from the average among those patterns the least
        /// </returns>
        /// <throws>  ReaderException if 3 such finder patterns do not exist </throws>
        private FinderPattern[] selectBestPatterns()
        {
            int startSize = possibleCenters.Count;

            if (startSize < 3)
            {
                // Couldn't find enough finder patterns
                return(null);
            }

            // Filter outlier possibilities whose module size is too different
            if (startSize > 3)
            {
                // But we can only afford to do so if we have at least 4 possibilities to choose from
                float totalModuleSize = 0.0f;
                for (int i = 0; i < startSize; i++)
                {
                    totalModuleSize += ((FinderPattern)possibleCenters[i]).EstimatedModuleSize;
                }
                //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 average = totalModuleSize / (float)startSize;
                for (int i = 0; i < possibleCenters.Count && possibleCenters.Count > 3; i++)
                {
                    FinderPattern pattern = (FinderPattern)possibleCenters[i];
                    if (System.Math.Abs(pattern.EstimatedModuleSize - average) > 0.2f * average)
                    {
                        possibleCenters.RemoveAt(i);
                        i--;
                    }
                }
            }

            if (possibleCenters.Count > 3)
            {
                // Throw away all but those first size candidate points we found.
                Collections.insertionSort(possibleCenters, new CenterComparator());
                SupportClass.SetCapacity(possibleCenters, 3);
            }

            return(new FinderPattern[] { (FinderPattern)possibleCenters[0], (FinderPattern)possibleCenters[1], (FinderPattern)possibleCenters[2] });
        }
예제 #8
0
        /// <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, ah, cross-cross-check
        /// with another horizontal scan. This is needed primarily to locate the real horizontal
        /// center of the pattern in cases of extreme skew.</p>
        ///
        /// <p>If that succeeds the finder pattern location is added to a list that tracks
        /// the number of times each location has been nearly-matched as a finder pattern.
        /// Each additional find is more evidence that the location is in fact a finder
        /// pattern center
        /// </summary>
        /// <param name="stateCount"> reading state module counts from horizontal scan </param>
        /// <param name="i"> row where finder pattern may be found </param>
        /// <param name="j"> end of possible finder pattern in row </param>
        /// <returns> true if a finder pattern candidate was found this time </returns>
        protected internal bool handlePossibleCenter(int[] stateCount, int i, int j)
        {
            int   stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
            float centerJ         = centerFromEnd(stateCount, j);
            float centerI         = crossCheckVertical(i, (int)centerJ, stateCount[2], stateCountTotal);

            if (!float.IsNaN(centerI))
            {
                // Re-cross check
                centerJ = crossCheckHorizontal((int)centerJ, (int)centerI, stateCount[2], stateCountTotal);
                if (!float.IsNaN(centerJ))
                {
                    float estimatedModuleSize = (float)stateCountTotal / 7.0f;
                    bool  found = false;
                    for (int index = 0; index < possibleCenters.Count; index++)
                    {
                        FinderPattern center = possibleCenters[index];
                        // Look for about the same center and module size:
                        if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
                        {
                            possibleCenters[index] = center.combineEstimate(centerI, centerJ, estimatedModuleSize);
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        FinderPattern point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
                        possibleCenters.Add(point);
                        if (resultPointCallback != null)
                        {
                            resultPointCallback.foundPossibleResultPoint(point);
                        }
                    }
                    return(true);
                }
            }
            return(false);
        }
예제 #9
0
        /**
         * <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, ah, cross-cross-check
         * with another horizontal scan. This is needed primarily to locate the real horizontal
         * center of the pattern in cases of extreme skew.</p>
         *
         * <p>If that succeeds the finder pattern location is added to a list that tracks
         * the number of times each location has been nearly-matched as a finder pattern.
         * Each additional find is more evidence that the location is in fact a finder
         * pattern center
         *
         * @param stateCount reading state module counts from horizontal scan
         * @param i row where finder pattern may be found
         * @param j end of possible finder pattern in row
         * @return true if a finder pattern candidate was found this time
         */
        private bool handlePossibleCenter(int[] stateCount,
                                          int i,
                                          int j)
        {
            int   stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
            float centerJ         = centerFromEnd(stateCount, j);
            float centerI         = crossCheckVertical(i, (int)centerJ, stateCount[2], stateCountTotal);

            if (!Single.IsNaN(centerI))
            {
                // Re-cross check
                centerJ = crossCheckHorizontal((int)centerJ, (int)centerI, stateCount[2], stateCountTotal);
                if (!Single.IsNaN(centerJ))
                {
                    float estimatedModuleSize = (float)stateCountTotal / 7.0f;
                    bool  found = false;
                    int   max   = possibleCenters.Count;
                    for (int index = 0; index < max; index++)
                    {
                        FinderPattern center = (FinderPattern)possibleCenters[index];
                        // Look for about the same center and module size:
                        if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
                        {
                            center.incrementCount();
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        possibleCenters.Add(new FinderPattern(centerJ, centerI, estimatedModuleSize));
                    }
                    return(true);
                }
            }
            return(false);
        }
예제 #10
0
        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, ah, cross-cross-check
		/// with another horizontal scan. This is needed primarily to locate the real horizontal
		/// center of the pattern in cases of extreme skew.</p>
		/// 
		/// <p>If that succeeds the finder pattern location is added to a list that tracks
		/// the number of times each location has been nearly-matched as a finder pattern.
		/// Each additional find is more evidence that the location is in fact a finder
		/// pattern center
		/// 
		/// </summary>
		/// <param name="stateCount">reading state module counts from horizontal scan
		/// </param>
		/// <param name="i">row where finder pattern may be found
		/// </param>
		/// <param name="j">end of possible finder pattern in row
		/// </param>
		/// <returns> true if a finder pattern candidate was found this time
		/// </returns>
		protected internal virtual bool handlePossibleCenter(int[] stateCount, int i, int j)
		{
			int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
			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, stateCount[2], stateCountTotal);
			if (!System.Single.IsNaN(centerI))
			{
				// Re-cross check
				//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'"
				centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2], stateCountTotal);
				if (!System.Single.IsNaN(centerJ))
				{
					//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) stateCountTotal / 7.0f;
					bool found = false;
					int max = possibleCenters.Count;
					for (int index = 0; index < max; index++)
					{
						FinderPattern center = (FinderPattern) possibleCenters[index];
						// Look for about the same center and module size:
						if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
						{
							center.incrementCount();
							found = true;
							break;
						}
					}
					if (!found)
					{
						ResultPoint point = new FinderPattern(centerJ, centerI, estimatedModuleSize);
						possibleCenters.Add(point);
						if (resultPointCallback != null)
						{
							resultPointCallback.foundPossibleResultPoint(point);
						}
					}
					return true;
				}
			}
			return false;
		}
 public FinderPatternInfo(FinderPattern[] patternCenters) {
   this.bottomLeft = patternCenters[0];
   this.topLeft = patternCenters[1];
   this.topRight = patternCenters[2];
 }
예제 #13
0
 public FinderPatternInfo(FinderPattern[] patternCenters)
 {
     this.bottomLeft = patternCenters[0];
     this.topLeft    = patternCenters[1];
     this.topRight   = patternCenters[2];
 }
예제 #14
0
        /**
         * <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));
        }
예제 #15
0
//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));
        }