Image Face Detection with C# NET application demo and tutorial.
Project Files: Download
In the battle against the pandemic, a lot of programmers turned their attention into developing software for detecting face masks. As a result, in this two part tutorial we will build an application that will be capable of detecting if the person on the image wears a face mask.
In the first part, I will explain how to implement face detection functionality. Later I will train a convolutional neural network to classify the extracted face image as a person who wears a face mask or not.
Face Detection is a technology that is used in a variety of applications. The sole purpose is to identify a human face in a digital image. The task is to find the locations and sizes of all objects in an image that belong to a given class. As a result, the algorithm will draw a bounding box around the desired object.
The Face Detection algorithm focus on the detection of frontal human faces. It is ML based approach where a cascade function is trained from a lot of positive and negative images. It is then used to detect objects in other images (in our case that would be faces).
Image Face Detection with C# NET
This is the application I created to accompany this blog post. It will allow the user to select an image. In addition, the user will be able to set the face detection algorithm parameters. And as a result, the application will draw a bounding boxes around the detected faces.
In the second part of this tutorial we will build a Convolutional Neural Network to detect if the person in the bounding box wears a mask.
Face Detection .NET Project
Before moving on let’s look at the dependency list we are going to need
The Accord.NET Framework is a .NET machine learning framework combined with audio and image processing libraries completely written in C#.
Face Detection Implementation
There are two classes from the Accord.NET library we are going to be using. The first one being HaarObjectDetector Class. This class is the implementation on the Viola-Jones Object Detector based on Haar-like features.
As a result, this class allows you to use different cascades for detecting different types of objects in an image.
For example, you can use this class to detect faces, eyes, nose, pedestrians etc.
The Accord NET library has a FaceHaarCascade Class that is specifically trained to detect faces in an image.
The code combining both of these classes looks something like this:
var faceDetector = new HaarObjectDetector(new FaceHaarCascade());
The HaarObjectDetector class has the implementation on the Viola-Jones object detection framework. Although it can be trained to detect a variety of object classes, it was motivated primarily by the problem of face detection.
It is a machine learning based approach where a cascade function is trained from a lot of positive and negative images. It is then used to detect objects in other images.
But, because we are using the FaceHaarCascade instance, in our case the HaarObjectDetector will be looking for faces.
Face Detection Parameters
Before we move on to detect faces, we need to setup some parameters
- MaxSize – Maximum window size to consider when searching objects.
- MinSize – Minimum window size to consider when searching objects.
- ScalingFactor – Gets or sets the scaling factor to rescale the window during search.
- ScalingMode – Gets or sets the desired scaling method.
- SearchMode – Gets or sets the desired searching method.
- Steady – Gets how many frames the object has been detected in a steady position.
- Suppression – Gets or sets the minimum threshold used to suppress rectangles which have not been detected sufficient number of times. This property only has effect when SearchMode is set to Average
- UseParallelProcessing – Gets or sets a value indicating whether this HaarObjectDetector should scan the image using multiple threads.
In Computer Vision, features like pixel intensities (RGB values, etc) doesn’t reveal a valuable information on the image. As a result, we need to extract features from the input images rather then using their pixel intensities. Haar-like features for example.
The different types of Haar-like features let us extract useful information from an image such as edges, straight lines, and diagonal lines that we can use to identify an object. For example, a human face.
Since the process of extracting Haar-like features involves calculating the sum of dark/light rectangular regions, the introduction of these parameters is a must.
We have to set the minimum and maximum window size which the algorithm needs to search for face like features in the given image. Because, the algorithm passes the image multiple times we need a scaling factor. The scaling factor allows us to rescale the window in which we are searching for objects. As a result, these parameters can help us detect bigger or smaller desired objects inside the image.
Face Detection Function
After we have set the parameters all we need to do is call the ProcessFrame method with a Bitmap image as a parameter.
var faceRectangles = faceDetector.ProcessFrame(picture);
The faceRectangles is an Array of Rectangles. The Rectangle struct represents each face bounding box location and size on the image.
Image Face Detection with C# NET
Now let’s quickly examine the face detection code in the application:
As you can see there is one button that is used to open and select an image – btnOpenImage
btnDetect holds the logic for face detection.
First we make sure a valid image is selected using the ImageSelector class. Next we use the wrapper class FaceDetector that abstracts the Accord NET HaarObjectDetectorClass and provides a method called ExtractFaces with the image as parameter as well as the HaarObjectDetectorClass parameters.
The next step is optional, but I still used it to pre-process the image. In order to maximize the number of face detections I decided to Grayscale the image, as well as apply the Equalize Histogram procedure.
The Grayscale method will turn your image from 3 channel RGB to a single channel grayscale image.
The EqualizeHistogram method usually increases the global contrast of the image, especially when the usable data of the image is represented by close contrast values. Through this adjustment, pixels intensities can be better distributed on the histogram. This allows for areas of lower local contrast to gain a higher contrast without affecting the global contrast.
The idea behind this Image Pre-processing step is to better enhance features that may represent faces.
And the last step would be to clear up the PictureBox Control from any pre existing drawn rectangle bounding boxes, if the ExtractFaces method returns result.
Because the method ExtractFaces returns the bounding box around a detected face, we can now draw it on the PictureBox.
This is just Part 1 of the two part series of the Face Mask Detection Project. We just described how to detect and extract a face from a given image. Next we use that image to recognize if a person is wearing a face mask or now.