private static void GenerateRandomMixtureComponent(
            MicrosoftResearch.Infer.Maths.Vector min, MicrosoftResearch.Infer.Maths.Vector max, out MicrosoftResearch.Infer.Maths.Vector mean, out PositiveDefiniteMatrix covariance)
        {
            Debug.Assert(min != null && max != null);
            Debug.Assert(min.Count == max.Count);

            MicrosoftResearch.Infer.Maths.Vector diff = max - min;

            mean = MicrosoftResearch.Infer.Maths.Vector.Zero(min.Count);
            for (int i = 0; i < min.Count; ++i)
            {
                mean[i] = min[i] + diff[i] * Random.Double();
            }

            covariance = PositiveDefiniteMatrix.IdentityScaledBy(
                min.Count,
                MicrosoftResearch.Infer.Maths.Vector.InnerProduct(diff, diff) / 16);
        }
        //private static void MainForDualDecomposition()
        //{
        //    ShapeModel shapeModel = CreateSimpleShapeModel1();
        //    ShapeConstraints constraints = ShapeConstraints.CreateFromConstraints(
        //        shapeModel,
        //        new[] { new VertexConstraints(new Vector(3, 0), new Vector(40, 40)), new VertexConstraints(new Vector(60, 10), new Vector(100, 50)) },
        //        new[] { new EdgeConstraints(10, 20) },
        //        1,
        //        1);
        //    Image2D<Color> image = Image2D.LoadFromFile("../../../images/simple_1.png", 0.2);
        //    Rectangle objectLocation = new Rectangle(30, 24, 159, 96);
        //    ImageSegmentator segmentator = new ImageSegmentator(image, objectLocation, 0.01, 0, 1, 0.05, 3);
        //    LowerBoundCalculator lowerBoundCalculator = new LowerBoundCalculator(segmentator);
        //    lowerBoundCalculator.CalculateLowerBound(constraints);
        //}

        static void Main()
        {
            Random.SetSeed(666);

            //MainForGiraffeAdjustSave();
            MainForLetterSave();
            //PrintColorModels();
            //MainForDualDecomposition();
            //MainForPointIsClosestExperiment();
            //MainForLengthAngleDependenceExperiment();
            //MainForGiraffeSave();
            //GenerateMeanShape();
            //DrawLengthAngleDependence();
            //MainForUnaryPotentialsCheck();
            //MainForSegmentation();
            //MainForConvexHull();
            //MainForShapeEnergyCheck();
        }
 public VertexConstraints CollapseRandomly()
 {
     return new VertexConstraints(new Vector(
         this.MinCoord.X + (this.MaxCoord.X - this.MinCoord.X) * Random.Double(),
         this.MinCoord.Y + (this.MaxCoord.Y - this.MinCoord.Y) * Random.Double()));
 }
