NuGenSegment AdjacentSegment(NuGenSegment[] lastSegment, int yStart, int yStop, int height)
        {
          for (int y = yStart - 1; y <= yStop + 1; y++)
            if ((0 <= y) && (y < height))
              if (lastSegment [y] != null)
                return lastSegment [y];

          return null;
        }
        int AdjacentSegments(NuGenSegment[] lastSegment, int yStart, int yStop, int height)
        {
          int segments = 0;
          bool inSegment = false;
          for (int y = yStart - 1; y <= yStop + 1; y++)
          {
            if ((0 <= y) && (y < height))
            {
              if (!inSegment && (lastSegment[y] != null))
              {
                inSegment = true;
                ++segments;
              }
              else if (inSegment && (lastSegment[y] == null))
                inSegment = false;
            }
          }

          return segments;
        }
示例#3
0
        private void SelectSegment(NuGenSegment segment)
        {
            if (selectedSegment != null)
                DeselectSelectedSegment();

            selectedSegment = segment;
            DrawSelectedSegments(Buffer);
        }
示例#4
0
 private void DeselectSelectedSegment()
 {
     //ClearSelectedSegments();
     selectedSegment = null;
 }
        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;
        }
 void ScrollSegment(NuGenSegment[] left, NuGenSegment[] right, int height)
 {
   for (int y = 0; y < height; y++)
     left [y] = right [y];
 }
        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();
              }
            }
          }
        }
        void MatchRunsToSegments(int x, int height, bool[] lastBool, NuGenSegment[] lastSegment,
          bool[] currBool, NuGenSegment[] currSegment, bool[] nextBool, SegmentSettings seg)
        {
          LoadSegment(currSegment, height);

          int yStart = 0;
          bool inRun = false;
          for (int y = 0; y < height; y++)
          {
            if (!inRun && currBool [y])
            {
              inRun = true;
              yStart = y;
            }

            if ((y + 1 >= height) || !currBool [y + 1])
            {
              if (inRun)
                FinishRun(lastBool, nextBool, lastSegment, currSegment, x, yStart, y, height, seg);

              inRun = false;
            }
          }

          RemoveUnneededLines(lastSegment, currSegment, height, seg);
        }
        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);
        }
 void LoadSegment(NuGenSegment[] columnSegment, int height)
 {
   for (int y = 0; y < height; y++)
     columnSegment [y] = null;
 }