Exemplo n.º 1
0
        public Tuple <TupleList, Image <int, T> > Run <T>(
            Image <double, T> scaledImage,
            double scale,
            double quantizationErrorBound = 2.0,
            double angleThreshold         = 22.5,
            double detectionThreshold     = 0.0,
            double densityThreshold       = 0.7,
            int numberOfBins = 1024)
        {
            var precision = Math.PI * angleThreshold / 180.0;
            var probabilityOfPointWithAngleWithinPrecision = angleThreshold / 180.0;
            var gradientMagnitudeThreshold = quantizationErrorBound / Math.Sin(precision);

            var levelLineResult = _levelLineCalculator.CreateLevelLineImage(scaledImage, gradientMagnitudeThreshold, numberOfBins);

            var angles           = levelLineResult.GradientImage;
            var modGradientImage = levelLineResult.ModGradientImage;
            var coordinates      = levelLineResult.CoordinatesOrderedByDecreasingGradientMagnitude;

            var width  = angles.Width;
            var height = angles.Height;

            var logNumberOfTests  = 5.0 * (Math.Log10(width) + Math.Log10(height)) / 2.0 + Math.Log10(11.0);
            var minimumRegionSize = (int)(-logNumberOfTests / Math.Log10(probabilityOfPointWithAngleWithinPrecision));
            var used = new Image <bool, T>(width, height, scaledImage.Metadata);

            var lineSegments = new TupleList(7);
            var regionOutput = new Image <int, T>(angles.Width, angles.Height, angles.Metadata);

            foreach (var coordinate in coordinates)
            {
                try
                {
                    // ReSharper disable once CompareOfFloatsByEqualityOperator
                    if (used[coordinate] || angles[coordinate] == MathHelpers.NoAngle)
                    {
                        continue;
                    }

                    var region = Region <T> .Create(coordinate, angles, modGradientImage, used, precision);

                    if (region.Size < minimumRegionSize)
                    {
                        continue;
                    }

                    var rectangle = region.ToRectangle(probabilityOfPointWithAngleWithinPrecision);

                    // Rectangle must be updated by the refine call
                    if (!region.Refine(densityThreshold, ref rectangle))
                    {
                        continue;
                    }

                    var logNumberOfFalseAlarms = rectangle.Improve(logNumberOfTests, detectionThreshold);

                    if (logNumberOfFalseAlarms <= detectionThreshold)
                    {
                        continue;
                    }

                    rectangle.FirstPoint.X  += 0.5;
                    rectangle.SecondPoint.X += 0.5;
                    rectangle.FirstPoint.Y  += 0.5;
                    rectangle.SecondPoint.Y += 0.5;

                    if (!scale.IsRoughlyEqualTo(1))
                    {
                        rectangle.FirstPoint.X  /= scale;
                        rectangle.FirstPoint.Y  /= scale;
                        rectangle.SecondPoint.X /= scale;
                        rectangle.SecondPoint.Y /= scale;
                        rectangle.Width         /= scale;
                    }

                    lineSegments.AddTuple(
                        rectangle.FirstPoint.X, rectangle.FirstPoint.Y,
                        rectangle.SecondPoint.X, rectangle.SecondPoint.Y,
                        rectangle.Width,
                        rectangle.ProbabilityOfPointWithAngleWithinPrecision,
                        logNumberOfFalseAlarms);

                    // Add the region to the image
                    foreach (var point in region.Points)
                    {
                        // Use the number of line segments so far to identify this
                        // particular line segment.
                        regionOutput[point] = lineSegments.Size;
                    }
                } catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw e;
                }
            }

            return(Tuple.Create(lineSegments, regionOutput));
        }