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