Пример #1
0
        private void TraceContiguousJunctions(Component component)
        {
            Dictionary <Discrete2D, BranchNode> junctionPoints = component.junctions;

            foreach (KeyValuePair <Discrete2D, BranchNode> starting in junctionPoints)
            {
                Debug.Assert(notVisitedMap[starting.Key.I, starting.Key.J]);
                MarkVisited(starting.Key); // n.b. not unmarked later, to prevent marking contiguous segments twice
                // Determine the 8-connected neighbours
                int neighbourhood = BitImage.Analysis.Neighbourhood(notVisitedMap, starting.Key.I, starting.Key.J);
                // TODO: Is it possible to have diagonally connected junctions?
                List <Discrete2D> relativeNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(neighbourhood));
                foreach (Discrete2D relativeNeighbour in relativeNeighbours)
                {
                    Discrete2D neighbour = starting.Key + relativeNeighbour;
                    // Check that the starting point hasn't already been consumed by the other branchpoint
                    if (IsJunction(neighbour))
                    {
                        SegmentNode segment = new SegmentNode();
                        segment.PreviousBranch = starting.Value;
                        segment.NextBranch     = junctionPoints[neighbour];
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Modify the neighbourhood to remove 8-neighbours which could be reached via
        /// 4-neighbour junction points, which have been temporarily removed.
        /// </summary>
        /// <param name="current">The pixel whose neighbourhood should be modified</param>
        /// <param name="neighbourhood">The neighbourhood to be modified</param>
        /// <returns>The modified neighbourhood</returns>
        private int AccountForJunctions(Discrete2D?current, int neighbourhood)
        {
            // Could use the same technique with a rotating bit pattern...
            Discrete2D west  = current.Value.West();
            Discrete2D north = current.Value.North();
            Discrete2D south = current.Value.South();
            Discrete2D east  = current.Value.East();

            if (connectivityMap.IsInRange(west.I, west.J) && IsJunction(west))
            {
                neighbourhood &= 431;
            }
            if (connectivityMap.IsInRange(north.I, north.J) && IsJunction(north))
            {
                neighbourhood &= 491;
            }
            if (connectivityMap.IsInRange(south.I, south.J) && IsJunction(south))
            {
                neighbourhood &= 191;
            }
            if (connectivityMap.IsInRange(east.I, east.J) && IsJunction(east))
            {
                neighbourhood &= 251;
            }
            return(neighbourhood);
        }
Пример #3
0
        private void TraceEightConnectedFromJunctions(Component component)
        {
            // TODO: This case only occurs if there are segments which are 8-connected
            // at BOTH ends to branch points. NOT YET TESTED.
            Dictionary <Discrete2D, BranchNode> junctionPoints = component.junctions;

            // Trace line segments from each junction point's 8-connected neighbours
            foreach (KeyValuePair <Discrete2D, BranchNode> starting in junctionPoints)
            {
                Debug.Assert(notVisitedMap[starting.Key.I, starting.Key.J]);
                MarkVisited(starting.Key); // Prevent tracings immediately returning to their origin
                // Determine the 8-connected neighbours
                int neighbourhood                = BitImage.Analysis.Neighbourhood(notVisitedMap, starting.Key.I, starting.Key.J);
                int fourNeighbourhood            = BitImage.Analysis.ToFourDiagonal(neighbourhood);  // One line different
                int filteredNeighbourhood        = RemoveJunctions(starting.Key, fourNeighbourhood); // NOT NEEDED??
                List <Discrete2D> fourNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(filteredNeighbourhood));
                foreach (Discrete2D relativeNeighbour in fourNeighbours)
                {
                    Discrete2D neighbour = starting.Key + relativeNeighbour;
                    // Check that the starting point hasn't already been consumed, for example,
                    // by a single line looping back so the same branch point it originated from
                    if (notVisitedMap[neighbour.I, neighbour.J])
                    {
                        SegmentNode segment = TraceSegment(component, neighbour);
                        segment.PreviousBranch = starting.Value;
                    }
                    else
                    {
                        Console.WriteLine("Model contains single segment loops!"); // TODO: Test this
                    }
                }
                UnmarkVisited(starting.Key); // Unmark, so that this junction point can be found for other segment ends
            }
        }
Пример #4
0
        private Discrete2D?AppendToSegment(Discrete2D?current, SegmentNode segment, Discrete2D neighbour)
        {
            // Add a point to the segment, and move on
            Debug.Assert(current.HasValue);
            Debug.Assert(IsStem(neighbour));
            Point2D currentGeographic = GridToGeographic(current.Value.I, current.Value.J);

            segment.Add(currentGeographic);
            MarkVisited(current.Value);
            return(neighbour);
        }
Пример #5
0
        private Discrete2D?Follow(Component component, Discrete2D?current, SegmentNode segment)
        {
            Debug.Assert(current.HasValue);
            int neighbourhood = BitImage.Analysis.Neighbourhood(notVisitedMap, current.Value.I, current.Value.J);

            neighbourhood = AccountForJunctions(current, neighbourhood);

            int eightConnectivity = BitImage.Analysis.EightConnectivity(neighbourhood);

            Debug.Assert(eightConnectivity > 0);

            if (eightConnectivity == 1)
            {
                List <Discrete2D> neighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(neighbourhood));
                Debug.Assert(eightConnectivity == neighbours.Count);

                Discrete2D neighbour = current.Value + neighbours[0];
                if (IsJunction(neighbour))
                {
                    current = EndSegmentAtJunction(component, current, segment, neighbour);
                }
                else if (IsFreeEnd(neighbour))
                {
                    current = EndSegmentAtFreeEnd(current, segment, neighbour);
                }
                else // neighbour is segment stem
                {
                    current = AppendToSegment(current, segment, neighbour);
                }
            }
            else // eightConnectivity > 1
            {
                // Determine numFour - the number of 4-connected neighbours
                int fourConnectivity = BitImage.Analysis.FourConnectivity(neighbourhood);
                Debug.Assert(fourConnectivity == 1);

                int fourNeighbourhood            = BitImage.Analysis.ToFourCross(neighbourhood);
                List <Discrete2D> fourNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(fourNeighbourhood));
                Debug.Assert(fourConnectivity == fourNeighbours.Count);

                Discrete2D neighbour = current.Value + fourNeighbours[0];
                if (IsJunction(neighbour))
                {
                    current = EndSegmentAtJunction(component, current, segment, neighbour);
                }
                else // Extend to neighbour
                {
                    Debug.Assert(IsStem(neighbour));
                    current = AppendToSegment(current, segment, neighbour);
                }
            }
            return(current);
        }
