Simple face recognition using OpenCV

This article is now at


Posted on January 21, 2011, in Code and tagged , , , . Bookmark the permalink. 28 Comments.

  1. hi there
    thanks for the rear example
    how can i run this on vs2010

    • Hello Mohammed,
      I am sorry, but I do not know how to run this code on Visual Studio. I don’t use any special GCC functions here, only the C++ standard library and OpenCV. So it should be a simple matter of installing OpenCV on your machine, and adapting the linking flags.
      – Pebibyte

  2. yes ive done the opencv stepup properly. it keeps asking me “did you forget to add include stdafx.h to your source”. can you email me the project folder. so i can try running it. are you using the same database in the cognetics article?
    hbk1_hbk1 at hotmail dot com

    • I am not using Visual Studio (I actually never used it), so my directory, which is, by the way, composed uniquely of facerecog.cpp, will not help you.

      Regarding stdafx.h in the OpenCV example source code, it refers to some Microsoft specific precompiled headers. The tutorial says

      Click on “Debug -> Build Solution” or “Release -> Build Solution” to compile your project. If there was a compile error then you did not set the header file includes correctly. If there was a linker error then you did not set the library path or lib files correctly.

      Double-check the steps to create your project, especially parts about include files. If that doesn’t help, I think you can remove the stdafx.h include, but you may have to change _tmain and _TCHAR into something more common.
      – Pebibyte

      • thx for your help. ill try doing the above and let you know how it goes.

      • hi i got rid of the errors by reinstalling opencv and building the libs all over again. the codes fine now. just wanted to know where to store the images. im using the same images as in the article . my train.txt and test.txt file are in the same directory as the source code. should i leave the images in one folder in there? also is the result for this code the same as the article?

      • The train.txt and test.txt files should be in the same directory as the binary. If you follow the Cognotics example, images are in several directories numbered s1 to s40. These directories also live in the same directory as the binary and train.txt/test.txt. Obviously, you can modify test.txt and train.txt to point toward images elsewhere.

  3. hi, how can i modify this code so when it is given a image of one of the people in the database it will return that persons information. im sorry for being a bother to you. im new to this and im working on a uni project with similar functionality.
    thanks for your help

    • Hello,
      I won’t write code for you, but I can give you some indications regarding the overall design: you have a database storing the information you want to display. What you want, is to add a field to your database to store the face of the person projected into the PCA space. You also need to store the projection matrix (the eigenvectors). At the recognition phase, you have to project the input face into the PCA space using the eigenvectors, then compute the distance between the projected vector and each stored vector and take the smallest distance.
      If you’re stuck with the implementation, you are better off taking some reference book and reading it (The Art of Computer Programming by Donald Knuth is an example), as it doesn’t seem to involve any difficulty outside of the PCA code (that you have on this blog).
      – Pebibyte

      • thank you soo much for the tips. and no i will not ask you to write any code for me. but i will take any advice on how to implement the above 🙂
        i was actually thinking along the same lines . so let me just confirm the above.
        a database of the user information with a field that contains the projected image and eigenvectors.of the user.
        regarding the recognition phase is the user with the lowest distance between the stored vectors the correct user?
        so i only have to compute the vectors to get the correct result?

      • Except that eigenvectors are common to all users, and only eigenvalues need to be stored for each one of them (“set of eigenvalues for a user” and “projected user face” are strictly equivalent). See any linear algebra course (Stanford, MIT and Khan Academy are three good free resources) to have more in-depth understanding of what’s going on here.
        And yes, regarding the recognition phase, you only have to compute the eigenvalues of the face to be recognized and take the user with the smallest distance. You may want to add a threshold to this distance, though, if you have to address the case where you try to recognize a person not in the database.
        – Pebibyte

  4. HI,
    Can you please help me for run this code in VS 2008? I’ve never use c++ in VS, but I’ve use c# in VS.

  5. hi~I check you code in windows,i have problems for all of the vectors this seems to not work, all vectors only contain ‘nan’ as components.and eigen values all 0;I need you help, thx~

  6. The problem with this code is that if you give an unknown face it will recognize it at some one else face. It should tell us that it is an unknown face. how can it Possible??/

    • It is actually quite simple in theory, but needs a lot of tuning in practice. Basically, you need to define a minimum distance and declare a match only if the distance is less than this threshold (in findNearestNeighbor()).

  7. Hi,
    I have a doubt,
    if say i need to add one more face to the training face list. then do i need to re-create the facedata.xml?
    Is there any work around for the same, like can i include one more sample training face instead of creating the whole xml file again?

    • I did not have looked at this code for quite some time, but yes, you don’t need to re-create everything. You just need to update projectedTrainFaceMat (add one more projected face) and update nTrainFaces accordingly.

  8. Thanks for this solution. I read all the articles/code from the willowgarage links and cognotics article, but it was a huge pian trying to actually get the code up and running. Then I found this. Thanks a lot.

  9. Hi,
    I built this code on linux and trying to run. I have created a txt file called ‘train.txt’. This file contains 2 jpg files in each line. when i run this app with ‘train’ as command line argument, the application is crashing in function cvLoadImage. Can you please suggest what the train.txt file should contain and what is the image size we need to use? Should the images contain more faces?
    If there are sample ‘train.txt’ with jpg image files, please share.
    thanks in advance

  10. Hi This is a followup post to my previous post, i have analyzed the code and put debug statements to debug the issue. Find below the detials of my analysis. Please suggest where i’m going wrong.
    1. I have Created a file “train.txt” and kept in the current folder
    2. if i cat train.txt, it shows
    3. face2.jpg is jpeg file with 2 faces and face3.jpg is with 3 faces. These are color jpg files
    4. The function, loadFaceImgArray(“train.txt) will open the train.txt file, it will go in the following while loop to get the image file names from “train.txt” file
    // count the number of faces
    while( fgets(imgFilename, 512, imgListFile) ) ++nFaces;
    5. when it comes out of this loop, i will have nFaces = 2 and imgFilename=face3.jpg
    6. Allocate memory for faceImgArr= 8 bytes
    7. Call cvCreateMat
    8. Go in for loop till nFaces, and load image, here it goes in 2 loops and loads face3.jpg
    9. Close the image file and return
    10.Call doPCA() function
    11. In doPCA() function, it crashes in statement faceImgSize.width = faceImgArr[0]->width;
    12. It is not able to access faceImgArr[0]->width location and hence giving segmentation fault.

    Can you please suggest me where i’m doing wrong? thanks in advance.

    • I think the issue is with the format of your train.txt file. As you can see on line 108, it expects each line to be composed of a decimal (actually, an integer), then a space, then a string. The actual format is:

      So a train.txt file with two faces, one for person #2 and one for person #3 should be:
      2 face2.jpg
      3 face3.jpg

      Hope that helps

  11. Hi,
    Thanks a lot for the inputs. Eventhough i could solve the crash issue, sorry that i’m still not clear about the train.txt file. Say i have test1.jpg which contains only one face, then should i write in the train.txt file as 1 test1.jpg and if the test1.jpg has 2 faces, then it should be 2 test1.jpg?

    Secondly is train.txt same as test.txt? else what should be test.txt?

    How to analyse the output of this program? It shows nearest= and truth= with some big number on the screen. How to interpret this?

    Thanks again

  12. Hi, i would like to know Which version of OpenCV i need to use for building this code? I’m Currently using OpenCV2.4. Please let me know if this works with Open CV 2.4?

  13. I can’t understan why nEigens is nTrainFaces-1. Can it be equal? I tried nEigens = nTrainFaces; but in this situation last eigen image is returned null. Why?

  1. Pingback: DetectionBasedTracker : OpenCV implementation. « bytesandlogics

%d bloggers like this: