/// <summary> /// /// Produces a binary Matrix with Dimensions /// For the threshold, we take the sum of weighted R,g,b value. The sum of weights must be 1. /// The result fills the field bm; /// </summary> /// <param name="bitmap"> A Bitmap, which will be transformed to a binary Matrix</param> /// <returns>Returns a binaray boolean Matrix </returns> void ConvertBitmap(Bitmap bitmap) { byte[] Result = new byte[bitmap.Width * bitmap.Height]; BitmapData SourceData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte *SourcePtr = (byte *)(void *)SourceData.Scan0; int l = Result.Length; for (int i = 0; i < l; i++) { // if ((0.2126 * (double)SourcePtr[4 * i + 2] + 0.7153 * (double)SourcePtr[4 * i + 1] + 0.0721 * (double)SourcePtr[4 * i]) < Treshold*255) if (((double)SourcePtr[4 * i + 2] + (double)SourcePtr[4 * i + 1] + (double)SourcePtr[4 * i]) < Treshold * 255 * 3) { Result[i] = 1; } else { Result[i] = 0; } } } bitmap.UnlockBits(SourceData); bm = new Bitmap_p(bitmap.Width, bitmap.Height); bm.data = Result; }
/// <summary> /// Decompose the given bitmap into paths. Returns a linked list of /// Path objects with the fields len, pt, area filled /// </summary> /// <param name="bm">A binary bitmap which holds the imageinformations.</param> /// <param name="plistp">List of Path objects</param> Path bmToPathlist() { Bitmap_p bm1 = bm.copy(); Point currentPoint = new Point(0, 0); Path path = new Path(); bool weiter = findNext(bm1, currentPoint, ref currentPoint); while (weiter) { path = findPath(bm1, currentPoint); xorPath(bm1, path); if (path.area > turdsize) { pathlist.Add(path); } weiter = findNext(bm1, currentPoint, ref currentPoint); } return(path); }
static bool majority(Bitmap_p bm1, int x, int y) { int i; int a; int ct; for (i = 2; i < 5; i++) { ct = 0; for (a = -i + 1; a <= i - 1; a++) { ct += bm1.at(x + a, y + i - 1) ? 1 : -1; ct += bm1.at(x + i - 1, y + a - 1) ? 1 : -1; ct += bm1.at(x + a - 1, y - i) ? 1 : -1; ct += bm1.at(x - i, y + a) ? 1 : -1; } if (ct > 0) { return(true); } else if (ct < 0) { return(false); } } return(false); }
/// <summary> /// Searches a x and a y such that source[x,y] = 1 and source[x+1,y] 0. /// If this not exists, false will be returned else the result is true. /// /// </summary> /// <param name="source">Is a Binary Matrix, which is produced by <see cref="BitMapToBinary"/> /// <param name="x">x index in the source Matrix</param> /// <param name="y">y index in the source Matrix</param> static bool findNext(Bitmap_p bm1, Point point, ref Point result) { int i = bm1.w * point.Y + point.X; while ((i < bm1.size) && (bm1.data[i] != 1)) { i++; } if (i >= bm1.size) { return(false); } result = bm1.index(i); return(true); }
static void xorPath(Bitmap_p bm1, Path path) { int y1 = path.pt[0].Y, len = path.len, x, y, maxX, minY, i, j; for (i = 1; i < len; i++) { x = path.pt[i].X; y = path.pt[i].Y; if (y != y1) { minY = y1 < y ? y1 : y; maxX = path.maxX; for (j = x; j < maxX; j++) { bm1.flip(j, minY); } y1 = y; } } }
void Clear() { bm = null; pathlist.Clear(); }
/// <summary> /// Compute a path in the binary matrix. /// Start path at the point (x0,x1), which must be an upper left corner /// of the path. Also compute the area enclosed by the path. Return a /// new path_t object, or NULL on error (note that a legitimate path /// cannot have length 0). /// </summary> /// <param name="Matrix">Binary Matrix</param> /// <returns></returns> /// <param name="x">x index in the source Matrix</param> /// <param name="y">y index in the source Matrix</param> Path findPath(Bitmap_p bm1, Point point) { Path path = new Path(); int x = point.X; int y = point.Y; int dirx = 0; int diry = 1; int tmp = -1; path.sign = bm.at(point.X, point.Y) ? "+" : "-"; while (true) { path.pt.Add(new Point(x, y)); if (x > path.maxX) { path.maxX = x; } if (x < path.minX) { path.minX = x; } if (y > path.maxY) { path.maxY = y; } if (y < path.minY) { path.minY = y; } path.len++; x += dirx; y += diry; path.area -= x * diry; if (x == point.X && y == point.Y) { break; } bool l = bm1.at(x + (dirx + diry - 1) / 2, y + (diry - dirx - 1) / 2); bool r = bm1.at(x + (dirx - diry - 1) / 2, y + (diry + dirx - 1) / 2); if (r && !l) { if ((turnpolicy == TurnPolicy.right) || (((turnpolicy == TurnPolicy.black) && (path.sign == "+"))) || (((turnpolicy == TurnPolicy.white) && (path.sign == "-"))) || (((turnpolicy == TurnPolicy.majority) && (majority(bm1, x, y)))) || ((turnpolicy == TurnPolicy.minority && !majority(bm1, x, y)))) { tmp = dirx; dirx = -diry; diry = tmp; } else { tmp = dirx; dirx = diry; diry = -tmp; } } else if (r) { tmp = dirx; dirx = -diry; diry = tmp; } else if (!l) { tmp = dirx; dirx = diry; diry = -tmp; } } return(path); }