Thursday, 25 October 2012

Android face detector demo

First things first, this is not about using the android api to detect a face, it's about some code i've been experimenting with over the last few months.

I decided to just upload the skeleton demo application i've been using for testing the detector on Android. It might give me the impetus to spend some more time on it.

I've put the package on google code in the MediaZ project as DetectNEON-0.apk (for want of somewhere better to put it). Note that there is no public source for it at the moment.

Update: I was a bit too lazy and only implemented code for a front-facing camera. I just uploaded another package DetectNEON-1.apk which might fix it, or just break it for everything.

The app has an inconveniently placed slider that lets one adjust the matching threshold, which may be required under different lighting conditions or due to the qualities of the camera sensor. One can also switch between android's 'built in' face detector and mine with the buttons at the top. The aspect ratio of the video display is broken, but that isn't what i was trying to test here. It is also obviously only displaying the raw hits and not grouping them in any way.

On my ainol elf 2 tablet the detector takes around 45ms on a 640x480 input frame using the settings i've set: minimum object size detected is 51x51 pixels, up to about 400x400. The code is single-threaded and I was using 'normal' mode for the CPU scheduler.

For comparison the Android face detector API takes about 500-600ms, although it does search to a smaller size - which is a critical factor in execution time for sliding window algorithms.

It seems to work better than I remembered, but I think last time i tested it was late at night in a poorly lit room.

Update 2: Just a bit more info that is scattered over the blog.

  • The classifier is trained on very upright fully-front faces (the CBCL data set), so will not detect as wide a range of orientations as the typical OpenCV cascades.
  • Once the training set is loaded into memory, it takes about 40ms to train a 17x17 classifier with approximately 10K images using simple Java code (i7 something cpu).
  • Although there was a small amount of hand-tuning with the negative set, the training is deterministic and employs no reinforcement techniques such as boosting.
  • The classifier is a fixed size in relation to the window size. The 17x17 classifier is about 2.5k bytes in total.
  • There is no pre-processing of the input signal in this demo.
  • Hence it is fairly sensitive to noise and camera 'qualities', however it returns a probability rather than a binary result, so can be adjusted for sensitivity.
  • The NEON code classifies each single pixel in under 1 cpu cycle on a Cortex-A8 CPU.
  • I've done no statistical verification on how well it works, and i'm mostly just surprised it works at all.


johndrinkwater said...

Tried it on my Nexus 7. There seems to be a 1 - horz when projecting the face boundary as its always the opposite side of the video to my face and pans into centre when I am there. Can email screenshots if my explanation sucks.

NotZed said...

Hmm, not that i implemented anything to use it, the elf2 or the firmware on it is reporting that the camera is a back facing camera which is wrong.

I will upload another version which might fix it, or maybe just make it wrong on everything, i don't have any other device handy today to test with.