示例#1
0
        public HexcellsSolver(HexPatternParameter pparam)
        {
            _patternParameter = pparam;

            Dictionary <string, Bitmap> refdic = new Dictionary <string, Bitmap>();

            refdic.Add("-", Properties.Resources.pattern_dash);
            refdic.Add("{", Properties.Resources.pattern_Open);
            refdic.Add("}", Properties.Resources.pattern_Close);
            refdic.Add("?", Properties.Resources.pattern_QMark);
            refdic.Add("0", Properties.Resources.pattern_0);
            refdic.Add("1", Properties.Resources.pattern_1);
            refdic.Add("2", Properties.Resources.pattern_2);
            refdic.Add("3", Properties.Resources.pattern_3);
            refdic.Add("4", Properties.Resources.pattern_4);
            refdic.Add("5", Properties.Resources.pattern_5);
            refdic.Add("6", Properties.Resources.pattern_6);
            refdic.Add("7", Properties.Resources.pattern_7);
            refdic.Add("8", Properties.Resources.pattern_8);
            refdic.Add("9", Properties.Resources.pattern_9);
            refdic.Add("10", Properties.Resources.pattern_10);
            refdic.Add("12", Properties.Resources.pattern_12);
            refdic.Add("13", Properties.Resources.pattern_13);
            refdic.Add("14", Properties.Resources.pattern_14);
            refdic.Add("15", Properties.Resources.pattern_15);
            refdic.Add("16", Properties.Resources.pattern_16);
            refdic.Add("17", Properties.Resources.pattern_17);
            refdic.Add("18", Properties.Resources.pattern_18);
            refdic.Add("19", Properties.Resources.pattern_19);


            POCR = new PatternOCR(refdic, OCRCoupling.NORMAL_COUPLED_SEGMENTS);
            Cam  = new HexCam();
            OCR  = new HexOCR(POCR);
        }
示例#2
0
        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);
        }
示例#3
0
        public HexGridProperties FindHexPattern(Bitmap shot, HexPatternParameter pparams)
        {
            double CellRadius;
            double CellGap;
            double CorrectionHorizontal;
            double CorrectionVertical;
            double PaddingX;
            double PaddingY;
            double NoCellBar_TR_X;
            double NoCellBar_TR_Y;
            bool   InitialSwap;
            Rect2i CounterArea;
            Rect2i CounterAreaInner;

            //##################################

            var counter = GetCounterArea(shot);

            bool[,] pattern = GetPattern(shot, pparams, counter.Item4, counter.Item5);
            var    centers   = GetHexPatternCenters(pattern, shot.Width, shot.Height, out _);
            var    grid      = GetHexPatternGrid(centers);
            double hexHeight = GetHexPatternHeight(pattern, shot.Height, centers) - 2;
            var    distance  = GetHexPatternDistance(grid);

            CellRadius           = hexHeight * (Math.Sin(MathExt.ToRadians(90)) / Math.Sin(MathExt.ToRadians(60)));
            CellGap              = distance.Item2 * 2 - hexHeight * 2;
            CorrectionVertical   = 0;
            CorrectionHorizontal = distance.Item1 - (2 * hexHeight + CellGap) * Math.Cos(MathExt.ToRadians(30));

            var anchor = centers.OrderBy(p => p.X).ThenBy(p => p.Y).First();

            PaddingX    = anchor.X;
            PaddingY    = anchor.Y;
            InitialSwap = false;

            int offsetX = 0;

            while (PaddingX - (hexHeight * 2 + CellGap + CorrectionVertical) > CellRadius + CellGap)
            {
                PaddingX -= hexHeight * 2 + CellGap + CorrectionVertical;
                offsetX++;

                InitialSwap = !InitialSwap;
            }
            double calculatedPosX = PaddingX + ((hexHeight + CellGap + hexHeight) * (Math.Cos(MathExt.ToRadians(30))) + CorrectionHorizontal) * offsetX;

            PaddingX += anchor.X - calculatedPosX;

            int offsetY = 0;

            while (PaddingY - ((2 * hexHeight + CellGap) * Math.Cos(MathExt.ToRadians(30)) + CorrectionHorizontal) > CellRadius + CellGap)
            {
                PaddingY -= (2 * hexHeight + CellGap) * Math.Cos(MathExt.ToRadians(30)) + CorrectionHorizontal;
                offsetY++;
            }
            double calculatedPosY = PaddingY + (hexHeight + CellGap + hexHeight + CorrectionVertical) * offsetY;

            PaddingY += anchor.Y - calculatedPosY;

            NoCellBar_TR_X = 175;
            NoCellBar_TR_Y = 165;

            CounterArea      = counter.Item2;
            CounterAreaInner = counter.Item3;

            //##################################

            return(new HexGridPropertiesBuilder()
                   .SetCellRadius(CellRadius)
                   .SetCellGap(CellGap)
                   .SetCorrectionHorizontal(CorrectionHorizontal)
                   .SetCorrectionVertical(CorrectionVertical)
                   .SetPaddingX(PaddingX)
                   .SetPaddingY(PaddingY)
                   .SetNoCellBar_TR_X(NoCellBar_TR_X)
                   .SetNoCellBar_TR_Y(NoCellBar_TR_Y)
                   .SetInitialSwap(InitialSwap)
                   .SetCounter_X(CounterArea.bl.X)
                   .SetCounter_Y(CounterArea.bl.Y)
                   .SetCounter_Width(CounterArea.Width)
                   .SetCounter_Height(CounterArea.Height)
                   .SetCounterInner_X(CounterAreaInner.bl.X)
                   .SetCounterInner_Y(CounterAreaInner.bl.Y)
                   .SetCounterInner_Width(CounterAreaInner.Width)
                   .SetCounterInner_Height(CounterAreaInner.Height)
                   .build());
        }
示例#4
0
        public Bitmap DisplayBinPattern(Bitmap shot, HexOCR ocr, HexPatternParameter pparams)
        {
            shot = new Bitmap(shot);

            var counter = ocr.GetCounterArea(shot);

            bool[,] pattern = ocr.GetPattern(shot, pparams, counter.Item4, counter.Item5);
            var centers = ocr.GetHexPatternCenters(pattern, shot.Width, shot.Height, out var errs);
            var grid    = ocr.GetHexPatternGrid(centers);

            BitmapData srcData = shot.LockBits(new Rectangle(0, 0, shot.Width, shot.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            IntPtr     Scan0   = srcData.Scan0;
            int        stride  = srcData.Stride;

            int width  = shot.Width;
            int height = shot.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;

                        bool on = pattern[x, y] || counter.Item1.Includes(x, y);

                        if (errs[x, y])
                        {
                            p[idx + 0] = 0;
                            p[idx + 1] = 0;
                            p[idx + 2] = 128;
                            p[idx + 3] = 255;
                        }
                        else if (pattern[x, y])
                        {
                            p[idx + 0] = 0;
                            p[idx + 1] = 0;
                            p[idx + 2] = 0;
                            p[idx + 3] = 255;
                        }
                        else if (counter.Item1.Includes(x, y))
                        {
                            p[idx + 0] = 128;
                            p[idx + 1] = 0;
                            p[idx + 2] = 0;
                            p[idx + 3] = 255;
                        }
                        else
                        {
                            p[idx + 0] = 255;
                            p[idx + 1] = 255;
                            p[idx + 2] = 255;
                            p[idx + 3] = 255;
                        }
                    }
                }
            }

            shot.UnlockBits(srcData);

            using (Graphics g = Graphics.FromImage(shot))
            {
                Pen pen = new Pen(Color.Magenta);

                foreach (var center in centers)
                {
                    g.DrawLine(pen, (int)(center.X - 5), (int)(center.Y - 5), (int)(center.X + 5), (int)(center.Y + 5));
                    g.DrawLine(pen, (int)(center.X + 5), (int)(center.Y - 5), (int)(center.X - 5), (int)(center.Y + 5));
                }

                foreach (var row in grid.Item1)
                {
                    g.DrawLine(pen, row, 0, row, shot.Height);
                }

                foreach (var col in grid.Item2)
                {
                    g.DrawLine(pen, 0, col, shot.Width, col);
                }

                g.DrawRectangle(pen, counter.Item2.bl.X, counter.Item2.bl.Y, counter.Item2.Width, counter.Item2.Height);

                g.DrawRectangle(pen, counter.Item3.bl.X, counter.Item3.bl.Y, counter.Item3.Width, counter.Item3.Height);
            }

            return(shot);
        }