Exploring Python Packages — OpenCV and face_recognition

Shrinand Kadekodi
6 min readJul 24, 2020

--

In this part we will be exploring something which is much more fun! Face Recognition! Face Recognition using python is quite simple. There are lot of packages and libraries which we will be using like OpenCV, dlib, face_recognition for the task. We will be using these libraries to detect faces in images for now and will be discussing two things -

Detecting faces — Here we will be just detecting faces in a photo (it will be a frontal face recognition).

Identifying faces in images — tagging faces by names and finding them in other images.

face_recognition package, which utilizes dlib is used in this task. For this you need to download dlib as well. Please go through my tutorial if you have not installed it the process is a bit tedious — https://evrythngunder3d.wordpress.com/2020/07/18/installing-dlib-for-python/

or on medium —
https://shrinandkadekodi.medium.com/installing-dlib-for-python-5b3842e7d22c

So lets get going and install the required packages and libraries!

Packages to install — OpenCV, dlib and face_recognition:

You need to install the above packages with pip install. For OpenCV open your Anaconda prompt and type — ‘ pip install opencv-python’. It will install OpenCV with any dependencies if required. The next step is to install face_recognition using — ‘ pip install face-recognition ‘. And of course you will have to install dlib as well! Once all these ingredients have been installed let’s start with preparing the course!

Face Identification/Detection:

In this task we will be trying to find out faces available in a given photo. We will do this by using OpenCV. For detection of face we will be using the Haar transform in the cascade classifier. How the Haar transform and cascade classifier works is out of the scope of this blog. For this we will be using the xml of frontal face detection ( haarcascade_frontalface_default.xml). You can download the xml from here — https://github.com/parulnith/Face-Detection-in-Python-using-OpenCV . Disclaimer : I have created the code by searching through the internet and using a variety of sources. The way in which the face detection works is -

  • Import the required packages.
  • Read the image by using OpenCV methods. One important thing to remember about OpenCV is that it reads images in BGR (Blue-Green-Red) and not traditional way of RGB (Red-Green-Blue). So if you try to view the image from OpenCV you will have to convert it using the method — cv2.cvtColor(rawImg, cv2.COLOR_BGR2RGB) where rawImg is the image to display.
  • Convert the image to grayscale by using cv2.cvtColor(rawImg, cv2.COLOR_BGR2GRAY) . A major reason for this is that it decreases the complexity and improves speed. Also another reason is that the OpenCV method for face detection requires grayscale images.
  • Once the faces are detected we will be enclosing them in a rectangular box to highlight them.

The code is below which carries out the above described functions:

# Importing the OpenCV package
import cv2
# This is the raw image taken
rawImg = cv2.imread('image_to_read_path.jpg')
# Resizing of the image
is required if it is too large. Here I have just given how you can do # this
# resizeImg =
# cv2.resize(rawImg, (int(rawImg.shape[1]/6),int(rawImg.shape[0]/6)),interpolation =
# cv2.INTER_AREA)
resizeImg = rawImg# As OpenCv takes form in BGR we convert to RGB for similarity across all
properImg = cv2.cvtColor(resizeImg, cv2.COLOR_BGR2GRAY)
# Load Haar Cascade for frontal face
haarCasFace = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Get the co ordinates where frontal face is there
facesRect = haarCasFace.detectMultiScale(properImg,scaleFactor = 1.3,minNeighbors = 2,minSize=(30,30))
print('Faces found: ', len(facesRect))
# Rectangle plotting on image for frontal face
for (x,y,w,h) in facesRect:
cv2.rectangle(resizeImg, (x, y), (x+w, y+h), (0, 255, 0), 2)


# View image in a window and close when exc is pressed
while True:
cv2.imshow('Correct Image',resizeImg)

# will close the windpw only when Esc key is pressed
if cv2.waitKey(1) & 0xFF == 27:
break

cv2.destroyAllWindows()

And you can see the image output as below:

The famous Oscar selfie, Credits: https://www.thedrum.com/news/2017/04/16/ellen-degeneres-enlists-bradley-cooper-help-keep-oscar-selfie-tweet-record

As you can see some of the faces have not been detected by OpenCV. You can check it by tweaking the different parameters in detectMultiScale method. But still it may not work in some different images. I would also suggest as an alternative to use face_recognition.

Its very easy to detect faces in images in python 😛. By writing a few lines of code we are able to detect faces and highlight them (though the theory behind them is vast and I will definitely write a blog explaining them in future).

