Question Search marker

Stepan

Member
Joined
Nov 1, 2024
Messages
5
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
 
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.
 

Latest posts

Back
Top Bottom