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())); }
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)); } }
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; }