UserNoName

UserNoName

  • 1.5k
  • 205
  • 249

Search by tags

Nov 2 2024 8:05 AM
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing.Imaging;

namespace Shooting
{
    public partial class Form1 : Form
    {
        private FilterInfoCollection CaptureDevices;
        private VideoCaptureDevice FinalFrame;
        private bool searchPixels = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            foreach (FilterInfo Device in CaptureDevices)
            {
                DeviceNameToolStripMenuItem.Items.Add(Device.Name);
            }
            DeviceNameToolStripMenuItem.SelectedIndex = 0;
            StartVideoImage();
        }

        private void StartVideoImage()
        {
            FinalFrame = new VideoCaptureDevice(CaptureDevices[DeviceNameToolStripMenuItem.SelectedIndex].MonikerString);
            FinalFrame.NewFrame += new NewFrameEventHandler(FinalFrame_NewFrame);
            FinalFrame.Start();
        }

        private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {

            System.Drawing.Image image = (Bitmap)eventArgs.Frame.Clone();
            image = MakeGrayscale((Bitmap)image);


            using (Graphics g = Graphics.FromImage(image))
            {

                int width = image.Width;
                int height = image.Height;


                int thirdWidth = width / 3;
                int thirdHeight = height / 3;


                g.DrawLine(Pens.Red, thirdWidth, 0, thirdWidth, height);
                g.DrawLine(Pens.Red, 2 * thirdWidth, 0, 2 * thirdWidth, height);

                g.DrawLine(Pens.Red, 0, thirdHeight, width, thirdHeight);
                g.DrawLine(Pens.Red, 0, 2 * thirdHeight, width, 2 * thirdHeight);

            }


            if (searchPixels)
            {
                ProcessImage((Bitmap)image);
            }

            VideoImage.Image = image;
        }

        private void ProcessImage(Bitmap image)
        {

            Bitmap binaryImage = Binarize(image, CalculateBlackThreshold(image));


            using (Graphics g = Graphics.FromImage(image))
            {

                Rectangle? markerRect = FindMarker(binaryImage);


                if (markerRect.HasValue)
                {
                    g.DrawRectangle(Pens.Yellow, markerRect.Value);
                }
            }
        }

        private Rectangle? FindMarker(Bitmap binaryImage)
        {
            int width = binaryImage.Width / 3;
            int height = binaryImage.Height / 3;
            int maxDistance = 3;

            int? minX = null, minY = null, maxX = null, maxY = null;

            for (int y = 0; y < height; y++)
            {
                int horizontalCurrentColor = -1;
                int horizontalCount = 0;
                int horizontalLastX = -1;

                for (int x = 0; x < width; x++)
                {
                    int pixelColor = binaryImage.GetPixel(x, y).R;

                    if (pixelColor != horizontalCurrentColor)
                    {
                        if (horizontalCurrentColor != -1)
                        {
                            if ((horizontalCurrentColor == 0 && pixelColor == 255) || (horizontalCurrentColor == 255 && pixelColor == 0))
                            {
                                if (horizontalLastX != -1 && (x - horizontalLastX) <= maxDistance)
                                {
                                    horizontalCount++;
                                }
                                else
                                {
                                    horizontalCount = 1;
                                }
                            }
                            else
                            {
                                horizontalCount = 0;
                            }
                        }

                        horizontalCurrentColor = pixelColor;
                        horizontalLastX = x;

                        if (horizontalCount >= 3)
                        {
                            if (!minX.HasValue || x < minX) minX = x;
                            if (!maxX.HasValue || x > maxX) maxX = x;
                            if (!minY.HasValue || y < minY) minY = y;
                            if (!maxY.HasValue || y > maxY) maxY = y;
                        }
                    }
                }
            }

            for (int x = 0; x < width; x++)
            {
                int verticalCurrentColor = -1;
                int verticalCount = 0;
                int verticalLastY = -1;

                for (int y = 0; y < height; y++)
                {
                    int pixelColor = binaryImage.GetPixel(x, y).R;

                    if (pixelColor != verticalCurrentColor)
                    {
                        if (verticalCurrentColor != -1)
                        {
                            if ((verticalCurrentColor == 0 && pixelColor == 255) || (verticalCurrentColor == 255 && pixelColor == 0))
                            {
                                if (verticalLastY != -1 && (y - verticalLastY) <= maxDistance)
                                {
                                    verticalCount++;
                                }
                                else
                                {
                                    verticalCount = 1;
                                }
                            }
                            else
                            {
                                verticalCount = 0;
                            }
                        }

                        verticalCurrentColor = pixelColor;
                        verticalLastY = y;

                        if (verticalCount >= 3)
                        {
                            if (!minX.HasValue || x < minX) minX = x;
                            if (!maxX.HasValue || x > maxX) maxX = x;
                            if (!minY.HasValue || y < minY) minY = y;
                            if (!maxY.HasValue || y > maxY) maxY = y;
                        }
                    }
                }
            }

            if (minX.HasValue && minY.HasValue && maxX.HasValue && maxY.HasValue)
            {
                Rectangle marker = new Rectangle(minX.Value, minY.Value, maxX.Value - minX.Value, maxY.Value - minY.Value);

                if (IsSurroundedByWhite(binaryImage, marker))
                {
                    return marker;
                }
            }

            return null;
        }