예제 #4
0
 public EdgeConstraints CollapseRandomly()
 {
     return(new EdgeConstraints(this.MinWidth + this.Freedom * Random.Double()));
 }
        static void LengthAngleDependenceExperiment(
            VertexConstraints constraint1, VertexConstraints constraint2, string fileName)
        {
            const int GeneratedPointCount = 100000;

            List <Vector> lengthAnglePoints = new List <Vector>();
            double        maxLength         = 0;

            for (int i = 0; i < GeneratedPointCount; ++i)
            {
                double randomX1 = constraint1.MinCoord.X + Random.Double() * (constraint1.MaxCoord.X - constraint1.MinCoord.X);
                double randomY1 = constraint1.MinCoord.Y + Random.Double() * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y);
                double randomX2 = constraint2.MinCoord.X + Random.Double() * (constraint2.MaxCoord.X - constraint2.MinCoord.X);
                double randomY2 = constraint2.MinCoord.Y + Random.Double() * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y);
                Vector vector1  = new Vector(randomX1, randomY1);
                Vector vector2  = new Vector(randomX2, randomY2);
                if (vector1 == vector2)
                {
                    continue;
                }

                Vector diff   = vector2 - vector1;
                double length = diff.Length;
                double angle  = Vector.AngleBetween(Vector.UnitX, diff);
                lengthAnglePoints.Add(new Vector(length, angle));

                maxLength = Math.Max(maxLength, length);
            }

            //ShapeConstraints constraintSet = ShapeConstraints.CreateFromConstraints(
            //    CreateSimpleShapeModel1(),
            //    new[] { constraint1, constraint2 },
            //    new[] { new EdgeConstraints(1) },
            //    1,
            //    1);
            BoxSetLengthAngleConstraints lengthAngleConstraints =
                BoxSetLengthAngleConstraints.FromVertexConstraints(constraint1, constraint2, 2, 0);

            const int lengthImageSize = 360;
            const int angleImageSize  = 360;
            double    lengthScale     = (lengthImageSize - 20) / maxLength;

            //Image2D<bool> myAwesomeMask = new Image2D<bool>(lengthImageSize, angleImageSize);
            //LengthAngleSpaceSeparatorSet myAwesomeSeparator = new LengthAngleSpaceSeparatorSet(constraint1, constraint2);
            //for (int i = 0; i < lengthImageSize; ++i)
            //    for (int j = 0; j < angleImageSize; ++j)
            //    {
            //        double length = i / lengthScale;
            //        double angle = MathHelper.ToRadians(j - 180.0);
            //        if (myAwesomeSeparator.IsInside(length, angle))
            //            myAwesomeMask[i, j] = true;
            //    }

            using (Bitmap image = new Bitmap(lengthImageSize, angleImageSize))
                using (Graphics graphics = Graphics.FromImage(image))
                {
                    graphics.Clear(Color.White);

                    // Draw generated points
                    for (int i = 0; i < lengthAnglePoints.Count; ++i)
                    {
                        DrawLengthAngle(graphics, Pens.Black, lengthAnglePoints[i].X, lengthAnglePoints[i].Y, lengthScale, 1);
                    }

                    // Draw estimated ranges
                    foreach (BoxLengthAngleConstraints child in lengthAngleConstraints.ChildConstraints)
                    {
                        DrawLengthAngleConstraintBox(graphics, Pens.Green, child, lengthScale);
                    }
                    DrawLengthAngleConstraintBox(graphics, new Pen(Color.Red, 2), lengthAngleConstraints.OverallRange, lengthScale);

                    // Draw constraint corners
                    //for (int i = 0; i < 4; ++i)
                    //{
                    //    for (int j = 0; j < 4; ++j)
                    //    {
                    //        Vector diff = constraint2.Corners[j] - constraint1.Corners[i];
                    //        DrawLengthAngle(diff.Length, Vector.AngleBetween(Vector.UnitX, diff), lengthScale, 5, graphics, Pens.Blue);
                    //    }
                    //}

                    // Draw my awesome separation lines
                    //for (int i = 0; i < lengthImageSize - 1; ++i)
                    //    for (int j = 0; j < lengthImageSize - 1; ++j)
                    //    {
                    //        bool border = false;
                    //        border |= myAwesomeMask[i, j] != myAwesomeMask[i + 1, j];
                    //        border |= myAwesomeMask[i, j] != myAwesomeMask[i, j + 1];
                    //        border |= myAwesomeMask[i, j] != myAwesomeMask[i + 1, j + 1];
                    //        if (border)
                    //            image.SetPixel(i, j, Color.Orange);
                    //    }

                    //graphics.DrawString(
                    //    String.Format("Max length is {0:0.0}", maxLength), SystemFonts.DefaultFont, Brushes.Green, 5, 5);

                    image.Save(fileName);
                }
        }
        static void PointIsClosestExperiment(
            Vector point,
            VertexConstraints point1Constraints,
            VertexConstraints point2Constraints,
            string fileName)
        {
            Console.WriteLine(string.Format("Doing experiment for {0}", fileName));

            Bitmap    image      = new Bitmap(320, 240);
            const int iterations = 200000;

            using (Graphics graphics = Graphics.FromImage(image))
            {
                for (int i = 0; i < iterations; ++i)
                {
                    Vector point1 = new Vector(
                        point1Constraints.MinCoord.X + (point1Constraints.MaxCoord.X - point1Constraints.MinCoord.X) * Random.Double(),
                        point1Constraints.MinCoord.Y + (point1Constraints.MaxCoord.Y - point1Constraints.MinCoord.Y) * Random.Double());
                    Vector point2 = new Vector(
                        point2Constraints.MinCoord.X + (point2Constraints.MaxCoord.X - point2Constraints.MinCoord.X) * Random.Double(),
                        point2Constraints.MinCoord.Y + (point2Constraints.MaxCoord.Y - point2Constraints.MinCoord.Y) * Random.Double());

                    double distanceSqr, alpha;
                    point.DistanceToSegmentSquared(point1, point2, out distanceSqr, out alpha);
                    alpha = MathHelper.Trunc(alpha, 0, 1);
                    Vector      closestPoint = point1 + (point2 - point1) * alpha;
                    const float radius       = 2;
                    graphics.FillEllipse(
                        Brushes.Green,
                        (float)closestPoint.X - radius,
                        (float)closestPoint.Y - radius,
                        radius * 2,
                        radius * 2);
                }

                graphics.DrawRectangle(
                    Pens.Blue,
                    point1Constraints.CoordRectangle.Left,
                    point1Constraints.CoordRectangle.Top,
                    point1Constraints.CoordRectangle.Width,
                    point1Constraints.CoordRectangle.Height);
                graphics.DrawRectangle(
                    Pens.Blue,
                    point2Constraints.CoordRectangle.Left,
                    point2Constraints.CoordRectangle.Top,
                    point2Constraints.CoordRectangle.Width,
                    point2Constraints.CoordRectangle.Height);
                graphics.FillEllipse(Brushes.Red, (float)point.X - 2, (float)point.Y - 2, 4, 4);
            }

            image.Save(fileName);
        }
        private static void TestEdgeLimitsCommonImpl(
            VertexConstraints constraint1, VertexConstraints constraint2, out Range lengthRange, out Range angleRange)
        {
            BoxSetLengthAngleConstraints lengthAngleConstraints =
                BoxSetLengthAngleConstraints.FromVertexConstraints(constraint1, constraint2, 3, 0);
            GeneralizedDistanceTransform2D transform = new GeneralizedDistanceTransform2D(
                new Range(0, 35), new Range(-Math.PI * 2, Math.PI * 2), new Size(2000, 2000));
            AllowedLengthAngleChecker allowedLengthAngleChecker = new AllowedLengthAngleChecker(constraint1, constraint2, transform, 1, 0);

            lengthRange = lengthAngleConstraints.LengthBoundary;
            angleRange  = lengthAngleConstraints.AngleBoundary;

            const int insideCheckCount = 1000;

            for (int i = 0; i < insideCheckCount; ++i)
            {
                Vector edgePoint1 =
                    constraint1.MinCoord +
                    new Vector(
                        Random.Double() * (constraint1.MaxCoord.X - constraint1.MinCoord.X),
                        Random.Double() * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y));
                Vector edgePoint2 =
                    constraint2.MinCoord +
                    new Vector(
                        Random.Double() * (constraint2.MaxCoord.X - constraint2.MinCoord.X),
                        Random.Double() * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y));

                Vector vec    = edgePoint2 - edgePoint1;
                double length = vec.Length;
                double angle  = Vector.AngleBetween(Vector.UnitX, vec);

                const double tolerance = 1e-10;
                Assert.IsTrue(lengthAngleConstraints.InRange(length, tolerance, angle, tolerance));
                Assert.IsTrue(lengthAngleConstraints.OverallRange.InRange(length, tolerance, angle, tolerance));
                Assert.IsTrue(allowedLengthAngleChecker.IsAllowed(length, angle));
            }

            const int outsideCheckCount = 1000;

            for (int i = 0; i < outsideCheckCount; ++i)
            {
                Vector edgePoint1 =
                    constraint1.MinCoord +
                    new Vector(
                        (Random.Double() * 2 - 0.5) * (constraint1.MaxCoord.X - constraint1.MinCoord.X),
                        (Random.Double() * 2 - 0.5) * (constraint1.MaxCoord.Y - constraint1.MinCoord.Y));
                Vector edgePoint2 =
                    constraint2.MinCoord +
                    new Vector(
                        (Random.Double() * 2 - 0.5) * (constraint2.MaxCoord.X - constraint2.MinCoord.X),
                        (Random.Double() * 2 - 0.5) * (constraint2.MaxCoord.Y - constraint2.MinCoord.Y));

                Vector vec    = edgePoint2 - edgePoint1;
                double length = vec.Length;
                double angle  = Vector.AngleBetween(Vector.UnitX, vec);

                // We've generated too long edge
                if (length > transform.RangeX.Right)
                {
                    continue;
                }

                bool definitelyOutside = !lengthAngleConstraints.OverallRange.InRange(length, 1e-6, angle, 1e-6);
                Assert.IsTrue(!definitelyOutside || !allowedLengthAngleChecker.IsAllowed(length, angle));
                Assert.IsTrue(!definitelyOutside || !lengthAngleConstraints.InRange(length, 1e-6, angle, 1e-6));
            }
        }
