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);
}
}
}
}