Codementor Events

How to detect faces using OpenCV and Python/C++?

Published Oct 02, 2018
How to detect faces using OpenCV and Python/C++?

OpenCV is a library of programming functions mainly aimed at real-time computer vision. This article aims at detecting faces from an image using OpenCV and Python/C++.

Pre-Requisites: Basic knowledge of coding in Python and C++, OpenCV, Python and C++ installed on the machine, a code editor.That's it...You are good to go now...

For detection of faces in our code we will be using Haar-cascade Detection in OpenCV. Object Detection using Haar feature-based cascade classifiers is an effective object detection method. 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. OpenCV already contains many pre-trained classifiers for face, eyes, smile etc. These XML files are stored at the location opencv/data/haarcascades/.

Lets start writing the code on Python first and then we will continue with C++.

Python:
Start with importing numpy module and opencv module.

import numpy as np
import cv2 as cv

Now, we will use the following Haar Cascade Classifier for our face detection code.
haarcascade_frontalface_default.xml - Pre Trained model for face detection

Let us load these cascades in our code.

face_cascade = cv.CascadeClassifier('\\cv2\\data\\haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier('\\cv2\\data\\haarcascade_eye.xml')

Now, we need to load the image in which we want to run our face detection algorithm. For this article we will be using the traditional OpenCV 'lenna' image as following.

lenna.jpg

Load this image in our code and convert it into grayscale.
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

Our image is now ready for the face cacade to be applied on. We use detectMultiScale function for detecting faces in the image along with our face detection cascade that we have loaded earlier in our code.

faces = face_cascade.detectMultiScale(gray, 1.3, 5)

Here 1.3 is the scale factor and 5 is minNeighbours.
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.

Now face detection is done and all the faces found in the image are stored in the array faces. Now, lets draw rectangles around the detected faces in our image.

for (x,y,w,h) in faces:
cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]

We are almost done with our face detection code and we just need to show our new image with detected faces. For that we have the following snippet of code.

cv.imshow('Face_Detect',img)
cv.waitKey(0)
cv.destroyAllWindows()

This is the resultant image that we get as per our input image.
result_lenna.PNG

That's it. We have successfully detected faces in an image using OpenCV and Python. Now try detecting different objects using different Haar Casacades in the OpenCV library. Well, you can even make a Haar cascase of your own! Provided you have a lot of pictures of your target object. This is beyond the scope of this article though.

C++:
Let's include all the required headers for our code:

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

objdetect.hpp -
Object detection module in OpenCV.

highgui.hpp -
It provides easy interface to:

Create and manipulate windows that can display images
Add trackbars to the windows
Read and write images to/from disk or memory.
Read video from camera or file and write video to a file.

imgproc.hpp -
It provides a lot of functions for processing images such as image filtering and geometric transformations.

Now, we write a function that takes in an input image and cascade classifier as argument and gives a output image after applying face detection algorithm.

void detectAndDraw( Mat& img, CascadeClassifier& cascade, double scale)

This is our function definition and we continue with writing the function body. First we initialize a vector for storing all the faces that our algorithm will detect and convert our imput image into grayscale.

vector<Rect> faces;
Mat gray;
cvtColor( img, gray, COLOR_BGR2GRAY );

We will now apply detectMultiScale function on our grayscale image.

cascade.detectMultiScale( gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

This function is similar to what we used in python. Face detection is now done and we need to draw rectangles around the detected faces.

for ( size_t i = 0; i < faces.size(); i++ )
{
Rect r = faces[i];
Scalar color = Scalar(255, 0, 0);
rectangle( img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)), cvPoint(cvRound((r.x +
r.width-1)*scale), cvRound((r.y + r.height-1)*scale)), color, 3, 8, 0);
}

Now we just need to show our result as follows.

imshow( "Face Detection", img );

That's it now we can simply call our detection function and get faces detected in a go.

int main()
{
// Load the cascade classifier
cascade.load( "../../haarcascade_frontalcatface.xml" ) ;
double scale=1;
frame = imread('lenna.jpg', CV_LOAD_IMAGE_COLOR);
detectAndDraw( frame, cascade, scale );
return 0;
}

imread() is used to load the input image. In this case it is the same 'lenna' image that we used in python code.

Result for our C++ code is:
result_lenna.PNG

That's it we have successfully detected faces in an image using OpenCV and C++.

Discover and read more posts from Shashwat Jain
get started