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