Face Detection in Python
Tags: python, facedetection, opencv
Published: 2019-07-17 22:23:20

 Hi in this post i'll show you how to use OpenCV library to detect faces inside a picture, in a future post i'll show you how to detect in a Real-Time video that was amazing stuff to practice the visual recognition. 

> well let's start 

## Requirements 

check your version of python or install python 3.6.

``` bash
python--version
```

then we need to install OpenCV library by searching in the [official webpage](https://opencv.org/), in my local environment i use the OpenCV v4.1 you can use instead a previous version v3.X, i recommend you to follow the official
instructions to install in the documentation. 

## Code the Face Detection solution 

Now we start coding the face detection program. First need to import the OpenCV library and the system library(could be optional, i use this library to get a parameter when i run the python code).

```python
import cv2
import sys
``` 

Next to import statements, we need to get the parameter passed from the user, this parameter was the picture to test in the face detection program.

```python
# Get user supplied values
imagePath = sys.argv[1]
```

In the next part we need to add in our code the magic for face detection this part is called Haar Cascade feature; you maybe ask why is a haar cascade, well now i'll explain you what it is. 

> Object Detection using Haar feature-based cascade classifiers is an effective object detection method proposed by Paul Viola and Michael Jones in their paper, "Rapid Object Detection using a Boosted Cascade of Simple Features" in 2001. 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. Here we will work with face detection. Initially, the algorithm needs a lot of positive images (images of faces) and negative images (images without faces) to train the classifier. Then we need to extract features from it. For this, haar features shown in below image are used. They are just like our convolutional kernel. Each feature is a single value obtained by subtracting sum of pixels under white rectangle from sum of pixels under black rectangle. Now we have an idea was the HaarCascade can continue with the code, i'm using the Haar cascade file created by Rainer Lienhart ( the file you found in the repository of the code), we need to add the file to the code.
- by OpenCV docuentation

```python
cascPath = "haarcascade_frontalface_default.xml"
```

Next, we need to train the OpenCV classifier with the haar cascade file.

```python
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
```

In the next step we need to read the image and set to gray color because OpenCV do better job with gray scale pictures with haar cascade classifier.

```python
# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
```

In this part the magic is done, the OpenCV framework do the magic detecting the faces inside an image and return the position of the face in the image, you can adjust the parameters to get more detailed results or more crazy haha!!!.

```python
# Detect faces in the image
faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor = 1.05,
    minNeighbors = 5,
    minSize = (30, 30),
    flags = cv2.CASCADE_SCALE_IMAGE
)
```

To finish our code for face detection just print the number of faces found in the image and then draw a rectangle with the face inside them, and show a windows with the images and the faces rounded; for close the window press any key.

```python
print("Found {0} faces!".format(len(faces)))

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

height, width, channels = image.shape
cv2.imshow("{0} Faces found".format(len(faces)), image)
cv2.waitKey(0)
```

This is an example of the result more accurate.

![Lot people good quiality](https://1.bp.blogspot.com/-E7gxWsBDFt0/XS9IqyqpG-I/AAAAAAAAWzo/or6VTnoARuolE0FyWqPQ1U05YnO-UVyugCPcBGAYYCw/s320/Captura.PNG)    

Like you see in the image they recognize a hand like a face, that was some of the issues i found, i try to set more accurate values but it detect less faces you can play with it to see how it works. 

And this is another example, like you see detect many faces in a low resolution picture but have a lot of errors, in this image and this configurations only 1 face is not detected.

![Lot of people low quiality](https://1.bp.blogspot.com/-w0X2CmxtJjk/XS9R_wGjTmI/AAAAAAAAWz0/_9KPKNVQ1Vo3L7cDWJZNgTN_5FUYM3CFwCLcBGAs/s640/Captura1.PNG)    

## Complete code 

Here is the complete code, like you see only takes 33 lines with white spaces, it is a really short program with powerfull applications.

```python
import cv2
import sys

# Get user supplied values
imagePath = sys.argv[1]
cascPath = "haarcascade_frontalface_default.xml"

# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)

# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Detect faces in the image
faces = faceCascade.detectMultiScale(
    gray,
    scaleFactor = 1.05,
    minNeighbors = 5,
    minSize = (30, 30),
    flags = cv2.CASCADE_SCALE_IMAGE
)

print("Found {0} faces!".format(len(faces)))

# Draw a rectangle around the faces
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

height, width, channels = image.shape
cv2.imshow("{0} Faces found".format(len(faces)), image)
cv2.waitKey(0)
```

## Conclusion 

For finish this post, like you see, if you use the actual solution the face detection you can develop a more detailed program like a doorbell or something like a cam in the traffic light to detect a face and maybe do a better
recognition of the person face. 

Next to this you maybe try to do the same program but in a real video or wait for my next post to learn how to do it.