예제 #1
0
        public void MakeSegments(Image imageProcessed, SegmentSettings seg)
        {
            segments.Clear();

            // for each new column of pixels, loop through the runs. a run is defined as
            // one or more colored pixels that are all touching, with one uncolored pixel or the
            // image boundary at each end of the set. for each set in the current column, count
            // the number of runs it touches in the adjacent (left and right) columns. here is
            // the pseudocode:
            //   if ((L > 1) || (R > 1))
            //     "this run is at a branch point so ignore the set"
            //   else
            //     if (L == 0)
            //       "this run is the start of a new segment"
            //     else
            //       "this run is appended to the segment on the left
            int width  = imageProcessed.Width;
            int height = imageProcessed.Height;

            bool[]         lastBool    = new bool [height];
            bool[]         currBool    = new bool [height];
            bool[]         nextBool    = new bool [height];
            NuGenSegment[] lastSegment = new NuGenSegment [height];
            NuGenSegment[] currSegment = new NuGenSegment [height];

            Bitmap     b      = new Bitmap(imageProcessed);
            BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);

            LoadBool(lastBool, bmData, -1);
            LoadBool(currBool, bmData, 0);
            LoadBool(nextBool, bmData, 1);
            LoadSegment(lastSegment, height);

            for (int x = 0; x < width; x++)
            {
                MatchRunsToSegments(x, height, lastBool, lastSegment, currBool, currSegment, nextBool, seg);

                // get ready for next column
                ScrollBool(lastBool, currBool, height);
                ScrollBool(currBool, nextBool, height);
                if (x + 1 < width)
                {
                    LoadBool(nextBool, bmData, x + 1);
                }
                ScrollSegment(lastSegment, currSegment, height);
            }

            b.UnlockBits(bmData);
        }
예제 #2
0
        void FinishRun(bool[] lastBool, bool[] nextBool,
                       NuGenSegment[] lastSegment, NuGenSegment[] currSegment,
                       int x, int yStart, int yStop, int height, SegmentSettings set)
        {
            // when looking at adjacent columns, include pixels that touch diagonally since
            // those may also diagonally touch nearby runs in the same column (which would indicate
            // a branch)

            // count runs that touch on the left
            if (AdjacentRuns(lastBool, yStart, yStop, height) > 1)
            {
                return;
            }
            // count runs that touch on the right
            if (AdjacentRuns(nextBool, yStart, yStop, height) > 1)
            {
                return;
            }

            NuGenSegment seg;

            if (AdjacentSegments(lastSegment, yStart, yStop, height) == 0)
            {
                // this is the start of a new segment
                seg = new NuGenSegment((int)(0.5 + (yStart + yStop) / 2.0));

                segments.Add(seg);
            }
            else
            {
                // this is the continuation of an existing segment
                seg = AdjacentSegment(lastSegment, yStart, yStop, height);

                seg.AppendColumn(x, (int)(0.5 + (yStart + yStop) / 2.0), set);
            }

            for (int y = yStart; y <= yStop; y++)
            {
                currSegment [y] = seg;
            }
        }
예제 #3
0
        void RemoveUnneededLines(NuGenSegment[] lastSegment, NuGenSegment[] currSegment, int height, SegmentSettings seg)
        {
            NuGenSegment segLast = null;

            for (int yLast = 0; yLast < height; yLast++)
            {
                if ((lastSegment[yLast] != null) && (lastSegment [yLast] != segLast))
                {
                    segLast = lastSegment [yLast];

                    // if the segment is found in the current column then it is still in work so postpone processing
                    bool found = false;
                    for (int yCur = 0; yCur < height; yCur++)
                    {
                        if (segLast == currSegment [yCur])
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        if (segLast.Length < (seg.minPoints - 1) * seg.pointSeparation)
                        {
                            segments.Remove(segLast); // autoDelete is on
                        }
                        else
                        {
                            // keep segment, but try to fold lines
                            segLast.RemoveUnneededLines();
                        }
                    }
                }
            }
        }
예제 #4
0
 public SegmentLine(NuGenSegment segment)
 {
     this.segment = segment;
 }