creating a face-recognising security cam with a raspberry pi part 2

Upload: rocke-zoolander

Post on 03-Apr-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    1/11

    Through the Interface

    September 19, 201 2

    Creating a face-recognising security cam with a Raspberry Pi Part 2

    In the first post in this series, we introduced the idea behind the Facecam, a Facebook-enabled security camera

    running on a Raspberry Pi device.

    Over the next three posts were going to look in more detail at the systems co mponents. In this post, were gointo start by looking at the co mponent the only one that doesnt actually run on the RaspberryPi that

    do wnloads the information from Faceboo k to build the facial reco gnition database to be used by the dev ice.

    As mentioned last time, Iv e coded this as a .NET application actually by ex tending the WinForms sample

    provided with the Facebo ok C# SDK in order to dedicate the Raspberry Pi to performing the security cam

    function. Im not actually going to share the co de for this application, as its really a work in progress. The co de

    itself isnt very co mplicated the Facebo ok piece is mostly ex ecuting FQL, which allows y ou to use a SQL-like

    syntax to query the Facebo ok Graph API and Ill be descr ibing the techniques it uses should people want to g

    ahead and roll their own.

    Before loo king at the behaviour of the application itself, its important to understand more about this databasethat its going to help build.

    The facial reco gnition co de Iv e adopted is based on work by Shervin Emami and uses the Eigenface algorithm t

    co mpare detec ted faces against a database. To understand more about Eigenface, this article pro vides a

    thorough explanation.

    Shervins OnlineFaceRec sample makes use o fOpenCV for this process. Ive borrowed co de from this sample fo

    use on the Raspberry Pi, but today s application simply builds a file and folder structure that can be used by the

    OnlineFaceRec application to train the database (and essentially build the facedata.xml file well transfer acros

    to the Raspberry Pi).

    There are two main parts of this proc ess: downloading the friend data from Facebo ok and then parsing that daton disk in order to create a training script to be passed to OnlineFaceRec.

    These two functions are reflected by the basic UI of the .NET application:

    Clicking on the first button lets us log in to Facebo ok and accept the permissions requested by the .NET

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://www.shervinemami.info/faceRecognition.htmlhttp://en.wikipedia.org/wiki/Eigenfacehttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2450970c-pihttp://www.cognotics.com/opencv/servo_2007_series/part_4/index.htmlhttp://en.wikipedia.org/wiki/Eigenfacehttp://www.shervinemami.info/faceRecognition.htmlhttps://developers.facebook.com/docs/reference/api/https://developers.facebook.com/docs/reference/fql/http://csharpsdk.org/https://github.com/facebook-csharp-sdk/facebook-winforms-samplehttp://through-the-interface.typepad.com/through_the_interface/2012/09/creating-a-face-recognising-security-cam-with-a-raspberry-pi-part-1.htmlhttp://through-the-interface.typepad.com/through_the_interface/
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    2/11

    application. Which reminds me: to create an application that makes use of the Facebook A PI, youll need to

    register it with Facebook and include the AppId in y our co de. As y ou c an see below, I c alled my app

    FriendExtractor:

    Once were lo gged in, we see the main dialog which will help us drive the download proc ess:

    Clicking on the Populate Friends button pulls down the list of the current users friends from Faceboo k and

    populates the list on the left:

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017744ae6a65970d-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017c31d0a3da970b-pihttp://facebook.com/developers
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    3/11

    Y ou can se e the list has checkbo xes asso ciated with each item. Originally the implementation didnt allo w

    selection o f friends to include, which ended in a huge amount of data being downloaded (it turns out I hav e

    friends who seem to do no thing other than upload their pictures to Facebo ok and have 1 000+ tagged images u

    there). Running OnlineFaceRec to train the database with the results ended up in a 400 MB facedata.xml file

    be ing c reated. Giv en the fact the R-Pi has 25 6MB of RAM< I figured that was a no n-starter. :-)

    I therefore enabled selec tion of friends that are actually likely to v isit our home or that I may end up demoin

    this to at AU which greatly reduc es the amount of probably redundant data that gets downloaded and

    processed. The list of selected friends gets saved in a simple text file and reloaded automatically.

    I also added the ability to start do wnloading from a particular friend, to allow incremental additions/updates.

    The first time its run, its certainly wo rth starting from the beginning, of co urse, but y ou may want to restart

    from a friend further down the list a later point.

    When y ou selec t a friend o n the le ft, the Start Download from Selected butto n should c ome aliv e. Pushing it

    does whats written on the box :

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017c31d0a3fa970b-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    4/11

    Once c ompleted, y oull have a folder full of photos of you and y our friends. The folder structure contains one

    level of indirection to use the user I D as friends can v ery well have the same name (theres a teenager named

    Kean Walmsley who lives in Canada and friended me o n Facebo ok some time ago, for instance) and inside tha

    folder y oull find a collec tion of images:

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017744ae6a93970d-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    5/11

    Looking closely, abo ve, y oull see there are both .jpg and .pgm images. The .jpg files are those downloaded

    directly from Faceboo k nothing surprising there. The .pgm files are c reated by the .NET application using

    following algorithm:

    For each tagged photo o f a user

    Use OpenCV face detection to find the faces in the image

    For this I used Emgu CV a .NET wrapper for OpenCV along with OpenCVs face detection featur

    that looks for haar-like features

    Compare the tag location with the faces returned. For the best match

    Take a greyscale copy of the cropped area

    Resize it to 50 x 5 0

    Equalize the histogram to get c onsistent brightness and contrast

    Save that file to the .pgm format

    Regarding the quality o f the photos downloaded from Facebook: frankly, it varies. Some pho tos are po orly

    tagged, and some are tagged well enough but the face c annot easily be ex tracted (which sometimes means

    someone elses gets picked up in its place). A nd then some pho tos simply arent well suited to facedetection/ex traction, so the results end up being just plain strange.

    Iv e found that some kind of manual scrubbing process between the download and the script creation/database

    training helps the quality of the data a great deal. Ive used a tool called Ir fanView to do this: y ou can searc h a

    set of sub-folders for *.pgm files and transfer the results acro ss into Thumbnail View, and c an then proc eed to

    delete the ugly pics from there. Of course y ou could do the same thing in Explo rer if you had a shell extension

    that can prev iew .pgm files, but I wasnt able to find one. A nd IrfanView seems to wo rk pretty well.

    Heres a v iew of some shots o f Sco tt Sheppard and Shaan Hurley , for instance:

    http://www.irfanview.net/http://opencv.willowgarage.com/wiki/FaceDetection/http://www.emgu.com/http://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff24c3970c-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    6/11

    In time I expec t a bespoke tool one that remembers the pics youve deleted before, to save yo u having to

    repeat that task each time is the way to go. But thats for another time.

    Once this is done, y ou should hav e a fairly c lean set of normalised (i.e. of the same size and with similar

    br ightness/ contrast) files that can be used to generate a training script for the OnlineFac eRec tool.

    The second button o n our main dialog runs some co de that copies the .pgm files to a separate folder and create

    a training script listing them all:

    privatevoid btnCreateScript_Click(object sender, EventArgs e)

    {

    conststring root = "Z:\\fb_photos\\"; conststring destRoot = "Z:\\rp_photos\\";

    SortedList checkedFriends =

    InfoDialog.LoadCheckedFriends();

    // Get the list of PGM files in our source directory

    DirectoryInfo di = newDirectoryInfo(root);

    var files = di.GetFiles("*.pgm", SearchOption.AllDirectories);

    StringBuilder sb = newStringBuilder(),

    cur = newStringBuilder();

    // We'll maintain an index for the persons and an

    // old user ID, so we can tell when we have changed

    // to a new person's data

    int person = 0;

    string ouid = "";

    // Maintain a counter of the number of photos for

    // the current person (we only write out 2+ photos,

    // as otherwise they don't train the database),

    // as well as a list of their paths

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff24f6970c-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    7/11

    int photosForCurrent = 0;

    List filesForCurrent = newList();

    foreach (FileInfo fi in files)

    {

    var path = fi.DirectoryName;

    var info = path.Split(new[] { '\\' });

    if (info.Length == 4)

    {

    string name = info[2], uid = info[3];

    if (ouid != uid)

    {

    // We have a new user

    ouid = uid;

    // If the last user had more than 2 photos...

    if (photosForCurrent > 2)

    {

    // Let's add them to the training script and

    // copy the files to the destination

    person++;

    sb.Append(cur.ToString());

    foreach (string file in filesForCurrent)

    {

    string destFile =

    destRoot +

    Utils.RemoveAccents(file.Substring(root.Length));

    Directory.CreateDirectory(

    Path.GetDirectoryName(destFile)

    );

    File.Copy(file, destFile, true);

    }

    }

    // Reset the string, photos and image file info

    // for the current user

    cur.Clear();

    photosForCurrent = 0;

    filesForCurrent.Clear();

    }

    long id = Int64.Parse(uid);

    if (checkedFriends.ContainsKey(id))

    {

    // Add the information on the current photo to

    // the current user's string

    cur.Append(

    String.Format(

    "{0} {1} {2}\r\n",

    person, Utils.RemoveAccents(name),

    "./" +

    Utils.RemoveAccents(fi.FullName).

    Substring(root.Length).Replace('\\', '/')

    )

    );

  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    8/11

    // Do the same for the photos to copy across to

    // the destination

    photosForCurrent++;

    filesForCurrent.Add(fi.FullName);

    }

    }

    }

    // Don't forget to tidy up and copy the last user's

    // training string and files across

    sb.Append(cur.ToString());

    foreach (string file in filesForCurrent)

    {

    string destFile =

    destRoot + file.Substring(root.Length);

    Directory.CreateDirectory(

    Path.GetDirectoryName(destFile)

    );

    File.Copy(file, destFile, true);

    }

    // Finally we write out the string to the training file

    File.WriteAllText(

    destRoot + "training.txt", sb.ToString()

    );

    }

    In case y oure wondering, Ive kept the two main pieces of the process separate primarily so I can co mbine my

    wifes friends with my own be fore tr aining the database. :-)

    Now its a simple matter of running OnlineFaceRec with the training script:

    The output of this tool is pretty interesting: aside from the v ery importantfacedata.xmlfile (the database well

    use on the Raspberry Pi), we also two files that are created mainly to demonstrate the principle at work.

    Firstly we have the average face which is the absolute av erage of all the pictures of your friends, and tends to

    be a bland, slightly andro gy nous and some might say idealised image o f a human fac e:

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017744ae6af1970d-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    9/11

    And seo ndly we hav e an image o f the Eigenfac es themse lv es, which map the differences from this av erage imag

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017c31d0a4c9970b-pihttp://through-the-interface.typepad.com/.a/6a00d83452464869e2017d3bff2526970c-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    10/11

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017c31d0a4c9970b-pi
  • 7/28/2019 Creating a Face-recognising Security Cam With a Raspberry Pi Part 2

    11/11

    Creating a face-

    recognising

    Creating a face-

    recognising

    Waiting for my

    Raspberry Pi

    Creating a motion-

    detecting security

    Neither of these images needs to b e transferred acro ss to the Raspberry Pi their data is captured in the XML

    database (which stands at around 28 MB for the selected subset of my friends).

    In the next post, well look at the implementation of a co mponent that makes use o f this XML data to perform

    facial reco gnition on images captured by o ur motion detecto r.

    You m igh t also like:

    http://through-the-interface.typepad.com/.a/6a00d83452464869e2017c31d0a4c9970b-pihttp://through-the-interface.typepad.com/through_the_interface/2012/08/creating-a-motion-detecting-security-cam-with-a-raspberry-pi-part-1.htmlhttp://through-the-interface.typepad.com/through_the_interface/2012/08/waiting-for-my-raspberry-pi.htmlhttp://through-the-interface.typepad.com/through_the_interface/2012/10/creating-a-face-recognising-security-cam-with-a-raspberry-pi-part-4.htmlhttp://through-the-interface.typepad.com/through_the_interface/2012/09/creating-a-face-recognising-security-cam-with-a-raspberry-pi-part-1.html