public bool[,] GetPattern(Bitmap shot) { BitmapData srcData = shot.LockBits(new Rectangle(0, 0, shot.Width, shot.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; int width = shot.Width; int height = shot.Height; bool[,] result = new bool[width, height]; unsafe { byte *p = (byte *)(void *)Scan0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int idx = (y * stride) + x * 4; double distance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.COLOR_CELL_HIDDEN); result[x, y] = (distance < 16.875); } } } shot.UnlockBits(srcData); return(result); }
public Tuple <Rect2i, Rect2i, Rect2i, int, int> GetCounterArea(Bitmap shot) { BitmapData srcData = shot.LockBits(new Rectangle(0, 0, shot.Width, shot.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; int width = shot.Width; int height = shot.Height; Rect2i resultAll; Rect2i resultNumber; Rect2i resultInner; unsafe { byte *p = (byte *)(void *)Scan0; int topx = width - 1; int topy = height - 1; #region Find Top bool fin = false; for (int x = width - 1; x >= 0 && !fin; x--) { for (int y = 0; y < height && !fin; y++) { int idx = (y * stride) + x * 4; if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topx = x; topy = y; fin = true; } } } for (int y = topy; y > 0; y--) { int idx = (y * stride) + topx * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topy = y; } if (hdistance > 50) { break; } } for (int x = topx; x < width; x++) { int idx = (topy * stride) + x * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { topx = x; } if (hdistance > 50) { break; } } #endregion int boty = topy; int botx = topx; #region Find Bottom for (int y = boty; y < height; y++) { int idx = (y * stride) + topx * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { boty = y; } if (hdistance > 50) { break; } } for (int x = topx; x < width; x--) { int idx = (topy * stride) + x * 4; double hdistance = ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER); if (ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16) { botx = x; } if (hdistance > 50) { break; } } #endregion resultAll = new Rect2i(botx, topy, topx - botx, boty - topy); int midy = topy; #region Find Middle bool firstHill = false; for (int y = topy; y < boty; y++) { bool clear = true; for (int x = botx; x < topx; x++) { int idx = (y * stride) + x * 4; clear &= ColorExt.GetColorDistance(p[idx + 2], p[idx + 1], p[idx + 0], COLOR_COUNTER) < 16; } firstHill |= !clear; if (firstHill && clear) { midy = y; break; } } #endregion resultNumber = new Rect2i(botx, midy, topx - botx, boty - midy); #region Find Inner Area int minX = topx; int maxX = botx; int minY = boty; int maxY = midy; for (int x = botx; x <= topx; x++) { for (int y = midy; y < boty; y++) { int idx = (y * stride) + x * 4; if (ColorExt.GetSaturation(p[idx + 2], p[idx + 1], p[idx + 0]) < 5) { minX = Math.Min(minX, x); maxX = Math.Max(maxX, x); minY = Math.Min(minY, y); maxY = Math.Max(maxY, y); } } } #endregion resultInner = new Rect2i(minX, minY, maxX - minX + 1, maxY - minY + 1); } shot.UnlockBits(srcData); var ignore_x = MathExt.Min(resultAll.bl.X - 10, resultNumber.bl.X - 10, resultInner.bl.X - 10); var ignore_y = MathExt.Max(resultAll.bl.Y + 10, resultNumber.bl.Y + 10, resultInner.bl.Y + 10); return(Tuple.Create(resultAll, resultNumber, resultInner, ignore_x, ignore_y)); }
public bool[,] GetPattern(Bitmap shot, HexPatternParameter pparams, int ignore_x, int ignore_y) { BitmapData srcData = shot.LockBits(new Rectangle(0, 0, shot.Width, shot.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr Scan0 = srcData.Scan0; int stride = srcData.Stride; int width = shot.Width; int height = shot.Height; bool[,] result = new bool[width, height]; ColorExt.Cache(HexagonCellImage.REAL_COLOR_CELL_ACTIVE); ColorExt.Cache(HexagonCellImage.REAL_COLOR_CELL_HIDDEN); ColorExt.Cache(HexagonCellImage.REAL_COLOR_CELL_INACTIVE); unsafe { byte *p = (byte *)(void *)Scan0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (x > ignore_x && y < ignore_y) { continue; } int idx = (y * stride) + x * 4; result[x, y] = false; if (pparams.UseActiveCellsInBinaryGridRecognition) { var ok = ((pparams.ActiveCellHueThreshold >= 255) || ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_ACTIVE) < pparams.ActiveCellHueThreshold) && ((pparams.ActiveCellSatThreshold >= 255) || ColorExt.GetSaturationDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_ACTIVE) < pparams.ActiveCellSatThreshold) && ((pparams.ActiveCellValThreshold >= 255) || ColorExt.GetValueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_ACTIVE) < pparams.ActiveCellValThreshold); if (ok) { result[x, y] = true; continue; } } if (pparams.UseHiddenCellsInBinaryGridRecognition) { var ok = ((pparams.HiddenCellHueThreshold >= 255) || ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_HIDDEN) < pparams.HiddenCellHueThreshold) && ((pparams.HiddenCellSatThreshold >= 255) || ColorExt.GetSaturationDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_HIDDEN) < pparams.HiddenCellSatThreshold) && ((pparams.HiddenCellValThreshold >= 255) || ColorExt.GetValueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_HIDDEN) < pparams.HiddenCellValThreshold); if (ok) { result[x, y] = true; continue; } } if (pparams.UseInactiveCellsInBinaryGridRecognition) { var ok = ((pparams.InactiveCellHueThreshold >= 255) || ColorExt.GetHueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_INACTIVE) < pparams.InactiveCellHueThreshold) && ((pparams.InactiveCellSatThreshold >= 255) || ColorExt.GetSaturationDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_INACTIVE) < pparams.InactiveCellSatThreshold) && ((pparams.InactiveCellValThreshold >= 255) || ColorExt.GetValueDistance(p[idx + 2], p[idx + 1], p[idx + 0], HexagonCellImage.REAL_COLOR_CELL_INACTIVE) < pparams.InactiveCellValThreshold); if (ok) { result[x, y] = true; continue; } } } } } shot.UnlockBits(srcData); return(result); }