Face Recognition is a trending technology at present. And today, we’re going to learn face recognition and detection using the Python OpenCV library.
Everywhere you see faces, you look out into the offline world and the Internet world.
Faces, both in photographs and in films. Our brain, of course, quickly recognizes the human in the photographs and videos.
Yet we want computers or cell phones to define these items themselves. So let’s talk about two ways we can detect faces in photos.
How does face recognition work?
The most popular way for face and object detection, in general, is using HOG classifiers.
HOG stands for Histogram of Oriented Gradients. The crux of the matter is in finding appropriate feature descriptors for an image, be it faces or other objects.
In 2005, Histogram of Oriented Gradients(HOG) features were implemented by Navneet Dalal and Bill Triggs.
The Histogram of Oriented Gradients (HOG) is a function descriptor used primarily for object recognition in image processing. A function descriptor is a representation of an image or an image patch that by extracting valuable information from it, simplifies the image.
The theory behind the descriptor histogram of directed gradients is that the distribution of intensity gradients or edge directions will define the appearance and shape of local objects within an image.
The x and y derivatives of an image (Gradients) are helpful because due to sudden change in amplitude, the magnitude of gradients is high around edges and corners and we know that edges and corners pack a lot more object shape details than flat regions.
Therefore the gradient path histograms are used as properties of this descriptor:
Steps to calculate HOG descriptors for face recognition and detection
- The picture is divided into 8 to 8 cell blocks, and for each 8 to 8 cell block, a histogram of gradients is measured.
- A vector of 9 buckets (numbers) corresponding to angles from 0 to 180 degrees is basically a histogram (20-degree increments).
- The values of these 64 cells (8X8) are binned into these 9 buckets and cumulatively inserted.
- This restricts 64 values to 9 values, in principle.
Using the face_recognition library to detect faces
There is a library called face_recognition that has optimized code for detecting faces.
We’ll install and import in the same line using the Python pip and import. So let’s quickly do that:
import PIL.Image import PIL.ImageDraw !pip install face_recognition import face_recognition as fr
Next I downloaded an image from the internet, which had a lot of faces:
So now we can load the above file:
img = fr.load_image_file("/content/boyband.jpg") print(img)
When we run the above code, we get this output:
array([[[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], [[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], [[223, 218, 248], [223, 218, 248], [223, 218, 248], ..., [248, 248, 248], [248, 248, 248], [248, 248, 248]], ..., [[201, 28, 30], [205, 32, 34], [206, 32, 34], ..., [160, 14, 15], [179, 18, 23], [185, 18, 25]], [[201, 27, 29], [203, 29, 31], [204, 30, 32], ..., [152, 8, 8], [171, 12, 16], [181, 14, 21]], [[201, 27, 29], [201, 27, 29], [200, 27, 29], ..., [150, 8, 7], [167, 13, 15], [180, 15, 21]]], dtype=uint8)
Any color image is comprised of 3 channels: blue, green, and red. These are three matrices present in the above array. So a 50×50 color image will become a 50x50x3 matrix.
We can get the number of faces in the photo which gives us 10:
face_loc = fr.face_locations(img) no_of_faces = len(face_loc) print(no_of_faces)
So we have 10 faces in the photo. Let’s draw rectangles on these faces and then output it to a file:
pil_image = PIL.Image.fromarray(img) for face_location in face_locations: top,right,bottom,left =face_location draw_shape = PIL.ImageDraw.Draw(pil_image) draw_shape.rectangle([left, top, right, bottom],outline="red") pil_image.save("output.jpg")
So it’s quite accurate. Now, let’s talk about another method.
Using Python OpenCV to detect faces
Python OpenCV on the other hand uses HAAR cascades to detect its features. It’s a little slower, but highly accurate!
import cv2 import matplotlib.pyplot as plt %matplotlib inline
Now I took another picture from the internet:
image2 = cv2.imread("/content/MET-GALA.jpg") gray_img = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) plt.imshow(gray_img, cmap='gray')
Next we bring in the cascade classifier for face that is present within OpenCV:
haar_face_cascade = cv2.CascadeClassifier('/content/haarcascade_frontalface_alt.xml') faces = haar_face_cascade.detectMultiScale(gray_img) print('Faces found: ', len(faces))
and it gives us accurately 8.
So now let’s draw a rectangle around it:
for (x, y, w, h) in faces: cv2.rectangle(image2, (x, y), (x+w, y+h), (0, 255, 0), 2) plt.imshow(image2)
And voila ! That’s it for now.
Complete Code for Face Recognition in Python
The complete code along with all the necessary image files and XML can be found at https://github.com/arkaprabha-majumdar/face_recog
1. First implementation using the face_recognition library
import PIL.Image import PIL.ImageDraw import face_recognition as fr import matplotlib.pyplot as plt image1 =fr.load_image_file("/content/boyband.jpg") image2 =fr.load_image_file("/content/MET-GALA.jpg") print(image1) plt.imshow(image1) pil_image = PIL.Image.fromarray(image2) for face_location in face_loc: top,right,bottom,left =face_location draw_shape = PIL.ImageDraw.Draw(pil_image) draw_shape.rectangle([left, top, right, bottom],outline="green") pil_image.save("output.jpg")
2. Second Implementation Using OpenCV
import cv2 import matplotlib.pyplot as plt gray_img = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY) plt.imshow(gray_img, cmap='gray') haar_face_cascade = cv2.CascadeClassifier('/content/haarcascade_frontalface_alt.xml') faces = haar_face_cascade.detectMultiScale(gray_img) print('Faces found: ', len(faces)) for (x, y, w, h) in faces: cv2.rectangle(image2, (x, y), (x+w, y+h), (0, 255, 0), 2) plt.imshow(image2)
Make sure the file paths are correct so you can have the exact outputs as we have in our examples above. If you need help, you can always refer to the Github repository mentioned above.
If you liked reading this article and want to read more, continue to follow Journaldev. Stay tuned for many such interesting articles in the coming few days!
Happy learning! 🙂