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