        private Bitmap Binarize(Bitmap original, int threshold)
        {
            Bitmap binarizedBmp = new Bitmap(original.Width, original.Height);
            Rectangle rect = new Rectangle(0, 0, original.Width, original.Height);
            BitmapData originalData = original.LockBits(rect, ImageLockMode.ReadOnly, original.PixelFormat);
            BitmapData binarizedData = binarizedBmp.LockBits(rect, ImageLockMode.WriteOnly, binarizedBmp.PixelFormat);

            unsafe
            {
                byte* originalPtr = (byte*)originalData.Scan0;
                byte* binarizedPtr = (byte*)binarizedData.Scan0;

                for (int y = 0; y < original.Height; y++)
                {
                    for (int x = 0; x < original.Width; x++)
                    {
                        int pixelIndex = y * originalData.Stride + x * 4;
                        byte blue = originalPtr[pixelIndex];
                        byte green = originalPtr[pixelIndex + 1];
                        byte red = originalPtr[pixelIndex + 2];

                        int brightness = (int)(red * 0.3 + green * 0.59 + blue * 0.11);
                        byte newColor = (byte)(brightness >= threshold ? 255 : 0);

                        binarizedPtr[pixelIndex] = newColor;
                        binarizedPtr[pixelIndex + 1] = newColor;
                        binarizedPtr[pixelIndex + 2] = newColor;
                        binarizedPtr[pixelIndex + 3] = 255;
                    }
                }
            }

            original.UnlockBits(originalData);
            binarizedBmp.UnlockBits(binarizedData);
            return binarizedBmp;
        }


        private int CalculateBlackThreshold(Bitmap image)
        {
            double averageBrightness = CalculateAverageBrightness(image);
            double standardDeviation = CalculateStandardDeviation(image, averageBrightness);
            return (int)(averageBrightness - 2 * standardDeviation);
        }
        private double CalculateAverageBrightness(Bitmap image)
        {
            int sumBrightness = 0;
            int count = 0;

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    Color pixelColor = image.GetPixel(x, y);
                    int brightness = (int)(pixelColor.R * 0.3 + pixelColor.G * 0.59 + pixelColor.B * 0.11);
                    sumBrightness += brightness;
                    count++;
                }
            }

            return (double)sumBrightness / count;
        }

        private double CalculateStandardDeviation(Bitmap image, double averageBrightness)
        {
            double sumSquaredDifference = 0;
            int count = 0;

            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    Color pixelColor = image.GetPixel(x, y);
                    int brightness = (int)(pixelColor.R * 0.3 + pixelColor.G * 0.59 + pixelColor.B * 0.11);
                    double squaredDifference = Math.Pow(brightness - averageBrightness, 2);
                    sumSquaredDifference += squaredDifference;
                    count++;
                }
            }

            return Math.Sqrt(sumSquaredDifference / count);
        }

        public Bitmap MakeGrayscale(Bitmap original)
        {
            Bitmap newBmp = new Bitmap(original.Width, original.Height);
            using (Graphics g = Graphics.FromImage(newBmp))
            {
                ColorMatrix colorMatrix = new ColorMatrix(new float[][]
                {
                    new float[] {0.3f, 0.3f, 0.3f, 0, 0},
                    new float[] {0.59f, 0.59f, 0.59f, 0, 0},
                    new float[] {0.11f, 0.11f, 0.11f, 0, 0},
                    new float[] {0, 0, 0, 1, 0},
                    new float[] {0, 0, 0, 0, 1}
                });

                ImageAttributes imgAttr = new ImageAttributes();
                imgAttr.SetColorMatrix(colorMatrix);
                g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
                    0, 0, original.Width, original.Height, GraphicsUnit.Pixel, imgAttr);
            }

            return newBmp;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (FinalFrame != null)
            {
                if (FinalFrame.IsRunning)
                {
                    FinalFrame.SignalToStop();
                    FinalFrame.WaitForStop();
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            searchPixels = true;
        }

        private void BlackThresholdTrackBar_Scroll(object sender, EventArgs e)
        {


        }

        private bool IsSurroundedByWhite(Bitmap binaryImage, Rectangle marker)
        {
            for (int x = marker.Left - 1; x <= marker.Right + 1; x++)
            {
                if (x < 0 || x >= binaryImage.Width) continue;
                if (binaryImage.GetPixel(x, marker.Top - 1).R == 0) return false; // ????
                if (binaryImage.GetPixel(x, marker.Bottom + 1).R == 0) return false; // ???
            }

            for (int y = marker.Top - 1; y <= marker.Bottom + 1; y++)
            {
                if (y < 0 || y >= binaryImage.Height) continue;
                if (binaryImage.GetPixel(marker.Left - 1, y).R == 0) return false; // ????
                if (binaryImage.GetPixel(marker.Right + 1, y).R == 0) return false; // ?????
            }

            return true;
        }


    }
}

Good afternoon. Please tell me what algorithm you can use to find the label data on the image via a webcam in real time


Answers (1)