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"); exit(0); } bi = new BMPImg(); printf("\nloading %s\n", argv[1]); bi->Load(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); else 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
The little blond one in the photograph is me at like 5 or so.
Note: This code is windows specific.
Requires:
- PIL http://www.pythonware.com/products/pil/
- fdlib http://www.kyb.mpg.de/bs/people/kienzle/facedemo/facedemo.htm
- VideoCapture http://videocapture.sourceforge.net/
- pygame http://pygame.org/news.html
- psyco (optional) http://psyco.sourceforge.net/
from VideoCapture import Device from ctypes import * import Image, ImageDraw, os, time, pygame, sys from pygame.locals import * from psyco import full full() fd = cdll.LoadLibrary("fdlib.dll") #assignments cam = Device() pygame.init() 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] cnt+=1 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: im.save("5.jpg") #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)) screen.blit(faceNumber,(0,0)) pygame.display.flip() pygame.time.delay(int(1000 * 1.0/fps))