Пример #6
0
        private SegmentNode TraceSegment(Component component, Discrete2D start)
        {
            Discrete2D?current = start;

            Debug.Assert(connectivityMap[current.Value.I, current.Value.J] != 0);
            SegmentNode segment = network.CreateSegmentNode();

            while (current.HasValue)
            {
                current = Follow(component, current, segment);
            }
            return(segment);
        }
Пример #7
0
        /// <summary>
        /// Modify the neighbourhood to remove any eight-connected junctions. Useful
        /// when processing contiguous junction points
        /// </summary>
        /// <param name="current">The pixel whose neighbourhood should be modified</param>
        /// <param name="neighbourhood">The neighbourhood to be modified</param>
        /// <returns>The modified neighbourhood</returns>
        private int RemoveJunctions(Discrete2D?current, int neighbourhood)
        {
            Debug.Assert(current.HasValue);
            const int         allExceptCenter = 510; // TODO: Make this and the next line static
            List <Discrete2D> allNeighbours   = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(allExceptCenter));
            Int32             bits            = 1;

            foreach (Discrete2D relativeCoord in allNeighbours)
            {
                bits <<= 1;
                Discrete2D neighbour = current.Value + relativeCoord;
                if (connectivityMap.IsInRange(neighbour.I, neighbour.J) && IsJunction(neighbour))
                {
                    Int32 mask = ~bits;
                    neighbourhood &= mask;
                    Debug.Assert(neighbourhood >= 0 && neighbourhood < 512);
                }
            }
            return(neighbourhood);
        }
