Question Search marker

Stepan

Member
Joined
Nov 1, 2024
Messages
8
Programming Experience
1-3
I need to find a marker on an image using a webcam in real time. I need to find exactly this marker and nothing else besides it. How can this be done?
Снимок экрана (177).png
 
What have you done and where are you stuck? If you haven't done anything, you don't know that you can't do it yourself yet.

not quite looking for it correctly

 
Please post just the relevant code as text in code tags.

Yes, the entire project is helpful for people who want to do try to fully reproduce the problem, but for more casual users of this forum, or those of us just reading on mobile devices, being able to read the code to focus on (if you'll pardon the pun) helps get more attention on your problem.
 
What have you done and where are you stuck? If you haven't done anything, you don't know that you can't do it yourself yet.

Please post just the relevant code as text in code tags.

Yes, the entire project is helpful for people who want to do try to fully reproduce the problem, but for more casual users of this forum, or those of us just reading on mobile devices, being able to read the code to focus on (if you'll pardon the pun) helps get more attention on your problem.
I'm trying to find these markers through the webcam, but I can't do anything, the program finds unnecessary items
C#:
using AForge.Imaging.Filters;
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 = 5;

         
            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) ||
                                (Math.Abs(horizontalCurrentColor - pixelColor) <= 1))
                            {
                                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) ||
                                (Math.Abs(verticalCurrentColor - pixelColor) <= 1))
                            {
                                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)
            {
                return new Rectangle(minX.Value, minY.Value, maxX.Value - minX.Value, maxY.Value - minY.Value);
            }

     
            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)
        {

         
        }



    }
}
 
Last edited:
Please post just the relevant code as text in code tags.

You seem to have overlooked the word "relevant" in that post. Much of the code you have posted is clearly not relevant and it's not a good use of our time to wade through it to work out what is. You need to post just the part that is relevant to the issue, along with an explanation of what you found when you debugged it, i.e. exactly what happened that you didn't expect or didn;t happen that you did expect. Note that that explanation needs to be at the code level first, and possibly at the application level too. If the code actually did what you expected but the result in the application was still wrong, that is also relevant information. It means that there's an issue with your expectations.
 
As @jmcilhinney , noted there still too much code that you dumped on us.

Just scanning the code, it looks like you are just looking for edges within a certain number of pixels away from each other, but you are not truly looking for that comb pattern that you are looking for.

Furthermore, it looks like you are only searching the top left third of the incoming image. I assume that's just leftover debugging code for the sake of speed, and eventually you'll want to search the entire image.
 
As @jmcilhinney , noted there still too much code that you dumped on us.

Just scanning the code, it looks like you are just looking for edges within a certain number of pixels away from each other, but you are not truly looking for that comb pattern that you are looking for.

Furthermore, it looks like you are only searching the top left third of the incoming image. I assume that's just leftover debugging code for the sake of speed, and eventually you'll want to search the entire image.

"but you're actually looking for the wrong template."
That's right, I can't figure out how to implement it to find this pattern.

"Moreover, it looks like you are only searching in the upper left part of the incoming image. I'm guessing it's just leftover debugging code to improve speed, and eventually you'll want to search the entire image." I'm looking for this template in one half to understand how it works at all, and then I'll search through the entire image. In general, I need to be able to find a target through a webcam, for this purpose there are such special templates on the target

If you can explain to me at least verbally what needs to be done, I will be very grateful.
 
Choose an image processing algorithm and either implement it, or pull in a library that has an implementation. There's no need to roll your own algorithm from scratch unless this is schoolwork where you are being asked to design your own algorithm.

I don't know how well suited this algorithm is for what you need. I just happened to be the among the first that Google returned. But on the right side of screen, you'll also see a bunch of other well known algorithms that may suit your problem better:
 
Choose an image processing algorithm and either implement it, or pull in a library that has an implementation. There's no need to roll your own algorithm from scratch unless this is schoolwork where you are being asked to design your own algorithm.

I don't know how well suited this algorithm is for what you need. I just happened to be the among the first that Google returned. But on the right side of screen, you'll also see a bunch of other well known algorithms that may suit your problem better:

What other algorithm can I use? This method is not suitable. I'm sorry for asking stupid questions.
 
Sorry, I deliberately did not take the computer vision and image processing class in college even though it was being taught by one of my favorite teachers. Hopefully someone can make a recommendation for you.
 
Help me finalize the program.
The bottom line is this: you need to find the labels on the image using a webcam (I use a camera from PS) in real time.