예제 #8
0
        public Shape MutateShape(Shape shape, ShapeModel shapeModel, Size imageSize, double normalizedTemperature)
        {
            if (shape == null)
            {
                throw new ArgumentNullException("shape");
            }
            if (shapeModel == null)
            {
                throw new ArgumentNullException("shapeModel");
            }

            double maxImageSideSize = Math.Max(imageSize.Width, imageSize.Height);
            Shape  mutatedShape;

            double weightSum =
                this.edgeWidthMutationWeight +
                this.edgeLengthMutationWeight +
                this.edgeAngleMutationWeight +
                this.shapeTranslationWeight +
                this.shapeScaleWeight;

            if (weightSum <= 0)
            {
                throw new InvalidOperationException("At least one type of mutation should have non-zero probability weight.");
            }
            double rand = Random.Double(0, weightSum);

            // Shape part mutation
            if (rand < this.edgeWidthMutationWeight + this.edgeLengthMutationWeight + this.edgeAngleMutationWeight)
            {
                ShapeLengthAngleRepresentation representation = shape.GetLengthAngleRepresentation();
                int randomEdge = Random.Int(shape.Structure.Edges.Count);

                // Mutate edge width
                if (rand < this.edgeWidthMutationWeight)
                {
                    double       widthShiftStdDev = maxImageSideSize * this.edgeWidthMutationPower * normalizedTemperature;
                    const double minWidth         = 3;
                    double       widthShift       = Random.Normal(0, widthShiftStdDev, -shape.EdgeWidths[randomEdge] + minWidth);
                    representation.EdgeWidths[randomEdge] += widthShift;
                }
                // Mutate edge length
                else if (rand < this.edgeWidthMutationWeight + this.edgeLengthMutationWeight)
                {
                    double lengthShiftStdDev = maxImageSideSize * this.edgeLengthMutationPower * normalizedTemperature;
                    double lengthShift       = Random.Normal(0, lengthShiftStdDev);
                    representation.EdgeLengths[randomEdge] += lengthShift;
                }
                // Mutate edge angle
                else
                {
                    double angleShiftStdDev = this.edgeAngleMutationPower * normalizedTemperature;
                    double angleShift       = Random.Normal(0, angleShiftStdDev);
                    representation.EdgeAngles[randomEdge] += angleShift;
                }

                mutatedShape = shapeModel.BuildShapeFromLengthAngleRepresentation(representation);
            }
            // Whole shape mutation
            else
            {
                rand        -= this.edgeWidthMutationWeight + this.edgeLengthMutationWeight + this.edgeAngleMutationWeight;
                mutatedShape = shape.Clone();

                // Translate shape
                if (rand < this.shapeTranslationWeight)
                {
                    Vector maxTopLeftShift     = new Vector(Double.NegativeInfinity, Double.NegativeInfinity);
                    Vector minBottomRightShift = new Vector(Double.PositiveInfinity, Double.PositiveInfinity);
                    for (int i = 0; i < mutatedShape.VertexPositions.Count; ++i)
                    {
                        maxTopLeftShift.X     = Math.Max(maxTopLeftShift.X, -mutatedShape.VertexPositions[i].X);
                        maxTopLeftShift.Y     = Math.Max(maxTopLeftShift.Y, -mutatedShape.VertexPositions[i].Y);
                        minBottomRightShift.X = Math.Min(minBottomRightShift.X, imageSize.Width - mutatedShape.VertexPositions[i].X);
                        minBottomRightShift.Y = Math.Min(minBottomRightShift.Y, imageSize.Height - mutatedShape.VertexPositions[i].Y);
                    }

                    double translationStdDev = maxImageSideSize * this.shapeTranslationPower * normalizedTemperature;
                    Vector shift             = new Vector(Random.Normal(0, translationStdDev), Random.Normal(0, translationStdDev));
                    shift = MathHelper.Trunc(shift, maxTopLeftShift, minBottomRightShift);

                    for (int i = 0; i < mutatedShape.VertexPositions.Count; ++i)
                    {
                        mutatedShape.VertexPositions[i] += shift;
                    }
                }
                // Scale shape
                else
                {
                    Vector       shapeCenter = shape.VertexPositions.Aggregate(Vector.Zero, (a, c) => a + c) / shape.VertexPositions.Count;
                    double       scaleStdDev = this.shapeScalePower * normalizedTemperature;
                    const double minScale    = 0.1;
                    double       scale       = Random.Normal(1.0, scaleStdDev, minScale);
                    for (int i = 0; i < mutatedShape.VertexPositions.Count; ++i)
                    {
                        mutatedShape.VertexPositions[i] = shapeCenter + scale * (mutatedShape.VertexPositions[i] - shapeCenter);
                    }
                }
            }

            Debug.Assert(mutatedShape != null);
            return(mutatedShape);
        }
        private void DoSegmentation(object sender, DoWorkEventArgs e)
        {
            Random.SetSeed(666);

            // Load and downscale image
            Image2D <Color> originalImage   = Image2D.LoadFromFile(this.segmentationProperties.ImageToSegment);
            double          scale           = this.segmentationProperties.DownscaledImageSize / (double)Math.Max(originalImage.Width, originalImage.Height);
            Image2D <Color> downscaledImage = Image2D.LoadFromFile(this.segmentationProperties.ImageToSegment, scale);

            this.segmentedImage = Image2D.ToRegularImage(downscaledImage);

            // Load color models
            ObjectBackgroundColorModels colorModels = ObjectBackgroundColorModels.LoadFromFile(this.segmentationProperties.ColorModel);

            // Setup shape model
            ShapeModel model = ShapeModel.LoadFromFile(this.segmentationProperties.ShapeModel);

            this.segmentator.ShapeModel = model;

            // Common settings
            segmentator.ObjectColorUnaryTermWeight        = this.segmentationProperties.ObjectColorUnaryTermWeight;
            segmentator.BackgroundColorUnaryTermWeight    = this.segmentationProperties.BackgroundColorUnaryTermWeight;
            segmentator.ObjectShapeUnaryTermWeight        = this.segmentationProperties.ObjectShapeUnaryTermWeight;
            segmentator.BackgroundShapeUnaryTermWeight    = this.segmentationProperties.BackgroundShapeUnaryTermWeight;
            segmentator.ColorDifferencePairwiseTermWeight = this.segmentationProperties.ColorDifferencePairwiseTermWeight;
            segmentator.ColorDifferencePairwiseTermCutoff = this.segmentationProperties.ColorDifferencePairwiseTermCutoff;
            segmentator.ConstantPairwiseTermWeight        = this.segmentationProperties.ConstantPairwiseTermWeight;
            segmentator.ShapeEnergyWeight = this.segmentationProperties.ShapeEnergyWeight;

            // Custom setup
            if (this.segmentator is BranchAndBoundSegmentationAlgorithm)
            {
                this.SetupBranchAndBoundSegmentationAlgorithm((BranchAndBoundSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is CoordinateDescentSegmentationAlgorithm)
            {
                this.SetupCoordinateDescentSegmentationAlgorithm((CoordinateDescentSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is AnnealingSegmentationAlgorithm)
            {
                this.SetupAnnealingSegmentationAlgorithm((AnnealingSegmentationAlgorithm)this.segmentator);
            }
            else if (this.segmentator is SimpleSegmentationAlgorithm)
            {
                this.SetupSimpleSegmentationAlgorithm((SimpleSegmentationAlgorithm)this.segmentator);
            }

            // Show original image in status window)
            this.currentImage.Image = (Image)this.segmentedImage.Clone();

            // Run segmentation
            SegmentationSolution solution = segmentator.SegmentImage(downscaledImage, colorModels);

            // Re-run B&B segmentation with reduced constraints in two-step mode
            if (this.segmentator is BranchAndBoundSegmentationAlgorithm && this.segmentationProperties.UseTwoStepApproach && !this.segmentator.WasStopped)
            {
                BranchAndBoundSegmentationAlgorithm branchAndBoundSegmentator =
                    (BranchAndBoundSegmentationAlgorithm)this.segmentator;

                branchAndBoundSegmentator.MaxCoordFreedom  = this.segmentationProperties.MaxCoordFreedom;
                branchAndBoundSegmentator.MaxWidthFreedom  = this.segmentationProperties.MaxWidthFreedom;
                branchAndBoundSegmentator.StartConstraints = this.bestConstraints;
                branchAndBoundSegmentator.ShapeEnergyLowerBoundCalculator = new ShapeEnergyLowerBoundCalculator(
                    this.segmentationProperties.LengthGridSize, this.segmentationProperties.AngleGridSize);

                Console.WriteLine("Performing second pass...");
                solution = segmentator.SegmentImage(downscaledImage, colorModels);
            }

            // Save mask as worker result
            e.Result = solution;
        }