using OpenCvSharp; using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Windows.Media; using CvPoint = OpenCvSharp.Point; using CvSize = OpenCvSharp.Size; namespace OpenCvSharpTest { public static class ParticleDetectionTest { public static void ParticleDetectionTest1(Bitmap Bitmapimage) { //读取图片 //Bitmap Bitmapimage = new Bitmap("D:\\work\\WindowsFormsTest\\OpenCvSharpTest\\20251108153639.jpg"); //Mat image = Cv2.ImRead("D:\\work\\WindowsFormsTest\\OpenCvSharpTest\\20251108153840.jpg"); Mat image = BitmapToMat(Bitmapimage); Mat gray = new Mat(); //灰度化预处理 Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); Cv2.ImShow("gray", ReadCodeTest.ResizeMat(gray)); //二值化 Mat binary = new Mat(); Cv2.Threshold(gray, binary, 90, 255, ThresholdTypes.BinaryInv); //Cv2.ImShow("binary", ReadCodeTest.ResizeMat(binary)); //闭运算 Mat kernelX = new Mat(); kernelX = Cv2.GetStructuringElement(MorphShapes.Rect, new CvSize(15, 15)); Mat Open = new Mat(); Cv2.MorphologyEx(binary, Open, MorphTypes.Erode, kernelX); Cv2.ImShow("Opendimg", ReadCodeTest.ResizeMat(Open)); // 查找轮廓 CvPoint[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(Open, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); double circularityThreshold = 0.7; foreach (var blobInfo in contours) { // 1. 计算轮廓面积 double area = Cv2.ContourArea(blobInfo); // 忽略过小的噪点 if (area < 100) continue; // 2. 计算轮廓周长 double perimeter = Cv2.ArcLength(blobInfo, true); // 避免除以零 if (perimeter == 0) continue; // 3. 计算圆形度: 4 * PI * Area / (Perimeter * Perimeter) double circularity = (4 * Math.PI * area) / (perimeter * perimeter); // 4. 判断是否满足圆形度要求 if (circularity > circularityThreshold) { // 绘制满足条件的轮廓 Cv2.DrawContours(image, new[] { blobInfo }, -1, Scalar.Green, 10); // 可选:在圆心处绘制标记或文字显示圆形度 // var moments = Cv2.Moments(contour); // int cx = (int)(moments.M10 / moments.M00); // int cy = (int)(moments.M01 / moments.M00); // Cv2.Circle(image, new CvPoint(cx, cy), 5, Scalar.Red, -1); } } Cv2.ImShow("Output Image", ReadCodeTest.ResizeMat(image)); //Cv2.WaitKey(0); } /// /// 将Bitmap转换为Mat(输出为彩色图) /// 转换后的图像可以增加彩色框 /// /// 源Bitmap /// 对应的Mat对象 static Mat BitmapToMat(Bitmap bitmap) { using (var ms = new MemoryStream()) { bitmap.Save(ms, ImageFormat.Bmp); ms.Position = 0; return Mat.FromStream(ms, ImreadModes.Color); } } } }