Python · Computer Vision

Using the face_recognition Library in Python

Detect faces, recognize people, and build a real-time webcam recognition system with just a few lines of code, explained with working examples, real output, and the reasoning behind every step.

By Arj Updated July 2026 21 min read Python 3.6 to 3.11

1What is face_recognition

Face recognition has gone from science fiction to daily reality, it unlocks phones, powers surveillance systems, and quietly runs inside a growing number of smart apps. Python makes it surprisingly approachable to implement, largely thanks to the face_recognition library.

face_recognition is a Python library built directly on top of dlib and its deep learning face recognition model, wrapped in a much simpler, high-level API. With it you can:

  • Detect faces in images or video
  • Recognize and identify specific people
  • Extract facial features and compare faces numerically
  • Label known people automatically in a batch of photos

It is known for three things in particular: it is extremely accurate, since it is built on deep learning rather than older classical methods, it is very easy to use, and it is open-source and actively maintained.

How this relates to dlib
Everything face_recognition does under the hood is dlib: the same HOG or CNN-based detector, the same 68-point shape predictor, the same 128-dimensional embedding model. If you want to understand exactly what is happening beneath this library's simple function calls, or need lower-level control, the dlib in Python guide covers the same pipeline one layer down.

2Installation

First, make sure you are using a supported Python version, Python 3.6 through 3.11 at the time of writing. Because this library depends on dlib, which compiles C++ code, the install has a couple of extra steps compared to a typical pip package.

1. Install CMake

dlib's build process needs CMake available first:

terminal
pip install cmake

2. Install dlib and face_recognition

terminal
pip install dlib
pip install face_recognition

You can check the package details on its PyPI page before installing if you want to confirm the latest version.

Platform-specific notes
On Windows, you may need to install Visual Studio Build Tools before pip install dlib succeeds, since dlib compiles from source. On macOS, install CMake through Homebrew instead if the pip version gives you trouble: brew install cmake. The full detail on dlib's build requirements is covered in the dlib in Python guide, since this library inherits the exact same installation constraints.

3Preparing your images

Before writing any recognition code, it helps to organize your images into a predictable folder structure. A typical layout separates the people you already know from the photo you want to identify:

face_project/ ├── known/ │ ├── alice.jpg │ └── bob.jpg ├── unknown/ │ └── test.jpg
  • Place clear, front-facing images of each known person in known/, one photo per person, named after them.
  • Place the photo you want to identify in unknown/.
Image quality matters more than quantity
A single sharp, well-lit, front-facing photo per known person is usually enough to get strong results. Blurry, dark, or heavily angled reference photos hurt accuracy far more than having only one photo per person does.

4Basic face detection

The simplest possible use of the library is just finding how many faces exist in an image and where they are:

python
import face_recognition

image = face_recognition.load_image_file("unknown/test.jpg")
face_locations = face_recognition.face_locations(image)

print(f"Found {len(face_locations)} face(s) in the image.")
OutputFound 1 face(s) in the image.
face_recognition.load_image_file(path)

Loads an image directly as a NumPy array in RGB order, ready to feed into the rest of the library's functions. This matters because it is the opposite of OpenCV's default: if you ever mix the two libraries in one script, remember cv2.imread() gives you BGR while this gives you RGB, and passing the wrong order into either library silently produces wrong-looking results rather than an error. See the OpenCV in Python guide for the full BGR versus RGB explanation.

face_locations() returns a list of tuples, each in (top, right, bottom, left) order, one tuple per detected face.

5Comparing two faces

Detecting a face and identifying whose face it is are two different problems. To compare faces, you first convert each one into a numeric encoding, then check whether two encodings are close enough to count as a match.

python
known_image = face_recognition.load_image_file("known/alice.jpg")
unknown_image = face_recognition.load_image_file("unknown/test.jpg")

alice_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]

results = face_recognition.compare_faces([alice_encoding], unknown_encoding)

if results[0]:
    print("This is Alice!")
else:
    print("Not Alice.")
OutputThis is Alice!

face_encodings() returns a list, one 128-dimensional encoding per face found in the image, which is why the code indexes into it with [0] to grab the first (and in these examples, only) face. compare_faces() takes a list of known encodings to check against and a single new encoding, returning a list of booleans indicating which known encodings matched.

face_encodings() can return an empty list
If no face is detected in the image at all, face_encodings() returns an empty list, and indexing it with [0] raises an IndexError. Section 10 covers handling this safely, it is one of the most common errors beginners hit with this library.

6Identifying multiple people in a photo

A more realistic scenario is not comparing against one known person, but checking a photo against an entire folder of known faces at once, and labeling each detected face with whichever known person it matches.

python
import os

known_encodings = []
known_names = []

for filename in os.listdir("known"):
    image = face_recognition.load_image_file(f"known/{filename}")
    encoding = face_recognition.face_encodings(image)[0]
    known_encodings.append(encoding)
    known_names.append(os.path.splitext(filename)[0])

# Load unknown image
image = face_recognition.load_image_file("unknown/test.jpg")
face_locations = face_recognition.face_locations(image)
face_encodings = face_recognition.face_encodings(image, face_locations)

for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
    matches = face_recognition.compare_faces(known_encodings, face_encoding)

    name = "Unknown"
    if True in matches:
        first_match_index = matches.index(True)
        name = known_names[first_match_index]

    print(f"Detected: {name}")
