예제 #1
0
        /// <summary>
        ///   <p>Detects a QR Code in an image.</p>
        /// </summary>
        /// <returns>
        ///   <see cref="DetectorResult"/> encapsulating results of detecting a QR Code
        /// </returns>
        public virtual DetectorResult Detect()
        {
            FinderPatternFinder finder = new FinderPatternFinder(image);
            FinderPatternInfo   info   = finder.Find();

            if (info == null)
            {
                return(null);
            }

            return(ProcessFinderPatternInfo(info));
        }
예제 #2
0
        /// <summary>
        /// Processes the finder pattern info.
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns></returns>
        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)
            {
                return(null);
            }
            if (!ComputeDimension(topLeft, topRight, bottomLeft, moduleSize, out int dimension))
            {
                return(null);
            }
            Version provisionalVersion = Version.GetProvisionalVersionForDimension(dimension);

            if (provisionalVersion == null)
            {
                return(null);
            }
            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)
                {
                    alignmentPattern = FindAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
                    if (alignmentPattern == null)
                    {
                        continue;
                    }
                    break;
                }
                // If we didn't find alignment pattern... well try anyway without it
            }

            PerspectiveTransform transform = CreateTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);

            BitMatrix bits = GridSampler.SampleGrid(image, dimension, dimension, transform);

            if (bits == null)
            {
                return(null);
            }

            ResultPoint[] points;
            if (alignmentPattern == null)
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight };
            }
            else
            {
                points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern };
            }
            return(new DetectorResult(bits, points));
        }