In this article, we will describe an OpenCV application that will detect coins in an image. Coin detection is a common stage prior to full coin recognition. It consists of detecting and extracting coins from a given image.
The code that accompanies this series will be implemented in C# using Keras.NET, and in the last article of the series we will briefly use ML.NET. Out of all the options, why use Keras.NET? Keras.NET is very easy to learn, since it is basically a direct mapping from the classic TensorFlow written in Python into C#. It makes the example much easier for readers unfamiliar with machine learning to follow than if it were created in one of the other alternatives.
The coin detection process is divided into three stages:
- Transform the image to grayscale. Colors add complexity to the detection task, and in many cases they do not convey any relevant information that cannot be obtained from the luminance of the image.
- Apply Gaussian Blur. Since coins often include an inner circle, we apply this transformation to blur the image. This ensures that any inner circles are ignored by the next step so our algorithm won’t accidentally think they are a separate coin.
- Apply Hough transformation. This is to detect circular forms. More on the Hough transform can be found here.
To get started, let’s create a .NET Framework 4.7.2 Console Application in Visual Studio Community 2019. We’ll name our solution and project "CoinRecognitionExample" and create a Detection folder in it with the class CoinDetector
.
We will be using OpenCVSharp, so we can go ahead and install the dependency from Nuget Package Manager in Visual Studio.To do this, go to Tools > Nuget Package Manager.
We can see the dependencies that we would need to have installed regarding OpenCVSharp.
The actual implementation takes place in the CoinDetector
class:
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);
}
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();
}
}
}
In the constructor of the class, we receive the path to the image of coins. This and the ImagePreprocessing
method are the only two public entities of the CoinDetector
class. All other methods are private and relate to the three stages listed above.
In the ImageProcessing
method, we save an original Mat (matrix of pixels) object of the image and make a copy of it for the transformations that will take place. The Mat class and all calls to the Cv2 class come from OpenCVSharp. After each transformation, we make a call to new Window
to visually show the transformation.
The parameters of Cv2.HoughCircles
depend on the problem you are facing, that is, on the image that is being processed. The parameters shown in the code are the ones fitting our example.
To finalize the coin detection example, we can add the following lines in the main method of our console application project and execute.
string filePath = @"C:/Users/arnal/Documents/coins.jpg";
var coinDetector = new CoinDetector(filePath);
coinDetector.ImagePreprocessing();
This is the image we’ll use for testing. It contains Serbian Dinar coins among others:
The final result will be the image we saw earlier:
As we can see, coins have been detected within white circles in the central and final window corresponding to the Hough transformation.
This ends the first article of the series. In the next article, we will preprocess a dataset to be inputted to a machine learning model.