Computer vision is a field of study which encompasses how computers see and understand digital images and videos. We are sounded by applications and services which use computer vision. For example, automatic tagging of you and your friends in uploaded images on Facebook to Google search results for cats images or videos, all such application uses computer vision. Modern-day Smartphones and Laptops come with in-built face detection software, which can authenticate the identity of the user.
In this article, we will try to understand how we can use OpenCV libraries to detect human faces using the C++ program.
What is Haar Cascade Classifier?
Haar Cascade classifier is an effective object detection approach that was proposed by Paul Viola and Michael Jones in their paper, “Rapid Object Detection using a Boosted Cascade of Simple Features” in 2001. Haar Cascade Classifiers is basically a machine learning-based approach where a cascade function is trained from lots of images both positive and negative. Based on the training of object detection, an XML file is created which then could be used to detect objects as per our application.
We will not dwell inside how we can train the machine learning algorithm to detect certain objects but for our ease of understanding we can simply consider for each use case of object detection there would be an XML file containing required trained model data.
Face detection using Haar Cascade Classifier
Let's try to understand more about object detection using some simple examples. If you are new to OpenCV then it's highly recommended to go through my earlier article on getting started with Open CV using this link.
In this example, we will use class CascadeClassifier which is a Cascade classifier class for object detection. Let's quickly go through a few key methods of CascadeClassifier to understand how we are going to use them in our example program.
The parameterized constructor of CascadeClassifier's class is used to load the classifier XML file.
CascadeClassifier::CascadeClassifier(const string& filename);
// filename -> Cascade i.e. XML file
Note, if the default constructor is used then the user needs to use bool CascadeClassifier::load (const String &filename) to load the cascade file.
CascadeClassifier::empty() method allows users to inspect whether the classifier has been loaded or not.
bool CascadeClassifier::empty() const;
CascadeClassifier::detectMultiScale() method detects object in the input image which can be of different sizes. The detected objects are then returned as a list of rectangles, which is passed by reference as a second input parameter to the method i.e. vector<Rect>.
void CascadeClassifier::detectMultiScale(const Mat& image,
vector<Rect>& objects,
double scaleFactor=1.1,
int minNeighbors=3,
int flags=0,
Size minSize=Size(),
Size maxSize=Size());
image – Matrix of the type CV_8U containing an image where objects are detected.
objects – Vector of rectangles where each rectangle contains the detected object.
scaleFactor – Parameter specifying how much the image size is reduced at each image scale.
minNeighbors – Parameter specifying how many neighbors each candidate rectangle should have to retain it.
flags – Parameter with the same meaning for an old cascade as in the function vHaarDetectObjects. It is not used for a new cascade.
minSize – Minimum possible object size. Objects smaller than that are ignored.
maxSize – Maximum possible object size. Objects larger than that are ignored.
Face Detection Example
Now we've some basic understanding of different methods of CascadeClassifier, let's try to understand more by going through below sample example. In this example, we will use Image 1 as input to detect faces and draw a purple rectangle around detected faces.
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp> // for cascade classifier
#include <iostream>
#include <vector>
#include <string>
using namespace cv;
using namespace std;
// Function to draw bounding box abournd detected frontal face
// Input: image
// Output: void
void detect_faces(Mat& img)
{
CascadeClassifier face_cascade;
face_cascade.load("Resources/haarcascade_frontalface_default.xml");
// refer OpenCV installation folder for additioal cascade classifiers
if(face_cascade.empty())
cout << "Classifier has not been loaded!\n";
// creating rect for printing bounding box around detected faces
vector<Rect> faces;
// Detects objects of different sizes in the input image.
// The detected objects are returned as a list of rectangles.
face_cascade.detectMultiScale(img, faces, 1.1,10);
// drawing bounding box around detected faces
for(auto& face : faces)
rectangle(img, face.tl(), face.br(), Scalar(255, 0, 255), 3);
}
int main()
{
string path = "Resources/modi_obama.jpg";
Mat img = imread(path);
detect_faces(img);
imshow("Face Detection", img);
waitKey(0);
return 0;
}
Once we execute the above program, the below image window will appear with a purple rectangle around the detected faces.
We can easily extend the above program to take live input from the webcam and continuously draw purple rectangles on detected images.
int main()
{
VideoCapture v_cap(0); // 0: default webcam
Mat img;
while (true) // while one generate exception
{ //once v_cap frame read is over
v_cap.read(img); // load each frame into img
detect_faces(img);
imshow("Detected Faces", img); // display img
waitKey(10); // delay of 10 ms
}
return 0;
}
For more details on CascadeClassifier please refer to the documentation.
Conclusion
Haar Cascade Detection is one of the oldest face detection algorithms and it continues to be used in many areas. Deep learning is becoming famous as computational power has increased a lot in the past few decades but Haar Cascade Detection use is continuously increasing. Haar Features were not only used to detect faces, but also for eyes, lips, license number plates, etc. The models are stored on GitHub, and we can access them with OpenCV methods as discussed above.
Comments