예제 #1
0
        public Shape BuildShapeFromLengthAngleRepresentation(ShapeLengthAngleRepresentation lengthAngleRepresentation)
        {
            if (lengthAngleRepresentation == null)
            {
                throw new ArgumentNullException("lengthAngleRepresentation");
            }
            if (lengthAngleRepresentation.Structure != this.Structure)
            {
                throw new ArgumentException("Shape representation and shape model should have equal structures.");
            }

            Vector[] vertices = new Vector[this.Structure.VertexCount];
            vertices[this.Structure.Edges[0].Index1] = lengthAngleRepresentation.Origin;
            vertices[this.Structure.Edges[0].Index2] = lengthAngleRepresentation.Origin +
                                                       lengthAngleRepresentation.EdgeLengths[0] * new Vector(Math.Cos(lengthAngleRepresentation.EdgeAngles[0]), Math.Sin(lengthAngleRepresentation.EdgeAngles[0]));
            foreach (int childEdgeIndex in this.IterateNeighboringEdgeIndices(0))
            {
                BuildShapeFromLengthAngleRepresentationDfs(
                    vertices,
                    childEdgeIndex,
                    0,
                    vertices[this.Structure.Edges[0].Index1],
                    vertices[this.Structure.Edges[0].Index2],
                    (currentEdge, parentEdge, parentLength) => lengthAngleRepresentation.EdgeLengths[currentEdge],
                    (currentEdge, parentEdge, parentAngle) => lengthAngleRepresentation.EdgeAngles[currentEdge]);
            }

            return(new Shape(this.Structure, vertices, lengthAngleRepresentation.EdgeWidths));
        }
예제 #2
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);
        }
        public Shape BuildShapeFromLengthAngleRepresentation(ShapeLengthAngleRepresentation lengthAngleRepresentation)
        {
            if (lengthAngleRepresentation == null)
                throw new ArgumentNullException("lengthAngleRepresentation");
            if (lengthAngleRepresentation.Structure != this.Structure)
                throw new ArgumentException("Shape representation and shape model should have equal structures.");

            Vector[] vertices = new Vector[this.Structure.VertexCount];
            vertices[this.Structure.Edges[0].Index1] = lengthAngleRepresentation.Origin;
            vertices[this.Structure.Edges[0].Index2] = lengthAngleRepresentation.Origin +
                lengthAngleRepresentation.EdgeLengths[0] * new Vector(Math.Cos(lengthAngleRepresentation.EdgeAngles[0]), Math.Sin(lengthAngleRepresentation.EdgeAngles[0]));
            foreach (int childEdgeIndex in this.IterateNeighboringEdgeIndices(0))
            {
                BuildShapeFromLengthAngleRepresentationDfs(
                    vertices,
                    childEdgeIndex,
                    0,
                    vertices[this.Structure.Edges[0].Index1],
                    vertices[this.Structure.Edges[0].Index2],
                    (currentEdge, parentEdge, parentLength) => lengthAngleRepresentation.EdgeLengths[currentEdge],
                    (currentEdge, parentEdge, parentAngle) => lengthAngleRepresentation.EdgeAngles[currentEdge]);
            }

            return new Shape(this.Structure, vertices, lengthAngleRepresentation.EdgeWidths);
        }