Пример #1
0
        private void ReportBranchAndBoundCompletion(EnergyBound result)
        {
            // In order to report various masks we need to segment image again
            this.SegmentImageWithConstraints(result.Constraints.Collapse());

            BranchAndBoundCompletedEventArgs args = new BranchAndBoundCompletedEventArgs(
                this.ImageSegmentator.GetLastSegmentationMask(), this.ImageSegmentator.GetLastUnaryTerms(), this.ImageSegmentator.GetLastShapeTerms(), result.Constraints, result.Bound);

            if (this.BranchAndBoundCompleted != null)
            {
                this.BranchAndBoundCompleted.Invoke(this, args);
            }
        }
Пример #2
0
        private void ReportBranchAndBoundProgress(SortedSet <EnergyBound> front)
        {
            EnergyBound currentMin = front.Min;

            // In order to report various masks we need to segment image again
            this.SegmentImageWithConstraints(currentMin.Constraints);

            // Raise status report event
            BranchAndBoundProgressEventArgs args = new BranchAndBoundProgressEventArgs(
                front.Min.Bound, this.ImageSegmentator.GetLastSegmentationMask(), this.ImageSegmentator.GetLastUnaryTerms(), this.ImageSegmentator.GetLastShapeTerms(), currentMin.Constraints);

            if (this.BreadthFirstBranchAndBoundProgress != null)
            {
                this.BreadthFirstBranchAndBoundProgress.Invoke(this, args);
            }
        }
Пример #3
0
        private SortedSet <EnergyBound> BreadthFirstBranchAndBoundTraverse(ShapeConstraints constraints)
        {
            SortedSet <EnergyBound> front = new SortedSet <EnergyBound> {
                this.CalculateEnergyBound(constraints)
            };

            int      currentIteration        = 1;
            DateTime lastOutputTime          = startTime;
            int      processedConstraintSets = 0;

            while (!front.Min.Constraints.CheckIfSatisfied(this.maxCoordFreedom, this.maxWidthFreedom) && !this.IsStopping)
            {
                this.WaitIfPaused();

                EnergyBound parentLowerBound = front.Min;
                front.Remove(parentLowerBound);

                List <ShapeConstraints> expandedConstraints = parentLowerBound.Constraints.SplitMostFree(this.maxCoordFreedom, this.maxWidthFreedom);
                foreach (ShapeConstraints constraintsSet in expandedConstraints)
                {
                    EnergyBound lowerBound = this.CalculateEnergyBound(constraintsSet);
                    front.Add(lowerBound);

                    // Uncomment for strong invariants check
                    //ObjectBackgroundTerm[,] lowerBoundShapeTerm = new ObjectBackgroundTerm[this.segmentedImage.Width, this.segmentedImage.Height];
                    //for (int i = 0; i < this.segmentedImage.Width; ++i)
                    //    for (int j = 0; j < this.segmentedImage.Height; ++j)
                    //        lowerBoundShapeTerm[i, j] = CpuBranchAndBoundShapeTermsCalculator.CalculateShapeTerm(lowerBound.Constraints, new Point(i, j));
                    //ObjectBackgroundTerm[,] parentLowerBoundShapeTerm = new ObjectBackgroundTerm[this.segmentedImage.Width, this.segmentedImage.Height];
                    //for (int i = 0; i < this.segmentedImage.Width; ++i)
                    //    for (int j = 0; j < this.segmentedImage.Height; ++j)
                    //        parentLowerBoundShapeTerm[i, j] = CpuBranchAndBoundShapeTermsCalculator.CalculateShapeTerm(parentLowerBound.Constraints, new Point(i, j));
                    //for (int i = 0; i < this.segmentedImage.Width; ++i)
                    //    for (int j = 0; j < this.segmentedImage.Height; ++j)
                    //    {
                    //        Debug.Assert(lowerBoundShapeTerm[i, j].ObjectTerm >= parentLowerBoundShapeTerm[i, j].ObjectTerm - 1e-7);
                    //        Debug.Assert(lowerBoundShapeTerm[i, j].BackgroundTerm >= parentLowerBoundShapeTerm[i, j].BackgroundTerm - 1e-7);
                    //        //CalculateShapeTerm(lowerBound.Constraints, new Point(0, 67));
                    //        //CalculateShapeTerm(parentLowerBound.Constraints, new Point(0, 67));
                    //    }

                    // Lower bound should not decrease (check always, it's important!)
                    Trace.Assert(lowerBound.SegmentationEnergy >= parentLowerBound.SegmentationEnergy - 1e-6);
                    Trace.Assert(lowerBound.ShapeEnergy >= parentLowerBound.ShapeEnergy - 1e-6);

                    //this.CalculateEnergyBound(lowerBound.Constraints);
                    //this.CalculateEnergyBound(parentLowerBound.Constraints);

                    ++processedConstraintSets;
                }

                // Some debug output
                if (currentIteration % this.ProgressReportRate == 0)
                {
                    DateTime    currentTime = DateTime.Now;
                    EnergyBound currentMin  = front.Min;

                    DebugConfiguration.WriteDebugText(
                        "On iteration {0} front contains {1} constraint sets.", currentIteration, front.Count);
                    DebugConfiguration.WriteDebugText(
                        "Current lower bound is {0:0.0000} ({1:0.0000} + {2:0.0000}).",
                        currentMin.Bound,
                        currentMin.SegmentationEnergy,
                        currentMin.ShapeEnergy * this.ShapeEnergyWeight);
                    double processingSpeed = processedConstraintSets / (currentTime - lastOutputTime).TotalSeconds;
                    DebugConfiguration.WriteDebugText("Processing speed is {0:0.000} items per sec", processingSpeed);

                    double maxVertexConstraintsFreedom = currentMin.Constraints.VertexConstraints.Max(c => c.Freedom);
                    double maxEdgeConstraintsFreedom   = currentMin.Constraints.EdgeConstraints.Max(c => c.Freedom);
                    DebugConfiguration.WriteDebugText(
                        "Max vertex freedom: {0:0.00}, max edge freedom: {1:0.00}",
                        maxVertexConstraintsFreedom,
                        maxEdgeConstraintsFreedom);

                    DebugConfiguration.WriteDebugText("Elapsed time: {0}", DateTime.Now - this.startTime);

                    DebugConfiguration.WriteDebugText();

                    this.ReportBranchAndBoundProgress(front);

                    lastOutputTime          = currentTime;
                    processedConstraintSets = 0;
                }

                currentIteration += 1;
            }

            return(front);
        }
Пример #4
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));
        }