ParticleDetectionTest.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using OpenCvSharp;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.IO;
  6. using System.Windows.Media;
  7. using CvPoint = OpenCvSharp.Point;
  8. using CvSize = OpenCvSharp.Size;
  9. namespace OpenCvSharpTest
  10. {
  11. public static class ParticleDetectionTest
  12. {
  13. public static void ParticleDetectionTest1(Bitmap Bitmapimage)
  14. {
  15. //读取图片
  16. //Bitmap Bitmapimage = new Bitmap("D:\\work\\WindowsFormsTest\\OpenCvSharpTest\\20251108153639.jpg");
  17. //Mat image = Cv2.ImRead("D:\\work\\WindowsFormsTest\\OpenCvSharpTest\\20251108153840.jpg");
  18. Mat image = BitmapToMat(Bitmapimage);
  19. Mat gray = new Mat();
  20. //灰度化预处理
  21. Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
  22. Cv2.ImShow("gray", ReadCodeTest.ResizeMat(gray));
  23. //二值化
  24. Mat binary = new Mat();
  25. Cv2.Threshold(gray, binary, 90, 255, ThresholdTypes.BinaryInv);
  26. //Cv2.ImShow("binary", ReadCodeTest.ResizeMat(binary));
  27. //闭运算
  28. Mat kernelX = new Mat();
  29. kernelX = Cv2.GetStructuringElement(MorphShapes.Rect, new CvSize(15, 15));
  30. Mat Open = new Mat();
  31. Cv2.MorphologyEx(binary, Open, MorphTypes.Erode, kernelX);
  32. Cv2.ImShow("Opendimg", ReadCodeTest.ResizeMat(Open));
  33. // 查找轮廓
  34. CvPoint[][] contours;
  35. HierarchyIndex[] hierarchy;
  36. Cv2.FindContours(Open, out contours, out hierarchy,
  37. RetrievalModes.External, ContourApproximationModes.ApproxSimple);
  38. double circularityThreshold = 0.7;
  39. foreach (var blobInfo in contours)
  40. {
  41. // 1. 计算轮廓面积
  42. double area = Cv2.ContourArea(blobInfo);
  43. // 忽略过小的噪点
  44. if (area < 100) continue;
  45. // 2. 计算轮廓周长
  46. double perimeter = Cv2.ArcLength(blobInfo, true);
  47. // 避免除以零
  48. if (perimeter == 0) continue;
  49. // 3. 计算圆形度: 4 * PI * Area / (Perimeter * Perimeter)
  50. double circularity = (4 * Math.PI * area) / (perimeter * perimeter);
  51. // 4. 判断是否满足圆形度要求
  52. if (circularity > circularityThreshold)
  53. {
  54. // 绘制满足条件的轮廓
  55. Cv2.DrawContours(image, new[] { blobInfo }, -1, Scalar.Green, 10);
  56. // 可选:在圆心处绘制标记或文字显示圆形度
  57. // var moments = Cv2.Moments(contour);
  58. // int cx = (int)(moments.M10 / moments.M00);
  59. // int cy = (int)(moments.M01 / moments.M00);
  60. // Cv2.Circle(image, new CvPoint(cx, cy), 5, Scalar.Red, -1);
  61. }
  62. }
  63. Cv2.ImShow("Output Image", ReadCodeTest.ResizeMat(image));
  64. //Cv2.WaitKey(0);
  65. }
  66. /// <summary>
  67. /// 将Bitmap转换为Mat(输出为彩色图)
  68. /// 转换后的图像可以增加彩色框
  69. /// </summary>
  70. /// <param name="bitmap">源Bitmap</param>
  71. /// <returns>对应的Mat对象</returns>
  72. static Mat BitmapToMat(Bitmap bitmap)
  73. {
  74. using (var ms = new MemoryStream())
  75. {
  76. bitmap.Save(ms, ImageFormat.Bmp);
  77. ms.Position = 0;
  78. return Mat.FromStream(ms, ImreadModes.Color);
  79. }
  80. }
  81. }
  82. }