public static ShapeConstraints CreateFromShape(Shape shape)
 {
     IEnumerable<VertexConstraints> vertexConstraints =
         shape.VertexPositions.Select(vertex => new VertexConstraints(vertex));
     IEnumerable<EdgeConstraints> edgeConstraints =
         shape.EdgeWidths.Select(width => new EdgeConstraints(width));
     return CreateFromConstraints(shape.Structure, vertexConstraints, edgeConstraints);
 }
 public SegmentationSolution(Shape shape, Image2D<bool> mask, double energy)
 {
     if (shape == null && mask == null)
         throw new ArgumentException("Segmentation solution should contain something.");
     
     this.Shape = shape;
     this.Mask = mask;
     this.Energy = energy;
 }
 public SegmentationIterationFinishedEventArgs(
     int iteration,
     Shape shape,
     Image2D<bool> segmentationMask,
     Image2D<ObjectBackgroundTerm> unaryTermsImage,
     Image2D<ObjectBackgroundTerm> shapeTermsImage)
 {
     this.Iteration = iteration;
     this.Shape = shape;
     this.SegmentationMask = segmentationMask;
     this.UnaryTermsImage = unaryTermsImage;
     this.ShapeTermsImage = shapeTermsImage;
 }
 private void UpdateShapeTerms(Shape shape)
 {
     Parallel.For(
         0,
         this.shapeTerms.Width,
         i =>
             {
                 for (int j = 0; j < this.shapeTerms.Height; ++j)
                 {
                     this.shapeTerms[i, j] =
                         this.ShapeModel.CalculatePenalties(shape, new Vector(i, j));
                 }
             });
 }
        private double CalcObjective(Shape shape, bool report)
        {
            this.UpdateShapeTerms(shape);
            
            double shapeEnergy = this.ShapeModel.CalculateEnergy(shape);
            double labelingEnergy = this.ImageSegmentator.SegmentImageWithShapeTerms((x, y) => this.shapeTerms[x, y]);
            double energy = shapeEnergy * this.ShapeEnergyWeight + labelingEnergy;
            double additionalPenalty = this.AdditionalShapePenalty == null ? 0 : this.AdditionalShapePenalty(shape);
            double totalEnergy = energy + additionalPenalty;

            if (report)
            {
                DebugConfiguration.WriteImportantDebugText(
                    "Solution energy: {0:0.0000} ({1:0.0000} + {2:0.0000} * {3:0.0000} + {4:0.0000})",
                    totalEnergy,
                    labelingEnergy,
                    this.ShapeEnergyWeight,
                    shapeEnergy,
                    additionalPenalty);
            }

            return totalEnergy;
        }
 private Shape MutateSolution(Shape shape, double temperature)
 {
     return this.ShapeMutator.MutateShape(
         shape, this.ShapeModel, this.ImageSegmentator.ImageSize, temperature / this.SolutionFitter.StartTemperature);
 }
        public double CalculateEnergy(Shape shape)
        {
            if (shape == null)
                throw new ArgumentNullException("shape");
            if (shape.Structure != this.Structure)
                throw new ArgumentException("Shape and model have different structures.", "shape");

            double totalEnergy = 0;

            // Root edge term
            ShapeEdge rootEdge = this.Structure.Edges[this.rootEdgeIndex];
            totalEnergy += this.CalculateRootEdgeEnergyTerm(
                shape.VertexPositions[rootEdge.Index1], shape.VertexPositions[rootEdge.Index2]);
            
            // Unary energy terms)
            for (int i = 0; i < this.Structure.Edges.Count; ++i)
            {
                ShapeEdge edge = this.Structure.Edges[i];
                totalEnergy += this.CalculateEdgeWidthEnergyTerm(
                    i, shape.EdgeWidths[i], shape.VertexPositions[edge.Index1], shape.VertexPositions[edge.Index2]);
            }

            // Pairwise energy terms
            foreach (Tuple<int, int> edgePair in this.ConstrainedEdgePairs)
            {
                totalEnergy += this.CalculateEdgePairLengthEnergyTerm(
                    edgePair.Item1,
                    edgePair.Item2,
                    shape.GetEdgeVector(edgePair.Item1),
                    shape.GetEdgeVector(edgePair.Item2));
                totalEnergy += this.CalculateEdgePairAngleEnergyTerm(
                    edgePair.Item1,
                    edgePair.Item2,
                    shape.GetEdgeVector(edgePair.Item1),
                    shape.GetEdgeVector(edgePair.Item2));
            }

            return totalEnergy;
        }
 public ObjectBackgroundTerm CalculatePenalties(Shape shape, Vector point)
 {
     return new ObjectBackgroundTerm(
         this.CalculateObjectPenalty(shape, point), this.CalculateBackgroundPenalty(shape, point));
 }
        public double CalculateBackgroundPenalty(Shape shape, Vector point)
        {
            if (shape == null)
                throw new ArgumentNullException("shape");
            if (shape.Structure != this.Structure)
                throw new ArgumentException("Shape and model have different structures.", "shape");

            double maxPenalty = Double.NegativeInfinity;
            for (int i = 0; i < this.Structure.Edges.Count; ++i)
            {
                ShapeEdge edge = this.Structure.Edges[i];
                double penalty = this.CalculateBackgroundPenaltyForEdge(
                    point, shape.EdgeWidths[i], shape.VertexPositions[edge.Index1], shape.VertexPositions[edge.Index2]);
                maxPenalty = Math.Max(maxPenalty, penalty);
            }
            return maxPenalty;
        }
        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 double CalcShapeLabelingEnergy(Shape shape, Image2D<bool> mask)
        {
            double shapeTermSum = 0;
            for (int x = 0; x < mask.Width; ++x)
            {
                for (int y = 0; y < mask.Height; ++y)
                {
                    
                    if (mask[x, y])
                        shapeTermSum += this.ShapeModel.CalculateObjectPenalty(shape, new Vector(x, y)) * this.ObjectShapeUnaryTermWeight;
                    else
                        shapeTermSum += this.ShapeModel.CalculateBackgroundPenalty(shape, new Vector(x, y)) * this.BackgroundShapeUnaryTermWeight;
                }
            }

            return shapeTermSum * this.ImageSegmentator.UnaryTermScaleCoeff;
        }
 private double CalcObjective(Shape shape, Image2D<bool> mask)
 {
     double shapeEnergy = this.ShapeModel.CalculateEnergy(shape);
     double labelingEnergy = CalcShapeLabelingEnergy(shape, mask);
     return shapeEnergy * this.ShapeEnergyWeight + labelingEnergy;
 }
예제 #13
0
 private Shape MutateSolution(Shape shape, double temperature)
 {
     return(this.ShapeMutator.MutateShape(
                shape, this.ShapeModel, this.ImageSegmentator.ImageSize, temperature / this.SolutionFitter.StartTemperature));
 }