Face Recognition – OpenCV Python | Dataset Generator

In my last post we learnt how to setup opencv and python and wrote this code to detect faces in the frame. Now lets take it to the next level, lets create a face recognition program, which not only detect face but also recognize the person and tag that person in the frame

Lets Do Face Recognition

To make a face recognition program, first we need to train the recognizer with dataset of previously captured faces along with its ID, for example we have two person then first person will have ID 1 and 2nd person will have ID 2,  so that all the images of person one in the dataset will have ID 1 and all the images of the 2nd person in the dataset will have ID 2, then we will use those dataset images to train the recognizer to predict the 1 of an newly presented face from the live video frame

So lets break the program into 3 major part:

  1. Dataset Creator
  2. Trainer
  3. Detector

In this post we are going to see how to create a program to ganerate dataset for our face recognition program

Dataset Generator

Lets create the dataset generator script, open your python IDLE and create a new file and save it in your project folder and make sure you also have the haarcascade_frontalface_default.xml file in the same folderJust like in the previous post we will need to do the following first:

  • cv2 library (opencv library)
  • create a video capture object
  • cascadeClassifier object

So here it is in form of python code

In [ ]:
import cv2
cam = cv2.VideoCapture(0)
detector=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
Our dataset generator is going to capture few sample faces of one person from the live video frame
and assign a ID to it and it will save those samples in a folder which we are going to create now and we will name it dataSet
So create a folder named dataSet in the same location where you have saved your .py scriptWe are going to follow this naming convention for the sample images to make sure they dont mixed up with other person’s image samples

User.[ID].[SampleNumber].jpgfor example if the user id is 2 and its 10th sample from the sample list then the file name will be

User.2.10.jpg
Why this format?? well we can easily get which user’s face it is from its file name while loading the image for the training the recognizer
OK, now lets get the user id from the shell as input, and initialize a counter variable to store the sample number
In [ ]:
Id=raw_input('enter your id: ')
sampleNum=0
Now let start the main loop, we will take 20 samples from the video feed and will save it in the dataSet folder that we created previously
In [ ]:
while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

    cv2.imshow('frame',img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
We wrote the above code to detect face in my earlier post,
So we are going to modify this code to make the dataset generator for our face recognizer program
In [ ]:
while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        
        #incrementing sample number 
        sampleNum=sampleNum+1
        #saving the captured face in the dataset folder
        cv2.imwrite("dataSet/user."+Id+'.'+str(sampleNum)+".jpg",gray[y:y+h,x:x+w])

        cv2.imshow('frame',img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

So we added this two lines there to get the sample number and save the face in jpg format with our naming convention

and for those who dont know what we captured the face, its this “gray[y:y+h,x:x+w]” part where x,y is the top left coordinate of the face rectangle and h,w is the height and the weight of the face in terms of pixels

but this code will take samples vary rapidly like 20 samples in a second.. but we dont want that, we want to capture faces from different angles and for that it needs to be slow.

for that we need to increase the delay between the frames
and we need to break the loop after it took 20 samples so we need to change few more things in the above code

In [ ]:
while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        
        #incrementing sample number 
        sampleNum=sampleNum+1
        #saving the captured face in the dataset folder
        cv2.imwrite("dataSet/User."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w]) #

        cv2.imshow('frame',img)
    #wait for 100 miliseconds 
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # break if the sample number is morethan 20
    elif sampleNum>20:
        break

There we go, now it will wait for 100 between frames which will give you time to move your face to get a different angle and it will close after taking 20 samples

So our main loop is done now we just have to release the camera and close the windows

In [ ]:
cam.release()
cv2.destroyAllWindows()

Lets Test It

If we run this code now then we will see that it will capture faces from the live video and will save it in the dataSet folder

looks good… Now we have our dataset we can now train the recognizer to learn the faces from this dataset

In the next post we will create the trainer portion of the code

NOW THE COMPLETE CODE IN ONE PIECE

In [ ]:
import cv2
cam = cv2.VideoCapture(0)
detector=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

Id=raw_input('enter your id')
sampleNum=0
while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        
        #incrementing sample number 
        sampleNum=sampleNum+1
        #saving the captured face in the dataset folder
        cv2.imwrite("dataSet/User."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w])

        cv2.imshow('frame',img)
    #wait for 100 miliseconds 
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # break if the sample number is morethan 20
    elif sampleNum>20:
        break
cam.release()
cv2.destroyAllWindows()

VIDEO TUTORIAL OF THIS POST

 

 

Updates:
Github links:

For this code: you can visit: https://github.com/thecodacus/Face-Recognition

