65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中的深度学习:使用 OpenCV 进行硬币检测

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (5投票s)

2020 年 11 月 2 日

CPOL

3分钟阅读

viewsIcon

21982

downloadIcon

1062

在本系列文章中,我们将使用深度神经网络 (DNN) 来执行硬币识别。具体来说,我们将训练一个 DNN 来识别图像中的硬币。

本系列文章随附的代码将使用 Keras.NET 在 C# 中实现,在本系列的最后一篇文章中,我们将简要使用 ML.NET。 在所有选项中,为什么使用 Keras.NET? Keras.NET 很容易学习,因为它基本上是从用 Python 编写的经典 TensorFlow 直接映射到 C#。与在其他备选方案中创建相比,它使不熟悉机器学习的读者更容易理解该示例。

硬币检测过程分为三个阶段

  1. 将图像转换为灰度。颜色增加了检测任务的复杂性,并且在许多情况下,它们没有传达任何无法从图像的亮度中获得的相关信息。
  2. 应用高斯模糊。由于硬币通常包含一个内圆,我们应用此转换来模糊图像。 这确保了下​​一步会忽略任何内圆,因此我们的算法不会意外地认为它们是单独的硬币。
  3. 应用霍夫变换。这是为了检测圆形。 关于霍夫变换的更多信息可以在 这里 找到。

首先,让我们在 Visual Studio Community 2019 中创建一个 .NET Framework 4.7.2 控制台应用程序。我们将把我们的解决方案和项目命名为 "CoinRecognitionExample",并在其中创建一个名为 Detection 的文件夹,其中包含 CoinDetector 类。

我们将使用 OpenCVSharp,因此我们可以从 Visual Studio 中的 Nuget 包管理器安装依赖项。为此,请转到工具 > Nuget 包管理器

我们可以看到我们需要安装的关于 OpenCVSharp 的依赖项。

实际的实现发生在 CoinDetector 类中

  public class CoinDetector
    {
        private Mat _image;
        private Mat _originalImage;
        private string _pathToFile;

        public CoinDetector(string pathToFile)
        {
            _pathToFile = pathToFile;
        }

        public void ImagePreprocessing()
        {
            _image = new Mat(_pathToFile, ImreadModes.Color);
            _originalImage = _image.Clone();
            TransformGrayScale();
            TransformGaussianBlur();
            HoughSegmentation();
        }

        private void TransformGrayScale()
        {
            _image = _originalImage.CvtColor(ColorConversionCodes.BGR2GRAY);
            new Window("Grayed Coins", WindowMode.Normal, _image);
            Cv2.WaitKey();
        }

        private void TransformGaussianBlur()
        {
            Cv2.GaussianBlur(_image, _image, new Size(0, 0), 1);
            new Window("Blurred Coins", WindowMode.Normal, _image);
            //Cv2.WaitKey();
        }

        private void HoughSegmentation()
        {
            Mat result = _image.Clone();

            var circleSegments = Cv2.HoughCircles(_image, HoughMethods.Gradient, 1.02, 40);
            for (int i = 0; i < circleSegments.Length; i++)
            {
                Cv2.Circle(result, (Point) circleSegments[i].Center, (int)circleSegments[i].Radius, new Scalar(255, 255, 0), 2);
            }

            using (new Window("Circles", result))
            {
                Cv2.WaitKey();
            }
        }
    }

在类的构造函数中,我们接收硬币图像的路径。这以及 ImagePreprocessing 方法是 CoinDetector 类的仅有的两个公共实体。所有其他方法都是私有的,并且与上面列出的三个阶段相关。

在 ImageProcessing 方法中,我们保存了图像的原始 Mat(像素矩阵)对象,并为其将要发生的转换制作了副本。 Mat 类和对 Cv2 类的所有调用都来自 OpenCVSharp。在每次转换之后,我们调用 new Window 以可视化显示转换。

Cv2.HoughCircles 的参数取决于您面临的问题,即正在处理的图像。代码中显示的参数是适合我们示例的参数。

要完成硬币检测示例,我们可以在控制台应用程序项目的主方法中添加以下几行并执行。

 string filePath = @"C:/Users/arnal/Documents/coins.jpg";
            var coinDetector = new CoinDetector(filePath);
            coinDetector.ImagePreprocessing();

这是我们将用于测试的图像。它包含塞尔维亚第纳尔硬币等

最终结果将是我们之前看到的图像

我们可以看到,硬币已在与霍夫变换相对应的中心和最终窗口中的白色圆圈内被检测到。

本系列的第一篇文章到此结束。在 下一篇文章 中,我们将预处理一个数据集以输入到机器学习模型中。

© . All rights reserved.