Пример #8
0
 private bool IsJunction(Discrete2D coord)
 {
     Debug.Assert(connectivityMap != null);
     return(connectivityMap[coord.I, coord.J] >= 3);
 }
Пример #9
0
 private bool IsStem(Discrete2D coord)
 {
     Debug.Assert(connectivityMap != null);
     return(connectivityMap[coord.I, coord.J] == 2);
 }
Пример #10
0
 private bool IsFreeEnd(Discrete2D coord)
 {
     Debug.Assert(connectivityMap != null);
     return(connectivityMap[coord.I, coord.J] == 1);
 }
Пример #11
0
 private void UnmarkVisited(Discrete2D point)
 {
     notVisitedMap[point.I, point.J] = true;
 }
Пример #12
0
 private void MarkVisited(Discrete2D point)
 {
     notVisitedMap[point.I, point.J] = false;
 }
Пример #13
0
        private Discrete2D?EndSegmentAtFreeEnd(Discrete2D?current, SegmentNode segment, Discrete2D neighbour)
        {
            // End segment here by adding last node
            Debug.Assert(current.HasValue);
            Point2D currentGeographic = GridToGeographic(current.Value.I, current.Value.J);

            segment.Add(currentGeographic);
            Point2D neighbourGeographic = GridToGeographic(neighbour.I, neighbour.J);

            segment.Add(neighbourGeographic);
            segment.NextBranch = null;
            MarkVisited(current.Value);
            MarkVisited(neighbour);
            return(null);
        }
Пример #14
0
        private Discrete2D?EndSegmentAtJunction(Component component, Discrete2D?current, SegmentNode segment, Discrete2D junction)
        {
            // End segment here with edge to junction
            Debug.Assert(current.HasValue);
            BranchNode branchPoint = component.junctions[junction];
            Point2D    geographic  = GridToGeographic(current.Value.I, current.Value.J);

            segment.Add(geographic);
            segment.NextBranch = branchPoint;
            MarkVisited(current.Value);
            return(null);
        }
Пример #15
0
    private static void test01(int n)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST01 looks at a 20x20 region.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    16 December 2012
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Parameters:
    //
    //    Input, int N, the number of sample points to be generated.
    //
    {
        int n1 = 0;
        int n2 = 0;

        Console.WriteLine("");
        Console.WriteLine("TEST01");
        Console.WriteLine("  Consider data skewed toward the upper left corner of the unit square.");
        Console.WriteLine("  Generate " + n + " samples");
        //
        //  Get the dimensions of the PDF data.
        //
        Discrete2D.get_discrete_pdf_size1(ref n1, ref n2);
        Console.WriteLine("  PDF data is on a " + n1 + " by " + n2 + " grid.");
        //
        //  Construct a PDF from the data.
        //
        double[] pdf = Discrete2D.get_discrete_pdf_data1(n1, n2);
        //
        //  "Integrate" the data over rows and columns of the region to get the CDF.
        //
        double[] cdf = Discrete2D.set_discrete_cdf(n1, n2, pdf);
        //
        //  Choose N CDF values at random.
        //
        int seed = 123456789;

        double[] u = UniformRNG.r8vec_uniform_01_new(n, ref seed);
        //
        //  Find the cell corresponding to each CDF value,
        //  and choose a random point in that cell.
        //
        double[] xy = Discrete2D.discrete_cdf_to_xy(n1, n2, cdf, n, u, ref seed);
        //
        //  Write data to a file for examination, plotting, or analysis.
        //
        string filename = "test01.txt";

        typeMethods.r8mat_write(filename, 2, n, xy);

        Console.WriteLine("");
        Console.WriteLine("  Wrote sample data to file \"" + filename + "\".");
    }