Hello World!
Hope everything is well at your end.. If not! and you are stuck with something like making your own face recognition system or just you want to implement few algorithms to do some task like face recognition this post will definitely help you out in just three steps.
So, let's get started with the things required to complete this project:
- OpenCV 2.4.9
- Python 2.7.10
- AT&T face dataset here's the link
- 30 minutes of time
Steps:
- Make/Create data
- Train the model and Save it to disk
- Load the saved model and test it in real time
01. Create your own data
Here's the folder hierarchy of our face data
| --database
| |—- s0
| | |—- 1.pgm
| | |—- 2.pgm
| | |—- ...
| |—- s1
| | |—- 1.pgm
| | |—- 2.pgm
| | |—- ...
| |—- aquib(your face folder name)
| | |—- 1.pgm
| | |—- 2.pgm
| | |—- ...
Because we are going to make it real time, we need to have our own face data so that we can test it.
The code below will take 45 images of the face and saves it in the folder. What is happening here’s is, the camera will open and detect the face from the frames and it take face and resize it to 112×92 pixels with the extension of the file name with .pgm. To detect face in a frame we use haarcascade frontalface default.xml and OpenCV function to detect face.
# create_database.py
import cv2, sys, numpy, os, time
count = 0
size = 4
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'database'
fn_name = sys.argv[1] #name of the person
path = os.path.join(fn_dir, fn_name)
if not os.path.isdir(path):
os.mkdir(path)
(im_width, im_height) = (112, 92)
haar_cascade = cv2.CascadeClassifier(fn_haar)
webcam = cv2.VideoCapture(0)
print "-----------------------Taking pictures----------------------"
print "--------------------Give some expressions---------------------"
# The program loops until it has 20 images of the face.
while count < 45:
(rval, im) = webcam.read()
im = cv2.flip(im, 1, 0)
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
mini = cv2.resize(gray, (gray.shape[1] / size, gray.shape[0] / size))
faces = haar_cascade.detectMultiScale(mini)
faces = sorted(faces, key=lambda x: x[3])
if faces:
face_i = faces[0]
(x, y, w, h) = [v * size for v in face_i]
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
pin=sorted([int(n[:n.find('.')]) for n in os.listdir(path)
if n[0]!='.' ]+[0])[-1] + 1
cv2.imwrite('%s/%s.png' % (path, pin), face_resize)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.putText(im, fn_name, (x - 10, y - 10), cv2.FONT_HERSHEY_PLAIN,
1,(0, 255, 0))
time.sleep(0.38)
count += 1
cv2.imshow('OpenCV', im)
key = cv2.waitKey(10)
if key == 27:
break
print str(count) + " images taken and saved to " + fn_name +" folder in database "
run python create_data.py name_of_the_person
02. Train the model and saving it to disk
we need to train the Images present in the face_data for training. The currently available algorithms(in opencv 2.4.9) are:
- Eigenfaces ( createEigenFaceRecognizer())
- Fisherfaces ( createFisherFaceRecognizer())
- Local Binary Patterns Histograms ( createLBPHFaceRecognizer())
We are going to use createLBPHFaceRecognizer(), Now open another new python file named it as trainer.py,
# trainer.py
import cv2, sys, numpy, os,pyttsx,time
size = 4
fn_haar = 'haarcascade_frontalface_default.xml'
fn_dir = 'database'
recognizer = cv2.createLBPHFaceRecognizer()
# Part 1: Create fisherRecognizer
print('Training...')
# Create a list of images and a list of corresponding names
(images, lables, names, id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(fn_dir):
for subdir in dirs:
names[id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
for filename in os.listdir(subjectpath):
path = subjectpath + '/' + filename
lable = id
images.append(cv2.imread(path, 0))
lables.append(int(lable))
id += 1
(im_width, im_height) = (112, 92)
# Create a Numpy array from the two lists above
(images, lables) = [numpy.array(lis) for lis in [images, lables]]
recognizer.train(images, lables)
recognizer.save('trainer.yml')
run python trainer.py
03. Load the saved model and test it on real-time video feed
Now, we have saved model to the disk, we have to load it in memory and start making prediction. How we are going to do this is just we need to detect face from the current frame as we have done earlier in step 1, then pass it to the classfier model which we have got from step 2. But before passing it directly we need to resize it as we have done for training data. Open new python file and name it real_time.py
import cv2,os
# Import numpy for matrices calculations
import numpy as np
# Create Local Binary Patterns Histograms for face recognization
recognizer = cv2.createLBPHFaceRecognizer()
# Load the trained mode
recognizer.load('trainer.yml')
fn_dir = 'database'
# Load prebuilt model for Frontal Face
cascadePath = "haarcascade_frontalface_default.xml"
(im_width, im_height) = (112, 92)
# Part 2: Use fisherRecognizer on camera stream
(images, lables, names, id) = ([], [], {}, 0)
for (subdirs, dirs, files) in os.walk(fn_dir):
for subdir in dirs:
names[id] = subdir
subjectpath = os.path.join(fn_dir, subdir)
for filename in os.listdir(subjectpath):
path = subjectpath + '/' + filename
lable = id
images.append(cv2.imread(path, 0))
lables.append(int(lable))
id += 1
face_cascade = cv2.CascadeClassifier(cascadePath)
webcam = cv2.VideoCapture(0)
while True:
(_, im) = webcam.read()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(im,(x,y),(x+w,y+h),(255,0,0),2)
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (im_width, im_height))
# Try to recognize the face
prediction = recognizer.predict(face_resize)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
if prediction[1]<500:
cv2.putText(im,'%s - %.0f' % (names[prediction[0]],prediction[1]),(x-10, y-10), cv2.FONT_HERSHEY_PLAIN,1,(0, 255, 0))
else:
cv2.putText(im,'not recognized',(x-10, y-10), cv2.FONT_HERSHEY_PLAIN,1,(0, 255, 0))
cv2.imshow('OpenCV', im)
key = cv2.waitKey(10)
if key == 27:
break
run real_time.py
Completed :)
This is very basics but still you can see some good results, I would like to point out few things are as follows:
- Light conditions really matters a lot, So your accuracy will vary accordingly
- Maximum accuracy I got is between 70-75%
- you can implement it on Raspberry Pi
Most of the things, I tried my best to explain in this post, But still if you face any issue just put it in the comment, You can download the code from my github repo
Here's the demo:
Thanks a lot !
This type of thing may be an added feature of web browsers soon.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
yeah, there are a lot of JavaScript libraries are there, Where we can run the deep-learning model in web browser.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Exactly.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @aquib! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Award for the number of comments
You got a First Reply
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit