예제 #1
0
        static void Main()
        {
            BlockConfiguration CameraBlockConfiguration = new BlockConfiguration(new Size(608, 608));

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FrmSolitaire(CameraBlockConfiguration));
        }
예제 #2
0
        Rectangle[] GenerateRegions(Image source, BlockConfiguration blockConfiguration)
        {
            List <Rectangle> regions = new List <Rectangle>();

            for (int x = 0; x < source.Width; x += blockConfiguration.BlockSize.Width)
            {
                for (int y = 0; y < source.Height; y += blockConfiguration.BlockSize.Height)
                {
                    regions.Add(new Rectangle(x, y, blockConfiguration.BlockSize.Width, blockConfiguration.BlockSize.Height));
                }
            }
            return(regions.ToArray());
        }
예제 #3
0
 public WebcamSource(GraphicBuffer UpdateBuffer, BlockConfiguration BlockConfig)
 {
     this.BlockConfig  = BlockConfig;
     this.UpdateBuffer = UpdateBuffer;
 }
예제 #4
0
        public FrmSolitaire(BlockConfiguration blockConfiguration)
        {
            FontFamily fontFamily = new FontFamily("Arial");

            obsFont = new Font(
                fontFamily,
                25,
                FontStyle.Regular,
                GraphicsUnit.Pixel);

            InitializeComponent();

            var gui = new FrmSolitaireGUI(this);

            gui.Show();

            var yoloWrapper = InitializeYoloWrapper();

            if (yoloWrapper == default)
            {
                return;                        //error case.
            }
            var detector = new YoloDetector(yoloWrapper);

            gBuffer = new GraphicBuffer(pnlGraphics);
            WebcamSource source = new WebcamSource(gBuffer, blockConfiguration);

            Brush redBrush   = new SolidBrush(Color.Red);
            Brush greenBrush = new SolidBrush(Color.Green);
            Brush blackBrush = new SolidBrush(Color.Black);
            Brush whiteBrush = new SolidBrush(Color.White);
            Pen   redPen     = new Pen(redBrush, 2);
            Pen   blackPen   = new Pen(blackBrush, 2);

            CvModel[] oldCardModels = default;
            Image     lastSource    = default;

            Rectangle[] regions = default;

            Thread detectionThread = new Thread(() => {
                while (true)
                {
                    //Thread.Sleep(200);

                    if (lastSource != default)
                    {
                        Image sourceCopy = null;
                        lock (mutex)
                        {
                            sourceCopy = (Image)lastSource.Clone();
                            if (regions == default)
                            {
                                regions = GenerateRegions(sourceCopy, blockConfiguration);
                            }
                        }

                        var foundCards = new List <CvModel>();

                        // split image into regional bitmaps
                        foreach (var region in regions)
                        {
                            var currentRegionBmp         = new Bitmap(blockConfiguration.BlockSize.Width, blockConfiguration.BlockSize.Height);
                            var currentRegionBmpGraphics = Graphics.FromImage(currentRegionBmp);

                            currentRegionBmpGraphics.DrawImage(sourceCopy, new Rectangle(0, 0, region.Width, region.Height), region, GraphicsUnit.Pixel);

                            foundCards.AddRange(detector.DetectObjects((Bitmap)currentRegionBmp, region));
                            currentRegionBmpGraphics.Dispose();
                        }

                        lock (mutex)
                        {
                            oldCardModels = foundCards.ToArray();
                            OnScanComplete?.Invoke(oldCardModels);
                        }
                        sourceCopy.Dispose();
                    }
                }
            });

            detectionThread.Start();

            gBuffer.OnDraw += e =>
            {
                lock (mutex)
                {
                    lastSource = e.Source;

                    if (regions != default)
                    {
                        int regionIndex = 0;
                        foreach (var region in regions)
                        {
                            regionIndex++;
                            e.BackBufferGraphics.DrawRectangle(blackPen, region);
                        }
                    }

                    if (oldCardModels != default)
                    {
                        foreach (var card in oldCardModels)
                        {
                            var bounds = new Rectangle(card.BoundingBox.X + card.Look_Bounds.X, card.BoundingBox.Y + card.Look_Bounds.Y, card.BoundingBox.Width, card.BoundingBox.Height);

                            //e.BackBufferGraphics.DrawRectangle(redPen, bounds);

                            var offset     = new Point(0, -25);
                            var confidence = card.Confidence;
                            confidence *= 100;


                            //e.BackBufferGraphics.DrawString($"{card.Type}: {(int)confidence}%", this.Font, blackBrush, new Point(offset.X + bounds.X + 1, offset.Y + bounds.Y + 1));
                            //e.BackBufferGraphics.DrawString($"{card.Type}: {(int)confidence}%", this.Font, greenBrush, new Point(offset.X + bounds.X, offset.Y + bounds.Y));
                        }
                    }

                    var GreenLowAlpha = Color.FromArgb(100, Color.Green);

                    var TransformedObservations = gui.BoardController.Transformed;
                    if (TransformedObservations != default)
                    {
                        foreach (var TransformedObservation in TransformedObservations)
                        {
                            var StartPoint = TransformedObservation.MinWorldPoint;
                            var Size       = new Size(TransformedObservation.MaxWorldPoint.X - TransformedObservation.MinWorldPoint.X, TransformedObservation.MaxWorldPoint.Y - TransformedObservation.MinWorldPoint.Y);
                            var Center     = new Point(
                                StartPoint.X + (TransformedObservation.MaxWorldPoint.X - TransformedObservation.MinWorldPoint.X) / 2 - 50,
                                StartPoint.Y + (TransformedObservation.MaxWorldPoint.Y - TransformedObservation.MinWorldPoint.Y) / 2 - 15);


                            e.BackBufferGraphics.FillRectangle(new SolidBrush(GreenLowAlpha), new Rectangle(StartPoint, Size));
                            e.BackBufferGraphics.DrawString($"{GetCardName(TransformedObservation.Type)}: {(int)(TransformedObservation.Confidence*100)} %", obsFont, blackBrush, Center);
                            e.BackBufferGraphics.DrawRectangle(new Pen(new SolidBrush(Color.Yellow)), new Rectangle(StartPoint, Size));
                        }
                        //e.BackBufferGraphics.FillRectangle(new SolidBrush(Color.Yellow), new Rectangle(_obs.MinWorldPoint.X, _obs.MinWorldPoint.Y, 5, 5));
                    }
                }

                e.BackBufferGraphics.DrawString($"FPS: {gBuffer.fps}", this.Font, blackBrush, new Point(5, 5));
                e.BackBufferGraphics.DrawString($"FPS: {gBuffer.fps}", this.Font, whiteBrush, new Point(4, 4));
            };

            source.Start();
            FormClosing += (s, e) =>
            {
                source.Stop();
                detectionThread.Abort();
            };
        }