Title: OpenCV Face detection with Haar cascades - PyImageSearch

URL Source: https://pyimagesearch.com/2021/04/05/opencv-face-detection-with-haar-cascades/

Published Time: 2021-04-05T14:00:00+00:00

Markdown Content:
![Image 1: OpenCV Face detection with Haar cascades](https://embed-ssl.wistia.com/deliveries/3c980117b65d98ae1acc6b86b6edcfc2.webp?image_crop_resized=960x540)

In this tutorial, you will learn how to perform face detection with OpenCV and Haar cascades.

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20675%20450'%3E%3C/svg%3E)

This guide, along with the next two, were inspired by an email I received from PyImageSearch reader, Angelos:

> _Hi Adrian,_
> 
> _I’ve been an avid reader for PyImageSearch for the last three years, thanks for all the blog posts!_
> 
> _My company does a lot of face application work, including face detection, recognition, etc._
> 
> _We just started a new project using embedded hardware. I don’t have the luxury of using_ [_OpenCV’s deep learning face detector_](https://pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/) _which you covered before, it’s just too slow on my devices._
> 
> _What do you recommend I do?_

To start, I would recommend Angelos look into coprocessors such as the Movidius NCS and Google Coral USB Accelerator. Those devices can run computationally expensive deep learning-based face detectors (including OpenCV’s deep learning face detector) in real-time.

That said, I’m not sure if these coprocessors are even an option for Angelos. They may be cost-prohibitive, require too much power draw, etc.

I thought about Angelos’ question for a bit and then went back through the archives to see if I had a tutorial that could help him out.

**To my surprise, I realized I had _never_ authored a dedicated tutorial on face detection with OpenCV’s Haar cascades!**

While we can obtain _significantly_ higher accuracy and more robust face detections with deep learning face detectors, OpenCV’s Haar cascades still have their place:

*   They are lightweight
*   They are _super fast_, even on resource-constrained devices
*   The Haar cascade model size is tiny (930 KB)

Yes, there are several problems with Haar cascades, namely that they are prone to false-positive detections and less accurate than their HOG + Linear SVM, SSD, YOLO, etc., counterparts. **However, they are still useful and practical, _especially_ on resource-constrained devices.**

Today you’ll learn how to perform face detection with OpenCV. Next week we’ll cover other Haar cascades included in OpenCV, namely eye and mouth detectors. And in two weeks, you’ll learn how to use dlib’s HOG + Linear SVM face detector and deep learning face detector.

**To learn how to perform face detection with OpenCV and Haar cascades, _just keep reading._**

![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

In the first part of this tutorial, we’ll configure our development environment and then review our project directory structure.

We’ll then implement two Python scripts:

1.  The first one will apply Haar cascades to detect faces in static images
2.  And the second script will utilize OpenCV’s Haar cascades to detect faces in real-time video streams

We’ll wrap up the tutorial with a discussion of our results, including the limitations of Haar cascades.

### **Configuring your development environment**

To follow this guide, you need to have the OpenCV library installed on your system.

Luckily, OpenCV is pip-installable:

$ pip install opencv-contrib-python

**If you need help configuring your development environment for OpenCV, I _highly recommend_ that you read my** [**_pip install OpenCV_ guide**](https://pyimagesearch.com/2018/09/19/pip-install-opencv/) — it will have you up and running in a matter of minutes.

### **Having problems configuring your development environment?**

[![Image 4](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20334'%3E%3C/svg%3E)](https://pyimagesearch.com/pyimagesearch-university/)

**Figure 1:** Having trouble configuring your dev environment? Want access to pre-configured Jupyter Notebooks running on Google Colab? Be sure to join [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/) — you’ll be up and running with this tutorial in a matter of minutes.

All that said, are you:

*   Short on time?
*   Learning on your employer’s administratively locked system?
*   Wanting to skip the hassle of fighting with the command line, package managers, and virtual environments?
*   **Ready to run the code _right now_ on your Windows, macOS, or Linux systems?**

Then join [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/) today!

**Gain access to Jupyter Notebooks for this tutorial and other PyImageSearch guides that are _pre-configured_ to run on Google Colab’s ecosystem right in your web browser!** No installation required.

And best of all, these Jupyter Notebooks will run on Windows, macOS, and Linux!

### **Project structure**

Before we can learn how to apply face detection with OpenCV’s Haar cascades, let’s first review our project directory structure.

Start by accessing the **_“Downloads”_** section of this tutorial to retrieve the source code and example images:

$ tree . --dirsfirst
.
├── images
│   ├── adrian\_01.png
│   ├── adrian\_02.png
│   └── messi.png
├── haar\_face\_detector.py
├── haarcascade\_frontalface\_default.xml
└── video\_face\_detector.py

1 directory, 6 files

We have two Python scripts to review today:

1.  `haar_face_detector.py`: Applies Haar cascade face detection to input images.
2.  `video_face_detector.py`: Performs real-time face detection with Haar cascades.

The `haarcascade_frontalface_default.xml` file is our pre-trained face detector, provided by the developers and maintainers of the OpenCV library.

The `images` directory then contains example images where we’ll apply Haar cascades.

### **Implementing face detection with OpenCV and Haar Cascades**

Let’s get started implementing face detection with OpenCV and Haar cascades.

Open the `haar_face_detector.py` file in your project directory structure, and let’s get to work:

\# import the necessary packages
import argparse
import imutils
import cv2

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", type=str, required=True,
	help="path to input image")
ap.add\_argument("-c", "--cascade", type=str,
	default="haarcascade\_frontalface\_default.xml",
	help="path to haar cascade face detector")
args = vars(ap.parse\_args())

**Lines 2-4** import our required Python packages. We’ll need `argparse` for command line argument parsing, `imutils` for OpenCV convenience functions, and `cv2` for our OpenCV bindings.

**Lines 7-13** parse our required command line arguments, including:

1.  `--image`: The path to the input image where we want to apply Haar cascade face detection.
2.  `--cascade`: The path to the pre-trained Haar cascade detector residing on disk.

With our command line arguments parsed, we can load our Haar cascade from disk:

\# load the haar cascade face detector from
print("\[INFO\] loading face detector...")
detector = cv2.CascadeClassifier(args\["cascade"\])

# load the input image from disk, resize it, and convert it to
# grayscale
image = cv2.imread(args\["image"\])
image = imutils.resize(image, width=500)
gray = cv2.cvtColor(image, cv2.COLOR\_BGR2GRAY)

A call to `cv2.CascadeClassifier` on **Line 17** loads our face detector from disk.

We then load our input `image`, resize it, and convert it to grayscale (we apply Haar cascades to grayscale images).

The final step is detection and annotation:

\# detect faces in the input image using the haar cascade face
# detector
print("\[INFO\] performing face detection...")
rects = detector.detectMultiScale(gray, scaleFactor=1.05,
	minNeighbors=5, minSize=(30, 30),
	flags=cv2.CASCADE\_SCALE\_IMAGE)
print("\[INFO\] {} faces detected...".format(len(rects)))

# loop over the bounding boxes
for (x, y, w, h) in rects:
	# draw the face bounding box on the image
	cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)

**Lines 28-30** then detect the actual faces in our input `image`, returning a list of bounding boxes, or simply the starting and ending _(x, y)_\-coordinates where the faces are in each image.

Let’s take a look at what each of these arguments means:

1.  `scaleFactor`: **How much the image size is reduced at each image scale.** This value is used to create the [scale pyramid](https://pyimagesearch.com/2015/03/16/image-pyramids-with-python-and-opencv/). To detect faces at multiple scales in the image (some faces may be closer to the foreground, and thus be larger, other faces may be smaller and in the background, thus the usage of varying scales). A value of `1.05` indicates that we are reducing the size of the image by 5% at each level in the pyramid.
2.  `minNeighbors`: **How many neighbors each window should have for the area in the window to be considered a face.** The cascade classifier will detect multiple windows around a face. This parameter controls how many rectangles (neighbors) need to be detected for the window to be labeled a face.
3.  `minSize`: **A tuple of width and height (in pixels) indicating the window’s minimum size.** Bounding boxes smaller than this size are ignored. It is a good idea to start with `(30, 30)` and fine-tune from there.

Finally, given the list of bounding boxes, we loop over them individually and draw the bounding box around the face on **Lines 34-36.**

### **Haar cascade face detection results**

Let’s put our Haar cascade face detector to the test!

Start by accessing the **_“Downloads”_** section of this tutorial to retrieve the source code, example images, and pre-trained Haar cascade face detector.

From there, you can open a shell and execute the following command:

$ python haar\_face\_detector.py --image images/messi.png
\[INFO\] loading face detector...
\[INFO\] performing face detection...
\[INFO\] 2 faces detected...

![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20482%20500'%3E%3C/svg%3E)

**Figure 2:** Applying face detection with OpenCV Haar cascades.

As **Figure 2** shows, we’ve been able to detect both faces in the input image successfully.

Let’s try another image:

$ python haar\_face\_detector.py --image images/adrian\_01.png
\[INFO\] loading face detector...
\[INFO\] performing face detection...
\[INFO\] 1 faces detected...

![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20525%20694'%3E%3C/svg%3E)

**Figure 3:** Successfully using Haar cascades for face detection.

Sure enough, my face has been detected.

The following image poses a bit of a problem, though, and demonstrates one of the largest limitations of Haar cascades, namely, _false-positive detections:_

$ python haar\_face\_detector.py --image images/adrian\_02.png
\[INFO\] loading face detector...
\[INFO\] performing face detection...
\[INFO\] 2 faces detected...

![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20525%20695'%3E%3C/svg%3E)

**Figure 4:** OpenCV’s Haar cascades are prone to false-positive detections.

While you can see that my face was correctly detected, we also have a false-positive detection toward the bottom of the image.

Haar cascades tend to be _very sensitive_ to your choice in `detectMultiScale` parameters. The `scaleFactor` and `minNeighbors` being the ones you have to tune most often.

When you end up with false-positive detections (or no face is detected at all), you should go back to your `detectMultiScale` function and attempt to tune the parameters by trial and error.

For example, our _original_ call to `detectMultiScale` looks like this:

rects = detector.detectMultiScale(gray, scaleFactor=1.05,
	minNeighbors=5, minSize=(30, 30),
	flags=cv2.CASCADE\_SCALE\_IMAGE)

Through experimentation, I found that I could still _detect my face_ while _removing the false-positive_ by updating the `minNeighbors` from `5` to `7`:

rects = detector.detectMultiScale(gray, scaleFactor=1.05,
	minNeighbors=7, minSize=(30, 30),
	flags=cv2.CASCADE\_SCALE\_IMAGE)

After doing that, we obtain the correct results:

$ python haar\_face\_detector.py --image images/adrian\_02.png
\[INFO\] loading face detector...
\[INFO\] performing face detection...
\[INFO\] 1 faces detected...

![Image 8](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20525%20695'%3E%3C/svg%3E)

**Figure 5:** Adjusting the parameters to OpenCV’s Haar cascade detection function can improve results.

This update worked because the `minNeighbors` parameter is designed to help control false-positive detections.

When applying face detection, Haar cascades are [sliding a window](https://pyimagesearch.com/2015/03/23/sliding-windows-for-object-detection-with-python-and-opencv/) from left-to-right and top-to-bottom across the image, computing [integral images](https://en.wikipedia.org/wiki/Summed-area_table) along the way.

When a Haar cascade thinks a face is in a region, it will return a higher confidence score. If there are enough high confidence scores in a given area, then the Haar cascade will report a positive detection.

By increasing `minNeighbors` we can require that Haar cascades find more neighbors, thus removing the false-positive detection we saw in **Figure 4.**

Again, the above example highlights the primary limitation of Haar cascades. While they are fast, you pay the price via:

1.  False-positive detections
2.  Less accuracy (as opposed to HOG + Linear SVM and deep learning-based face detectors)
3.  Manual parameter tuning

That said, in resource-constrained environments, you just cannot beat the speed of Haar cascade face detection.

### **Implementing real-time face detection with Haar cascades**

Our previous example demonstrated how to apply face detection with Haar cascades to single images.

Let’s now learn how to perform face detection in real-time video streams:

\# import the necessary packages
from imutils.video import VideoStream
import argparse
import imutils
import time
import cv2

**Lines 2-6** import our required Python packages. The `VideoStream` class allows us to access our webcam.

We have only a single command line argument to parse:

\# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-c", "--cascade", type=str,
	default="haarcascade\_frontalface\_default.xml",
	help="path to haar cascade face detector")
args = vars(ap.parse\_args())

The `--cascade` argument points to our pre-trained Haar cascade face detector residing on disk.

We then load the face detector and initialize our video stream:

\# load the haar cascade face detector from
print("\[INFO\] loading face detector...")
detector = cv2.CascadeClassifier(args\["cascade"\])

# initialize the video stream and allow the camera sensor to warm up
print("\[INFO\] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)

Let’s start reading frames from the video stream:

\# loop over the frames from the video stream
while True:
	# grab the frame from the video stream, resize it, and convert it
	# to grayscale
	frame = vs.read()
	frame = imutils.resize(frame, width=500)
	gray = cv2.cvtColor(frame, cv2.COLOR\_BGR2GRAY)

	# perform face detection
	rects = detector.detectMultiScale(gray, scaleFactor=1.05,
		minNeighbors=5, minSize=(30, 30),
		flags=cv2.CASCADE\_SCALE\_IMAGE)

Inside our `while` loop, we:

1.  Read the next `frame` from the camera
2.  Resize it to have a width of 500 pixels (smaller frames are faster to process)
3.  Convert the frame to grayscale

**Lines 33-35** then perform face detection using our Haar cascade.

The final step is to draw the bounding boxes of the detected faces on our `frame`:

	# loop over the bounding boxes
	for (x, y, w, h) in rects:
		# draw the face bounding box on the image
		cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

	# show the output frame
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF

	# if the \`q\` key was pressed, break from the loop
	if key == ord("q"):
		break

# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()

**Line 38** loops over the `rects` list, containing the:

1.  Starting `x` coordinate of the face
2.  Starting `y` coordinate of the face
3.  Width (`w`) of the bounding box
4.  Height (`h`) of the bounding box

We then display the output `frame` on our screen.

### **Real-time Haar cascade face detection results**

We are now ready to apply face detection in real-time with OpenCV!

Be sure to access the **_“Downloads”_** section of this tutorial to retrieve the source code and pre-trained Haar cascade.

From there, open a shell and execute the following command:

$ python video\_face\_detector.py
\[INFO\] loading face detector...
\[INFO\] starting video stream...

As you can see, our Haar cascade face detector is running in real-time without an issue!

If you need to obtain real-time face detection, _especially_ on embedded devices, then consider utilizing Haar cascade face detectors.

Yes, they are not as accurate as more modern face detectors, and yes, they are prone to false-positive detections as well, but the benefit is that you’ll gain tremendous speed, and you’ll require less computational power.

Otherwise, if you’re on a laptop/desktop, or you can use a coprocessor such as the Movidius NCS or Google Coral USB Accelerator, then use [deep learning-based face detection](https://pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/). You’ll obtain far higher accuracy and still be able to apply face detection in real-time.

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

![Image 9: Video Thumbnail](https://embed-ssl.wistia.com/deliveries/4bda0a1602c8b4d96d63a02617f3069e.webp?image_crop_resized=640x360)

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

**Summary**
-----------

In this tutorial, you learned how to perform face detection with OpenCV and Haar cascades.

While Haar cascades are _significantly_ less accurate than their HOG + Linear SVM, SSD, YOLO, etc., counterparts, they are _very fast and lightweight_. This makes them suitable for use on embedded devices, particularly in situations where coprocessors like the Movidius NCS and Google Coral USB Accelerator are unavailable.

Next week we’ll discuss other OpenCV Haar cascades, including eye and mouth detectors.

**To download the source code to this post (and be notified when future tutorials are published here on PyImageSearch), _simply enter your email address in the form below!_**

![Image 10](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!