예제 #1
0
        private GeneralizedDistanceTransform2D CalculateMinEnergiesForAllParentEdges(
            ShapeModel model,
            ShapeConstraints shapeConstraints,
            int parentEdgeIndex,
            int currentEdgeIndex,
            IList <ILengthAngleConstraints> lengthAngleConstraints)
        {
            // Calculate child transforms
            List <GeneralizedDistanceTransform2D> childDistanceTransforms = new List <GeneralizedDistanceTransform2D>();

            foreach (int neighborEdgeIndex in model.IterateNeighboringEdgeIndices(currentEdgeIndex))
            {
                // Iterate only through children
                if (neighborEdgeIndex == parentEdgeIndex)
                {
                    continue;
                }

                GeneralizedDistanceTransform2D childTransform = CalculateMinEnergiesForAllParentEdges(
                    model, shapeConstraints, currentEdgeIndex, neighborEdgeIndex, lengthAngleConstraints);
                Debug.Assert(childTransform.IsComputed);
                childDistanceTransforms.Add(childTransform);
            }

            ShapeEdgePairParams            pairParams = model.GetEdgePairParams(parentEdgeIndex, currentEdgeIndex);
            GeneralizedDistanceTransform2D transform  = this.AllocateDistanceTransform();

            SetupTransformFinitePenaltyRanges(transform, pairParams, lengthAngleConstraints[currentEdgeIndex]);
            SetupTransformInterestRanges(transform, lengthAngleConstraints[parentEdgeIndex]);

            Func <double, double, double> penaltyFunction =
                (scaledLength, shiftedAngle) =>
            {
                double length = scaledLength / pairParams.MeanLengthRatio;
                double angle  = shiftedAngle + pairParams.MeanAngle;

                double lengthTolerance = transform.GridStepSizeX / pairParams.MeanLengthRatio;
                double angleTolerance  = transform.GridStepSizeY;
                if (!lengthAngleConstraints[currentEdgeIndex].InRange(length, lengthTolerance, angle, angleTolerance))
                {
                    return(1e+20);
                }

                double penalty =
                    CalculateMinUnaryEdgeEnergy(currentEdgeIndex, model, shapeConstraints, length) +
                    CalculateMinPairwiseEdgeEnergy(length, angle, childDistanceTransforms);
                return(penalty);
            };

            transform.Compute(
                0.5 / MathHelper.Sqr(pairParams.LengthDiffDeviation),
                0.5 / MathHelper.Sqr(pairParams.AngleDeviation),
                penaltyFunction);

            return(transform);
        }
예제 #2
0
        private void SetupTransformFinitePenaltyRanges(
            GeneralizedDistanceTransform2D transform, ShapeEdgePairParams pairParams, ILengthAngleConstraints lengthAngleConstraints)
        {
            Range lengthRange = lengthAngleConstraints.LengthBoundary;
            Range angleRange  = lengthAngleConstraints.AngleBoundary;

            transform.AddFinitePenaltyRangeX(
                new Range(lengthRange.Left * pairParams.MeanLengthRatio, lengthRange.Right * pairParams.MeanLengthRatio));

            if (!angleRange.Outside)
            {
                transform.AddFinitePenaltyRangeY(new Range(angleRange.Left - pairParams.MeanAngle, angleRange.Right - pairParams.MeanAngle));
            }
            else
            {
                transform.AddFinitePenaltyRangeY(new Range(-Math.PI - pairParams.MeanAngle, angleRange.Left - pairParams.MeanAngle));
                transform.AddFinitePenaltyRangeY(new Range(angleRange.Right - pairParams.MeanAngle, Math.PI - pairParams.MeanAngle));
            }
        }
        private void SetupTransformFinitePenaltyRanges(
            GeneralizedDistanceTransform2D transform, ShapeEdgePairParams pairParams, ILengthAngleConstraints lengthAngleConstraints)
        {
            Range lengthRange = lengthAngleConstraints.LengthBoundary;
            Range angleRange = lengthAngleConstraints.AngleBoundary;
            
            transform.AddFinitePenaltyRangeX(
                new Range(lengthRange.Left * pairParams.MeanLengthRatio, lengthRange.Right * pairParams.MeanLengthRatio));

            if (!angleRange.Outside)
                transform.AddFinitePenaltyRangeY(new Range(angleRange.Left - pairParams.MeanAngle, angleRange.Right - pairParams.MeanAngle));
            else
            {
                transform.AddFinitePenaltyRangeY(new Range(-Math.PI - pairParams.MeanAngle, angleRange.Left - pairParams.MeanAngle));
                transform.AddFinitePenaltyRangeY(new Range(angleRange.Right - pairParams.MeanAngle, Math.PI - pairParams.MeanAngle));
            }
        }