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 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 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(); } } } } }
public SegmentLine(NuGenSegment segment) { this.segment = segment; }