示例#1
0
        protected override SegmentationSolution SegmentCurrentImage()
        {
            if (this.minEdgeWidth >= this.maxEdgeWidth)
            {
                throw new InvalidOperationException("Min edge width should be less than max edge width.");
            }
            if (this.startConstraints != null)
            {
                if (this.startConstraints.ShapeStructure != this.ShapeModel.Structure)
                {
                    throw new InvalidOperationException("Given start constraints have shape structure different from the one specified in shape model.");
                }
                // TODO: make this check work
                //foreach (VertexConstraints vertexConstraints in this.startConstraints.VertexConstraints)
                //{
                //    RectangleF imageRectangle =
                //        new RectangleF(0, 0, this.ImageSegmentator.ImageSize.Width, this.ImageSegmentator.ImageSize.Height);
                //    if (!imageRectangle.Contains(vertexConstraints.CoordRectangle))
                //        throw new InvalidOperationException("Given start constraints are not fully inside the segmented image.");
                //}
            }

            this.shapeUnaryTerms = new Image2D <ObjectBackgroundTerm>(
                this.ImageSegmentator.ImageSize.Width, this.ImageSegmentator.ImageSize.Height);

            ShapeConstraints constraints = this.startConstraints;

            if (constraints == null)
            {
                constraints = ShapeConstraints.CreateFromBounds(
                    this.ShapeModel.Structure,
                    Vector.Zero,
                    new Vector(this.ImageSegmentator.ImageSize.Width, this.ImageSegmentator.ImageSize.Height),
                    this.minEdgeWidth,
                    this.maxEdgeWidth);
            }

            if (this.BranchAndBoundStarted != null)
            {
                this.BranchAndBoundStarted(this, EventArgs.Empty);
            }

            this.startTime = DateTime.Now;
            DebugConfiguration.WriteImportantDebugText("Breadth-first branch-and-bound started.");

            SortedSet <EnergyBound> front = this.BreadthFirstBranchAndBoundTraverse(constraints);

            ReportBranchAndBoundCompletion(front.Min);

            if (front.Min.Constraints.CheckIfSatisfied(this.maxCoordFreedom, this.maxWidthFreedom))
            {
                DebugConfiguration.WriteImportantDebugText("Breadth-first branch-and-bound finished in {0}.",
                                                           DateTime.Now - this.startTime);
                DebugConfiguration.WriteImportantDebugText("Best lower bound is {0:0.0000}", front.Min.Bound);
            }
            else
            {
                DebugConfiguration.WriteImportantDebugText("Breadth-first branch-and-bound forced to stop after {0}.", DateTime.Now - this.startTime);
                DebugConfiguration.WriteImportantDebugText("Min energy value achieved is {0:0.0000}", front.Min.Bound);
            }

            EnergyBound collapsedBfsSolution = this.CalculateEnergyBound(front.Min.Constraints.Collapse());
            Shape       resultShape          = front.Min.Constraints.CollapseToShape();

            DebugConfiguration.WriteImportantDebugText(
                "Collapsed solution energy value is {0:0.0000} ({1:0.0000} + {2:0.0000})",
                collapsedBfsSolution.Bound,
                collapsedBfsSolution.SegmentationEnergy,
                collapsedBfsSolution.ShapeEnergy * this.ShapeEnergyWeight);
            return(new SegmentationSolution(resultShape, this.ImageSegmentator.GetLastSegmentationMask(), collapsedBfsSolution.Bound));
        }