OpenCvSharp 实现圆形检测与数量计数,直径计算(c#)

开发环境:.NET Framework4.8

输出类型 winfrom窗体应用程序

在这里插入图片描述

在这篇博客文章中,我将介绍如何使用 OpenCvSharp 在图像中检测圆形。这是一个有趣且实用的计算机视觉任务,可以应用于许多实际场景,如硬币检测、细胞计数等。

项目结构
首先,让我们看看项目的结构。这个项目是一个 Windows 窗体应用程序,包含以下组件:
一个 OpenFileDialog 组件用于选择图像文件。
一个 PictureBox 组件用于显示图像。
五个 NumericUpDown 组件用于调整霍夫圆检测算法的参数。
一个 ListView 组件用于显示检测到的圆形的直径。

1:加载图像


```csharp
private void button2_Click(object sender, EventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        label1.Text = dialog.FileName.ToString();
        pictureBox1.Image = Image.FromFile(dialog.FileName);
    }
}

3.处理图像

当用户调整参数或点击检测按钮时,触发图像处理流程。该流程包括加载图像、应用高斯模糊、使用霍夫变换检测圆形,并显示结果。

private async void button1_Click(object sender, EventArgs e)
{
    await ProcessImage(label1.Text);
}

private async Task ProcessImage(string imagePath)
{
    await Task.Run(() =>
    {
        // 检查图像文件是否存在
        if (!System.IO.File.Exists(imagePath))
        {
            MessageBox.Show($"未找到图像文件: {imagePath}");
            return;
        }

        // 加载图像
        Mat image = Cv2.ImRead(imagePath, ImreadModes.Grayscale);

        // 检查图像是否成功加载
        if (image.Empty())
        {
            MessageBox.Show($"加载图像失败: {imagePath}");
            return;
        }

        // 应用高斯模糊以减少噪声
        Mat blurred = new Mat();
        Cv2.GaussianBlur(image, blurred, new OpenCvSharp.Size(9, 9), 2, 2);

        // 使用霍夫圆检测找到圆
        HoughModes houghMode = HoughModes.Gradient;
        double minDist = 0.0;
        double param1 = 0.0;
        double param2 = 0.0;
        int minRadius = 0;
        int maxRadius = 0;

        numericUpDown1.Invoke((Action)(() =>
        {
            minDist = double.Parse(numericUpDown1.Value.ToString());
        }));
        numericUpDown2.Invoke((Action)(() =>
        {
            param1 = double.Parse(numericUpDown2.Value.ToString());
        }));
        numericUpDown3.Invoke((Action)(() =>
        {
            param2 = double.Parse(numericUpDown3.Value.ToString());
        }));
        numericUpDown4.Invoke((Action)(() =>
        {
            minRadius = int.Parse(numericUpDown4.Value.ToString());
        }));
        numericUpDown5.Invoke((Action)(() =>
        {
            maxRadius = int.Parse(numericUpDown5.Value.ToString());
        }));

        CircleSegment[] circles = Cv2.HoughCircles(blurred, houghMode, 1, minDist, param1: param1, param2: param2, minRadius: minRadius, maxRadius: maxRadius);

        // 创建用于显示结果的图像
        Mat resultImage = new Mat();
        Cv2.CvtColor(image, resultImage, ColorConversionCodes.GRAY2BGR);

        // 设置文本绘制的字体和参数
        HersheyFonts font = HersheyFonts.HersheySimplex;
        double fontScale = 0.5;
        int thickness = 1;

        double coinDiameterCm = 25; // 假设一元硬币直径为25毫米
        listView1.Invoke((Action)(() =>
        {
            listView1.Items.Clear();
            listView1.Columns.Clear();
            listView1.Columns.Add("直径", 100);
        }));

        foreach (var circle in circles)
        {
            Point center = new Point((int)circle.Center.X, (int)circle.Center.Y);
            int radius = (int)circle.Radius;

            double diameterCm = (radius * 2) * (coinDiameterCm / 1000); // 假设像素到毫米的比例为1:100

            Cv2.Circle(resultImage, center, radius, new Scalar(0, 0, 255), 5);
            string diameterText = $" {diameterCm:0.0} mm";
            listView1.Invoke((Action)(() =>
            {
                listView1.Items.Add(new ListViewItem(new string[] { diameterText }));
            }));
        }

        // 显示检测到的圆的总数量
        string totalCirclesText = $"总圆形数量: {circles.Length}";
        label2.Invoke((Action)(() =>
        {
            label2.Text = totalCirclesText;
        }));

        // 将Mat转换为Bitmap,并在PictureBox中显示
        Bitmap bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultImage);
        pictureBox1.Invoke((Action)(() =>
        {
            pictureBox1.Image = bitmap;
        }));
    });
}

总结

通过本文的介绍,你应该可以了解到如何使用 OpenCvSharp 实现图像中的圆形检测。这个过程包括加载图像、预处理图像、应用霍夫变换检测圆形,以及在用户界面中显示结果。希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值