I divide the image into 9 parts and I have a label search in parts 1 and 9. After the program finds the labels, you will need to find the center of the object (there will be no problems finding the center).
How my code works:
1.The image is converted to grayscale
2. The image is binarized using the current threshold value (here I have a problem, because in order to find a label, you need to change the binarization threshold for the first quadrant, you need one binarization threshold, and for the ninth - another, if one threshold is used for the entire image, then the program finds the label only in the first quadrant, although it shouldn't be like this)
3. Then the search for markers in the binary image is performed.
4. Pixels are analyzed for the presence of black (0) and white (255) areas
5.Checks whether the found marker is surrounded by white pixels

C#:
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;
        private Rectangle? foundMarker = null;
        private int currentThreshold = 50;

        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();
            BlackThresholdTrackBar.Value = currentThreshold;
        }

        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)
        {
            /*Bitmap image = (Bitmap)eventArgs.Frame.Clone();
              Bitmap grayscaleImage = MakeGrayscale((Bitmap)image);
              Bitmap binaryImage = Binarize(grayscaleImage, CalculateBlackThreshold(grayscaleImage));
              ProcessImage(binaryImage);*/

            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);
                int centerX = width / 2;
                int centerY = height / 2;
                g.DrawLine(Pens.Blue, centerX - 10, centerY, centerX + 10, centerY);

                g.DrawLine(Pens.Blue, centerX, centerY - 10, centerX, centerY + 10);
            }

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

            VideoImage.Image = image;
        }


        private void ProcessImage(Bitmap image)
        {
            //Bitmap binaryImage = Binarize(image, CalculateBlackThreshold(image));
            Bitmap binaryImage = Binarize(image, currentThreshold);
            using (Graphics g = Graphics.FromImage(image))
            {
                Rectangle? markerRect = FindMarker(binaryImage);

                if (markerRect.HasValue)
                {

                    if (IsSurroundedByWhite(binaryImage, markerRect.Value))
                    {

                        g.DrawRectangle(Pens.Yellow, markerRect.Value);
                    }
                    /*else
                    {

                        g.DrawRectangle(Pens.Red, markerRect.Value);
                    }*/
                }
            }
        }


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

            // Определение границ первого квадранта
            int firstQuadrantStartX = 0;
            int firstQuadrantStartY = 0;
            int firstQuadrantEndX = width / 3;
            int firstQuadrantEndY = height / 3;

            // Определение границ девятого квадранта
            int ninthQuadrantStartX = 2 * (width / 3);
            int ninthQuadrantStartY = 2 * (height / 3);
            int ninthQuadrantEndX = width;
            int ninthQuadrantEndY = height;

            int maxDistance = 5;

            // Поиск маркера в первом квадранте
            foundMarker = SearchInQuadrant(binaryImage, firstQuadrantStartX, firstQuadrantStartY, firstQuadrantEndX, firstQuadrantEndY, maxDistance);
            if (foundMarker.HasValue)
            {
                return foundMarker;
            }

            // Поиск маркера в девятом квадранте
            foundMarker = SearchInQuadrant(binaryImage, ninthQuadrantStartX, ninthQuadrantStartY, ninthQuadrantEndX, ninthQuadrantEndY, maxDistance);
            if (foundMarker.HasValue)
            {
                return foundMarker;
            }

            return null;
        }

        private Rectangle? SearchInQuadrant(Bitmap binaryImage, int startX, int startY, int endX, int endY, int maxDistance)
        {
            int? minX = null, minY = null, maxX = null, maxY = null;
            bool inMarker = false;

            for (int y = startY; y < endY; y++)
            {
                int lastX = -1; // Последний найденный X
                for (int x = startX; x < endX; x++)
                {
                    int pixelColor = binaryImage.GetPixel(x, y).R;

                    if (pixelColor == 0) // Черный
                    {
                        if (!inMarker)
                        {
                            inMarker = true; // Начинаем новый маркер
                            minX = x; // Устанавливаем начальные границы
                            minY = y;
                        }
                        lastX = x; // Обновляем последний X
                    }
                    else if (pixelColor == 255 && inMarker) // Белый после черного
                    {
                        if (lastX != -1 && x - lastX <= maxDistance)
                        {
                            maxX = x; // Обновляем границы
                            maxY = y;
                        }
                        else
                        {
                            inMarker = false; // Заканчиваем текущий маркер
                        }
                    }
                }
            }

            // Проверка по вертикали
            for (int x = startX; x < endX; x++)
            {
                int lastY = -1; // Последний найденный Y
                for (int y = startY; y < endY; y++)
                {
                    int pixelColor = binaryImage.GetPixel(x, y).R;

                    if (pixelColor == 0) // Черный
                    {
                        if (!inMarker)
                        {
                            inMarker = true; // Начинаем новый маркер
                            minX = x; // Устанавливаем начальные границы
                            minY = y;
                        }
                        lastY = y; // Обновляем последний Y
                    }
                    else if (pixelColor == 255 && inMarker) // Белый после черного
                    {
                        if (lastY != -1 && y - lastY <= maxDistance)
                        {
                            maxY = y; // Обновляем границы
                        }
                        else
                        {
                            inMarker = false; // Заканчиваем текущий маркер
                        }
                    }
                }
            }

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

            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];

                        // Используем порог для каждого канала
                        byte newColor = ((red < threshold) && (green < threshold) && (blue < threshold)) ? (byte)0 : (byte)255;

                        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 CalculateDynamicThreshold(Bitmap image, int startX, int startY, int endX, int endY)
        {
            double averageBrightness = CalculateAverageBrightnessInRegion(image, startX, startY, endX, endY);
            double standardDeviation = CalculateStandardDeviationInRegion(image, startX, startY, endX, endY, averageBrightness);
            return (int)(averageBrightness - 2 * standardDeviation);
        }

        private double CalculateAverageBrightnessInRegion(Bitmap image, int startX, int startY, int endX, int endY)
        {
            int sumBrightness = 0;
            int count = 0;

            for (int y = startY; y < endY; y++)
            {
                for (int x = startX; x < endX; 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 CalculateStandardDeviationInRegion(Bitmap image, int startX, int startY, int endX, int endY, double averageBrightness)
        {
            double sumSquaredDifference = 0;
            int count = 0;

            for (int y = startY; y < endY; y++)
            {
                for (int x = startX; x < endX; 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)
        {
            currentThreshold = BlackThresholdTrackBar.Value;
        }

        private bool IsSurroundedByWhite(Bitmap binaryImage, Rectangle marker)
        {
            bool isInFirstQuadrant = marker.Left < binaryImage.Width / 3 && marker.Top < binaryImage.Height / 3;
            bool isInNinthQuadrant = marker.Left >= 2 * (binaryImage.Width / 3) && marker.Top >= 2 * (binaryImage.Height / 3);

            if (isInFirstQuadrant)
            {
                // Проверка для первого квадранта
                for (int x = marker.Left; x <= marker.Right; x++)
                {
                    if (x < 0 || x >= binaryImage.Width) continue;
                    if (binaryImage.GetPixel(x, marker.Bottom + 1).R == 0) return false; // Проверка снизу
                }

                for (int y = marker.Top; y <= marker.Bottom; y++)
                {
                    if (marker.Right + 1 >= binaryImage.Width) return false;
                    if (binaryImage.GetPixel(marker.Right + 1, y).R == 0) return false; // Проверка справа
                }
            }
            else if (isInNinthQuadrant)
            {
                // Проверка для девятого квадранта
                if (marker.Top > 0)
                {
                    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 (marker.Bottom + 1 < binaryImage.Height)
                {
                    for (int x = marker.Left - 1; x <= marker.Right + 1; x++)
                    {
                        if (x < 0 || x >= binaryImage.Width) continue;
                        if (binaryImage.GetPixel(x, marker.Bottom + 1).R == 0) return false; // Проверка снизу
                    }
                }

                if (marker.Left > 0)
                {
                    for (int y = marker.Top; y <= marker.Bottom; y++)
                    {
                        if (marker.Left - 1 < 0) return false;
                        if (binaryImage.GetPixel(marker.Left - 1, y).R == 0) return false; // Проверка слева
                    }
                }

                if (marker.Right + 1 < binaryImage.Width)
                {
                    for (int y = marker.Top; y <= marker.Bottom; y++)
                    {
                        if (marker.Right + 1 >= binaryImage.Width) return false;
                        if (binaryImage.GetPixel(marker.Right + 1, y).R == 0) return false; // Проверка справа
                    }
                }
            }


            return true;
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {

        }
    }
}
 

Attachments

  • Снимок экрана (182).png
    Снимок экрана (182).png
    276.5 KB · Views: 2
Why is realtime processing needed? That looks like a static target typically used for air rifle or smallbore rifle -- neither of which is a dynamic environment to shoot in.
 
Anyway, in your shoes I would likely research how QR code scanning works with a focus (pun intended) on how it first finds the 3 reference squares in the corners of the QR code. How does it even determine that they are the reference squares?
 
Back
Top Bottom