Face Recognition :

I did not think face detection could be done so easily. So I thought maybe I can go one step further and try to identify the faces in the images (like Facebook name tagging images). For a start I tried with just one face. As I am a fan of Bradley Cooper I decided to identify him in this image.

But wait….. for this we need to first train the face recognition algorithm with the images of the person to be identified. And for this we will be using the face_recognition package. This uses inherently dlib which can use GPU when using neural nets. The path for this is more or less similar as the face detection. Disclaimer : I have created the code by searching through the internet and using a variety of sources.

  • First train the face_recognition package with multiple images of the person to be identified. The default method is hog (which I have used). You can also try with cnn method. But beware, without GPU it will take a very looooooooong time and your PC will freeze. As a matter of fact even with 2gb of MX150 I ran into BSD error 🤷‍♀️.
  • Get the different face data in an array and give each data the same name as the number of person is only one in our case.
  • Take the image where the person is there and compare with the data saved in the above step.
  • If maximum number of data match then assign the person the label saved.

Lets see the code to understand the implementation :

import face_recognition
import os
import cv2
# preprocessing images
def preProcessImage(image_path):

# This is the raw image taken
rawImg = cv2.imread(image_path)

# returning the image in RGB format
return cv2.cvtColor(rawImg, cv2.COLOR_BGR2RGB)
# encoding images
def faceRecogTrain(path):

# checking all the images in folder
image_paths = [os.path.join(path, f) for f in os.listdir(path)]

# encoded images will contains face images
knownEncoding = []

# labels will contains the label that is assigned to the image
knownName = []

for image_path in image_paths:

# preprocessing image
properImg = preProcessImage(image_path)

# face recognition with cnn
boxes = face_recognition.face_locations(properImg)

# encoding faces for prediction
encodings = face_recognition.face_encodings(properImg, boxes)
print('Faces found: ', len(encodings))

for encoding in encodings:
# saving the encodings
knownEncoding.append(encoding)
knownName.append('BradleyCooper')

return knownEncoding, knownName
# face recognition
def predictImages(path,priorEncoded,priorLabels):

# This is the raw image taken
rawImg = cv2.imread(path)

properImg = preProcessImage(path)

# face recognition with cnn
boxes = face_recognition.face_locations(properImg)

# encoding faces for prediction
encodings = face_recognition.face_encodings(properImg,boxes)

names = []

print('Faces found: ', len(encodings))

for encoding in encodings:

# comparing the faces with saved face data
matches = face_recognition.compare_faces(priorEncoded,encoding)
name = 'Unknown'
print(matches)
if True in matches:
matchedIdxs = [i for (i, b) in enumerate(matches) if b]
counts = {}
print(matchedIdxs)
for i in matchedIdxs:
name = priorLabels[i]
counts[name] = counts.get(name, 0) + 1

name = max(counts, key=counts.get)
names.append(name)

# drawing the rectangle and labelling the faces
for ((top, right, bottom, left), name) in zip(boxes, names):

# draw the predicted face name on the image
cv2.rectangle(rawImg, (left, top), (right, bottom), (0, 255, 0), 2)
y = top - 15 if top - 15 > 15 else top + 15
cv2.putText(rawImg, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 255, 0), 2)

# show the output image
cv2.imshow("Image",rawImg)
cv2.waitKey(0)
images, labels = faceRecogTrain("folder_path_of_image")
predictImages("path_of_image.jpg",images,labels)

And the output is as below

The famous Oscar selfie, Credits: https://www.thedrum.com/news/2017/04/16/ellen-degeneres-enlists-bradley-cooper-help-keep-oscar-selfie-tweet-record

You can see that some of the faces not recognized in OpenCV have been recognized here. And Bradley Cooper has been properly named 😅.

Well ending this post, we did see a couple of ways to detect and identify faces using python. Let me know if this was helpful!

References :
- https://www.geeksforgeeks.org/opencv-python-program-face-detection/
- https://www.geeksforgeeks.org/python-multiple-face-recognition-using-dlib/
- https://www.superdatascience.com/blogs/opencv-face-recognition
- https://www.pyimagesearch.com/2018/06/18/face-recognition-with-opencv-python-and-deep-learning/

Originally published at http://evrythngunder3d.wordpress.com on July 24, 2020.

--

--

Shrinand Kadekodi
Shrinand Kadekodi

Written by Shrinand Kadekodi

Simply curious about everything!

No responses yet