nazmi69 has done a good job converting the code for python 3.x and opencv 3.0
available at https://github.com/nazmi69/Face-Recognition

  • Pavel

    Thank you for tutorial!
    You have done only one of three parts, right?
    Please subscribe me for your updates || next parts of this.
    And please point me to an example with C++, if you have it or if you found it somewhere. Thank you again!

    • Anirban

      I will be uploading the other parts, and yeah for c++ the structure is same everything is same you just have to replace it with c++ syntax that you can get open opencv official website
      and I have added you in the email subscriber list. so you will be automatically notified in this email

  • Thanks for this, but there is a mistake in your code.

    On line 3 it should be face_detector = … instead of “detector ”

    or change

    “while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:”

    to

    while(True):
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:

    • Anirban

      Yeah sorry did not cross checked the code after mixing the pieces.. I fixed it, now its fine thanks for pointing out 🙂

  • Quality posts is the secret to attract the users to visit the website, that’s what this website is providing.

  • Prathamesh

    Hi, i tried with your code on Raspberry Pi 3 – OpenCV + Python

    But i got the following error –

    Traceback (most recent call last):
    File “/home/prath/Documents/Python Programs/1.py”, line 12, in
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    error: /home/prath/opencv-3.0.0/modules/imgproc/src/color.cpp:7564: error: (-215) scn == 3 || scn == 4 in function cvtColor

    Can you please help me in solving this?
    Thanks in advance

    • I guess you installes opencv using “apt-get install opencv” install it using “synaptic” you will find a package named opencv-python and the version will be 2.4

      and regarding this problem for some reason its not able to capture images, are you using picamera ?

      • shiva

        is it in linux or in the windows .
        i’m using the windows10
        the same problem i have been facing

        • Shiva all the tutorials are for both Windows and Linux. i was replying as he is using raspberry pi

          • Ravi Solanki

            i am using pi camera

          • you cannot use cv2.videoCapture() to access pi camera.. there are some tutorials in pi website to access pi camera you can check that

  • shiva

    i have tried your code but it is showing the error , please help me to solve this problem,
    Traceback (most recent call last):
    File “C:/exp/faceexp1/datasetcre.py”, line 8, in
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    error: ..\..\..\..\opencv\modules\imgproc\src\color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor

    • paste your code in the comment so that i can see whats wrong

      • shiva

        import cv2
        cam = cv2.VideoCapture(0)
        detector=cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)
        Id=raw_input(‘enter your id: ‘)
        sampleNum=0
        while(True):
        ret, img = cam.read()
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = detector.detectMultiScale(gray, 1.3, 5)
        for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        sampleNum=sampleNum+1

        cv2.imwrite(“dataSet/User.”+Id +’.’+ str(sampleNum) + “.jpg”, gray[y:y+h,x:x+w])

        cv2.imshow(‘frame’,img)

        if cv2.waitKey(100) & 0xFF == ord(‘q’):
        break

        elif sampleNum>20:
        break
        cam.release()
        cv2.destroyAllWindows()

        • put cam.release() outside the loop.. thats the reason your cam object is not able to get image after first loop.. it has already released the camera

          • shiva

            the photos are not saving in the dataset folder what should i do?
            the camera is opened and its closed

        • Ravi solanki

          i am getting the same error although i have put cam.release outside the loop.

          my code is:-

          import cv2
          cam = cv2.VideoCapture(0)
          detector=cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)

          Id=input(‘enter your id’)
          sampleNum=0
          while(True):
          ret, img = cam.read()
          gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
          faces = detector.detectMultiScale(gray, 1.3, 5)
          for (x,y,w,h) in faces:
          cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)

          #incrementing sample number
          sampleNum=sampleNum+1
          #saving the captured face in the dataset folder
          cv2.imwrite(“dataSet/User.”+Id +’.’+ str(sampleNum) + “.jpg”, gray[y:y+h,x:x+w])

          cv2.imshow(‘frame’,img)
          #wait for 100 miliseconds
          if cv2.waitKey(100) & 0xFF == ord(‘q’):
          break
          # break if the sample number is morethan 20
          elif sampleNum>20:
          break

          cam.release()
          cv2.destroyAllWindows()

          • maymuna

            i got same error while working on my raspberry pi so went to the terminal and put this line of code below
            sudo modprobe bcm2835-v4l2
            and it worked like a charm !

  • Vasantha

    The same problem in my code also. Code is running but photos are not saved in dataSet. What is the problem. I am running this code on raspberries pi with webcam.

    • shiva

      have u made the same code as shown in the blog.

      • Vasantha

        Yes. Now I got what was the problem.. I wanna change the path of my dataSet folder. Now it’s running. Thank you.

        • shiva

          kk fine

    • Ravi solanki

      i have the same problem. please guide me

  • HIrdya Negi

    if anyone getting this error
    NameError: name ‘raw_input’ is not defined
    change ‘raw_input’ to ‘input’
    since ‘raw_input’ is for python 2.7 &
    ‘input’ is for python 3.1

  • Areeba Kamil

    hi!
    Great job!
    I tried your code and it works perfectly fine!
    it captures images and stores it in the dataSet folder.

    there is one problem I am facing which is:
    When I tried your code for face detection only, it worked perfectly and the camera window opened and detected my face

    when I ran this code – datasetCreator – it also works fine and stores my pictures in the dataset but for some reason the camera window doesn’t open. I can see the light next to the web cam turn on as the code runs however the camera window does not open.

    is there something wrong with my computer (Lenovo G50) or should I change something in the code

    THANKS 😀

  • Jacki

    I have the some problem on my raspberry pi
    Please help me
    My error:

    Opencv Error: Assertion failed (scn == 3 || scn == 4 in cvtColor, file /home/pi/opencv-3.1.0/modules/imgproc/src/color.cpp, line 8000
    Traceback (most recent call last):
    File ”datasetCreator.py”, line 9, in
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    cv2.error: /home/pi/opencv-3.1.0/modules/imgproc/src/color.cpp:8000: error: (-215) scn == 3 || scn == 4 in function cvtColor

    I’m waiting for your help
    Regards

    • the captured image is emply
      I think you might have indentation issue in your code

  • Aditya Singh

    I am getting cvt.Color error in above program. Please suggest a way to solve it. Email ID is singh.aditya8499@gmail.com