public BoardInfo ProcessImage(BoardParameters bp, Pixels pix)
        {
            BoardInfo boardInfo = null;
            boardInfo = new BoardInfo(bp.FieldWidth, bp.FieldHeight);
            int halfSize = (int)(bp.BlockSize / 2) + 1;
            int[,] circleRadiusData = CalculateRadii((dx, dy) => (int)Math.Sqrt(dx * dx + dy * dy), halfSize);
            int[,] squareRadiusData = CalculateRadii((dx, dy) => (int)Math.Max(Math.Abs(dx), Math.Abs(dy)), halfSize);

            for (int y = 0; y < bp.FieldHeight; y++)
                for (int x = 0; x < bp.FieldWidth; x++)
                {
                    int px = (int)Math.Round(bp.LinedBoardRect.Left + bp.BlockSize * x);
                    int py = (int)Math.Round(bp.LinedBoardRect.Top + bp.BlockSize * y);
                    RawColor[] circles = RadiusColor(pix,
                        new Point(px, py),
                        circleRadiusData,
                        2 * halfSize
                        );
                    RawColor[] squares = RadiusColor(pix,
                        new Point(px, py),
                        squareRadiusData,
                        2 * halfSize
                        );

                    PointInfo info = new PointInfo();
                    info.StoneColor = GetStoneColor(circles, bp.BlockSize);
                    info.SmallStoneColor = GetSmallStoneColor(circles, bp.BlockSize);
                    if (info.SmallStoneColor == info.StoneColor)//Small stone is part of the real stone
                        info.SmallStoneColor = StoneColor.None;
                    if (GetCircleMarker(circles, bp.BlockSize, info.StoneColor))
                    {
                        if (info.SmallStoneColor != StoneColor.Black)//Can't distinguish circle from small stone
                            info.Marker = Marker.Circle;
                    }
                    if (GetSquareMarker(squares, bp.BlockSize, info.StoneColor))
                        info.Marker = Marker.Square;
                    boardInfo.Board[x, y] = info;
                }
            //MirrorBoardInfo(boardInfo);

            return boardInfo;
        }
        public bool GetBoardParameters(Pixels pix, out BoardParameters bp)
        {
            bp = new BoardParameters();
            bp.BoardRect = System.Drawing.Rectangle.Empty;
            bp.LinedBoardRect = System.Drawing.Rectangle.Empty;
            bp.FieldHeight = 0;
            bp.FieldWidth = 0;
            bp.BlockSize = 0;

            bp.BoardRect = FindBoard(pix);
            if (bp.BoardRect == System.Drawing.Rectangle.Empty)
                return false;
            float[] grayCols, grayRows;
            bp.LinedBoardRect = FindLinedBoard(pix, bp.BoardRect, out grayCols, out grayRows);
            double blockWidth, blockHeight;
            bool foundLines1 = CalculateFieldPosition(bp.LinedBoardRect.Left, bp.LinedBoardRect.Width, grayCols, out bp.FieldWidth, out blockWidth);
            bool foundLines2 = CalculateFieldPosition(bp.LinedBoardRect.Top, bp.LinedBoardRect.Height, grayRows, out bp.FieldHeight, out blockHeight);
            if (Math.Abs(blockHeight - blockWidth) > 1)
                return false;
            bp.BlockSize = (blockHeight + blockWidth) / 2;
            return foundLines1 && foundLines2;
        }
 private Pixels BitmapToPixels(Bitmap bmp)
 {
     Pixels pix = new Pixels(pixelPool.Alloc(bmp.Width, bmp.Height));
     pix.LoadFromBitmap(bmp);
     return pix;
 }
 public void Release(Pixels pix)
 {
     if (pix.Data != null)
         pixelPool.Release(pix.Data);
 }
 private void timer1_Tick(object sender, EventArgs e)
 {
     DateTime start0 = DateTime.UtcNow;
     if (this.Handle != ScreenCapture.GetForegroundWindow() && goRecorder == null)
         windowHandle = ScreenCapture.GetForegroundWindow();
     if (windowHandle == IntPtr.Zero)
         return;
     Window window = new Window(windowHandle);
     WindowTitle.Text = window.Title;
     if (windowHandle != ScreenCapture.GetForegroundWindow())//Capturing background windows is buggy
         return;
     Pixels pix = capturer.Capture(windowHandle);
     //allocStats.Text = "Alloc:" + capturer.CacheMissAllocs + "/" + capturer.TotalAllocs;
     //bmp.Save("ScreenShot.bmp");
     if (!Pixels.DataEquals(oldPixels, pix))
     {
         frameCounter++;
         FrameCounterLabel.Text = frameCounter.ToString();
         BoardInfo board = null;
         ImageToBoardInfo imageToBoardInfo = new ImageToBoardInfo();
         if (!(found && pix.Width == size.Width && pix.Height == size.Height))
         {
             found = imageToBoardInfo.GetBoardParameters(pix, out bp);
             size = pix.Size;
         }
         if (found)
             board = imageToBoardInfo.ProcessImage(bp, pix);
         if (board != null)
         {
             if (goRecorder != null)
             {
                 goRecorder.Add(Duration, board);
                 goRecorder.Replay.Save("Capture.GoVideo");
             }
             GameState gameState = GoVideoToReplay.BoardToGameState(board);
             StateRenderer renderer = new StateRenderer(new GoClient.Drawing.GraphicsSystem());
             renderer.BlockSize = 16;
             renderer.State = gameState;
             Preview.Image = ((GoClient.Drawing.Bitmap)renderer.Render()).InternalBitmap;
         }
     }
     ProcessingTime.Text = TS(DateTime.UtcNow - start0);
     timeLabel.Text = TimeSpan.FromSeconds(Math.Round(Duration.TotalSeconds)).ToString();
     capturer.Release(oldPixels);
     oldPixels = pix;
 }
 private void start_Click(object sender, EventArgs e)
 {
     AudioCheckBox.Enabled = false;
     RecordButton.Enabled = false;
     FinishButton.Enabled = true;
     goRecorder = new GoVideoRecorder();
     RecordingStart = DateTime.UtcNow;
     timeLabel.Text = "Starting...";
     frameCounter = 0;
     capturer.Release(oldPixels);
     oldPixels = Pixels.Null;
     if (AudioCheckBox.Checked)
     {
         audioRecorder = new Recorder(0.3f);
         audioRecorder.Paused = false;
     }
 }
示例#7
0
 public void Release(Pixels pix)
 {
     Release(pix.Data);
 }
示例#8
0
 public static Pixels CreateFromBitmap(Bitmap bmp)
 {
     Pixels pix = new Pixels(bmp.Width, bmp.Height);
     pix.LoadFromBitmap(bmp);
     return pix;
 }
示例#9
0
 public static bool DataEquals(Pixels pix1, Pixels pix2)
 {
     if (pix1.Width != pix2.Width || pix1.Height != pix2.Height)
         return false;
     if (pix1.Data == pix2.Data)
         return true;
     if (pix1.Data == null || pix2.Data == null)
         return false;
     int len = pix1.Width * pix1.Height;
     for (int i = 0; i < len; i++)
         if (pix1.Data[i] != pix2.Data[i])
             return false;
     return true;
 }
 RawColor[] RadiusColor(Pixels pix, Point center, int[,] radiusData, int maxRadius)
 {
     int[] counts = new int[maxRadius + 1];
     int[] sumR = new int[maxRadius + 1];
     int[] sumG = new int[maxRadius + 1];
     int[] sumB = new int[maxRadius + 1];
     RawColor[] result = new RawColor[maxRadius + 1];
     int halfSize = (radiusData.GetLength(0) - 1) / 2;
     int dx = halfSize - center.X;
     int dy = halfSize - center.Y;
     int left = Math.Max(0, center.X - halfSize);
     int top = Math.Max(0, center.Y - halfSize);
     int right = Math.Min(pix.Width, center.X + halfSize + 1);
     int bottom = Math.Min(pix.Height, center.Y + halfSize + 1);
     for (int y = top; y < bottom; y++)
         for (int x = left; x < right; x++)
         {
             RawColor c = pix.Data[x, y];
             int radius = radiusData[x + dx, y + dy];
             counts[radius]++;
             sumR[radius] += c.R;
             sumG[radius] += c.G;
             sumB[radius] += c.B;
         }
     RawColor undefined = RawColor.Transparent;
     for (int i = 0; i < maxRadius + 1; i++)
     {
         if (counts[i] == 0)
             result[i] = undefined;
         else
         {
             result[i] = RawColor.FromRGB(
                 (byte)(sumR[i] / counts[i]),
                 (byte)(sumG[i] / counts[i]),
                 (byte)(sumB[i] / counts[i]));
         }
     }
     return result;
 }
 System.Drawing.Rectangle FindLinedBoard(Pixels pix, System.Drawing.Rectangle boardRect, out float[] grayCols, out float[] grayRows)
 {
     CountPixels(pix, boardRect, IsGray, out grayCols, out grayRows);
     float[] grayCols2 = grayCols;
     float[] grayRows2 = grayRows;
     int left = (int)grayCols.FirstIndex((f, i) => IsLine(grayCols2, i));
     int right = (int)grayCols.LastIndex((f, i) => IsLine(grayCols2, i)) + 1;
     int top = (int)grayRows.FirstIndex((f, i) => IsLine(grayRows2, i));
     int bottom = (int)grayRows.LastIndex((f, i) => IsLine(grayRows2, i)) + 1;
     return System.Drawing.Rectangle.FromLTRB(left, top, right, bottom);
 }
        System.Drawing.Rectangle FindBoard(Pixels pix)
        {
            float[] boardCols, boardRows;
            CountPixels(pix, pix.Rect, IsBoard, out boardCols, out boardRows);
            float max = boardCols.Max();
            if (max < 0.1)
                return System.Drawing.Rectangle.Empty;
            int left = (int)boardCols.FirstIndex(f => f >= 0.8f * max);
            int right = (int)boardCols.LastIndex(f => f >= 0.8f * max) + 1;

            CountPixels(pix, new System.Drawing.Rectangle(left, 0, right - left, pix.Height), IsBoard, out boardCols, out boardRows);
            max = boardRows.Max();
            int top = (int)boardRows.FirstIndex(f => f >= 0.8f * max);
            int bottom = (int)boardRows.LastIndex(f => f >= 0.8f * max) + 1;

            return System.Drawing.Rectangle.FromLTRB(left, top, right, bottom);
        }
 private void CountPixels(Pixels pix, System.Drawing.Rectangle rect, Predicate<RawColor> filter, out float[] cols, out float[] rows)
 {
     int[] colsI = new int[pix.Width];
     int[] rowsI = new int[pix.Height];
     for (int y = rect.Top; y < rect.Bottom; y++)
     {
         for (int x = rect.Left; x < rect.Right; x++)
         {
             RawColor c = pix.Data[x, y];
             if (filter(c))
             {
                 colsI[x]++;
                 rowsI[y]++;
             }
         }
     }
     cols = new float[pix.Width];
     rows = new float[pix.Height];
     for (int x = 0; x < cols.Length; x++)
     {
         if (x < rect.Left || x > rect.Right - 1)
             cols[x] = float.NaN;
         else
             cols[x] = (float)colsI[x] / rect.Height;
     }
     for (int y = 0; y < rows.Length; y++)
     {
         if (y < rect.Top || y > rect.Bottom - 1)
             rows[y] = float.NaN;
         else
             rows[y] = (float)rowsI[y] / rect.Width;
     }
 }