Facial Recognition via Python (non-OpenCV)

After working with the IR, I decided to cut the IR equipment out of the equation and was going to try my hand at facial recognition. This one does not use OpenCV or haarcascades. Instead, it uses a library I found through google called fdlib. It was written in C/C++, so using it with python shouldn’t be a problem. You can embed C/C++ in python via ctypes. You have already seen me use it in a previews post to set the cursor position in windows.

You can find fdlib at http://www.kyb.mpg.de/bs/people/kienzle/facedemo/facedemo.htm

The download also came with an example also written in C/C++

#include "windows.h"
#include "loadbmp.h" // from http://gpwiki.org/index.php/LoadBMPCpp
#include "fdlib.h"

void main(int argc, char *argv[])
 int i, n, x[256], y[256], size[256], w, h, threshold;
 BMPImg *bi;
 unsigned char *bgrdata, *graydata;

 if (argc==1)
 printf("usage: fdtest bmpfilename [threshold]\n");

 bi = new BMPImg();
 printf("\nloading %s\n", argv[1]);
 w = bi->GetWidth();
 h = bi->GetHeight();
 printf("image is %dx%d pixels\n", w, h);
 bgrdata = bi->GetImg();
 graydata = new unsigned char[w*h];

 for (i=0; i
 graydata[i] = (unsigned char) ((.11*bgrdata[3*i] + .59*bgrdata[3*i+1] + .3*bgrdata[3*i+2]));
 //if (i<10) printf("%d ", graydata[i]);

 threshold = argc>2 ? atoi(argv[2]) : 0;
 printf("detecting with threshold = %d\n", threshold);
 fdlib_detectfaces(graydata, w, h, threshold);

 n = fdlib_getndetections();
 if (n==1)
 printf("%d face found\n", n);
 printf("%d faces found\n", n);

 for (i=0; i
 fdlib_getdetection(i, x+i, y+i, size+i);
 printf("x:%d y:%d size:%d\n", x[i], y[i], size[i]);

 delete[] graydata;
 delete bi;

I noticed in the first “for loop” they convert a color image into a gray-scale image. We can cut that piece of code out since PIL has a method for that. im.convert(“L”)

My Version is a little beefed up though. I use a webcam to grab the images and display them with pygame. This way its in realtime instead of supplying an image as a command line argument. Below is a saved image from my version, I would have used print screen to grab it while viewing my webcam, but its hard to hold a picture + fn + prt sc

test photo for fdlib

The little blond one in the photograph is me at like 5 or so.

Note: This code is windows specific.


from VideoCapture import Device
from ctypes import *
import Image, ImageDraw, os, time, pygame, sys
from pygame.locals import *
from psyco import full

fd = cdll.LoadLibrary("fdlib.dll")

cam = Device()
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption('Facial Recognition')
font = pygame.font.SysFont("Curier",26)

pixX = 0
pixY = 0
pixList = []

w = c_int(640)
h = c_int(480)
threshold = c_int(0)#raise this number for more accuracy

x = c_int * 256
y = c_int * 256
size = c_int * 256
x = x()
y = y()
size = size()

graydata = c_ubyte * (640*480)
graydata = graydata()
fps = 25.0
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    im = cam.getImage()
    draw = ImageDraw.Draw(im)
    img = im.convert("L") #convert to grayscale
    imd = list(img.getdata()) #graydata needed
    cnt = 0
    pixX = 0
    pixY = 0
    cnt = 0

    for pix in imd: #Convert python data types to ctypes
        graydata[cnt] = imd[cnt]

    fd.fdlib_detectfaces(byref(graydata), w, h, threshold)
    n = fd.fdlib_getndetections() #number of faces
    i = 0
    while i < n:
        fd.fdlib_getdetection(c_int(i), x, y, size)
        bBoxTres = size[0]/2
        draw.rectangle([(x[0]+bBoxTres,y[0]+bBoxTres),(x[0]-bBoxTres,y[0]-bBoxTres)], outline=224)
        #This is how I saved the image you see above. Cut this "if statement" out
        #if you don't want it saving an image every time it see's 5 faces
        if n >= 5:
        #This i += 1 is not part of the "if statement" above
        i += 1

    faceNumber = font.render('Number of Faces: '+str(n), True, (46,224,1))
    imn = pygame.image.frombuffer(im.tostring(), (640,480), "RGB")
    screen.blit(imn, (0,0))
    pygame.time.delay(int(1000 * 1.0/fps))

About Tech B.

I am currently employed as a tech support rep for Frontier DSL internet and Dail-Up service. If you live on the East Coast and have Frontier or the old Verizon, you may have spoken with me at one point. I do side jobs programming and building things for people. I know Python better than any language in my toolbox. I can also develop Android Apps, which are Java based. Other languages include C , VB/VB.NET, some C#, PBASIC, Batch, Javascript, and some PHP. I love microcontrollers and interfacing with the outside world. I am currently working with Arduinos, which are amazing. Also I can work with the Basic Stamp family of microcontrollers; future development includes FPGA and embedded Linux. I was going to school, but have financial issues at the moment that are keeping me from the books. I plan on going back in the next couple semesters and finishing up my Associates in IT, then perusing a BS in computer science.
This entry was posted in Programming Python and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s