OutputDetected: alice

The first loop builds a lookup of every known encoding and the name it belongs to, taken directly from each file's filename minus its extension. The second half then detects every face in the unknown image and checks each one against the entire known list at once, rather than comparing to just a single person as in the previous section.

What if more than one known face matches
matches.index(True) returns only the first match it finds, which is fine for small, curated datasets but can pick the wrong person if two known faces are similar enough to both cross the match threshold. For larger datasets, face_recognition.face_distance(), covered in section 9, lets you pick the closest match rather than just the first one.

7Real-time recognition with a webcam

Combining everything so far with OpenCV's video capture produces a live recognition system that labels a known face directly on the video feed.

python
import face_recognition
import cv2

# Load known face
known_image = face_recognition.load_image_file("known/alice.jpg")
known_encoding = face_recognition.face_encodings(known_image)[0]
known_names = ["Alice"]

video_capture = cv2.VideoCapture(0)

while True:
    ret, frame = video_capture.read()

    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)

    face_locations = face_recognition.face_locations(rgb_small_frame)
    face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        matches = face_recognition.compare_faces([known_encoding], face_encoding)

        name = "Unknown"
        if True in matches:
            name = known_names[0]

        # Scale back up
        top *= 4; right *= 4; bottom *= 4; left *= 4
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
        cv2.putText(frame, name, (left, top - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2)

    cv2.imshow('Video', frame)

    if cv2.waitKey(1) == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()
Why the frame is resized and scaled back up

Running face detection and encoding on a full-resolution webcam frame every single loop iteration is expensive. Shrinking the frame to a quarter size with fx=0.25, fy=0.25 before detection speeds this up enormously, since detection cost scales with pixel count.

The coordinates returned from that shrunk frame are also in the shrunk frame's scale, so multiplying top, right, bottom, and left each by 4 maps them back to the original full-size frame before drawing the rectangle, otherwise the box would appear a quarter of the correct size in the top-left corner of the actual face.

Do not forget cv2.VideoCapture's own release step
Just like any OpenCV video loop, forgetting video_capture.release() keeps the webcam locked after the script ends. See the working with camera feed guide for the full explanation of this pattern and other camera handling details.

8Tips for better accuracy

  • Use high-resolution images for face encoding. Low-resolution or heavily compressed reference photos give the encoding model less detail to work with.
  • Make sure faces are front-facing and well-lit. Extreme angles, heavy shadows, or backlighting reduce accuracy more than almost any other factor.
  • For faster performance, resize frames to a quarter scale for video, as shown in the webcam example above, this is the single biggest speed win available with almost no accuracy cost.

9Advanced features

FeatureMethod
Get face landmarksface_recognition.face_landmarks()
Find facial featuresReturns coordinates for eyes, nose, lips, and jaw
Compare multiple facescompare_faces() with a list of multiple known encodings
Get face distancesface_recognition.face_distance()

face_distance() deserves a closer look, since it solves the "which match is actually closest" problem mentioned back in section 6. Instead of a simple true or false, it returns the actual numeric distance between encodings, letting you pick the smallest one explicitly:

python
distances = face_recognition.face_distance(known_encodings, face_encoding)
best_match_index = distances.argmin()

if distances[best_match_index] < 0.6:
    name = known_names[best_match_index]

This is generally the more reliable approach once you have more than a couple of known people in your dataset.

10Troubleshooting

ProblemSolution
No faces foundUse clear, front-facing, well-lit images, extreme angles or poor lighting are the most common cause
IndexError on encodingCheck that face_encodings() actually returned a result before indexing into it with [0], an empty list means no face was detected
Slow webcam performanceResize the frame to a quarter scale as shown in section 7, or use a GPU-accelerated build of dlib if your hardware supports it

Guarding against the empty-list case from the second row looks like this in practice:

python
encodings = face_recognition.face_encodings(image)

if len(encodings) == 0:
    print("No face detected in this image.")
else:
    encoding = encodings[0]
    # continue with recognition

11What you can build

  • A smart door lock using a Raspberry Pi and camera module, unlocking automatically for recognized faces.
  • An attendance system for schools, checking students in against a known roster instead of manual sign-in.
  • A face-sorting photo gallery, automatically grouping photos by which known people appear in them.
  • Real-time face-based tagging for security cameras, flagging when a known or unknown person appears on camera.

12Where to go next

The face_recognition library makes face detection and recognition in Python extremely accessible, even for complete beginners. With just a few lines of code you can build genuinely impressive, real-world projects that leverage the same deep learning models used in production systems.

You now know how to detect and identify faces in images and video, compare faces against known profiles, and build real-time recognition with a webcam. A few directions to take it further:

  • Drop down a level to dlib directly if you need more control over the detection or encoding process than this library's simplified API exposes.
  • Build a complete, persistent system with a proper database of known faces rather than a folder of images, covered in the full face recognition system build.
  • Combine this with general OpenCV image handling techniques from the OpenCV in Python guide for preprocessing steps like resizing, cropping, or enhancing images before recognition.

For the broader sequence of what to study before and after this topic, see the Python roadmap.

Keep building your Python skill tree
See exactly what to learn after face_recognition, in order, with every guide on this site mapped to a stage.
View the Python roadmap
Scroll to Top