| Author |
Message |
strongsauce Freshman

Joined: 03 Dec 2008 Posts: 5
|
Posted: Fri Dec 05, 2008 7:43 am Post subject: Quick and easy FaceDetector demo |
|
|
Using Android's FaceDetector
Tutorial: Simple implementation of the Android SDK's FaceDetector and FaceDetector.Face classes.
First a few things about the FaceDetector class.
- According to the documentation, Bitmaps need to use the RGB565 format. However it seems to work with bitmaps using the default constructors for that class but I used mode RGB565 just in case.
- Seems that the class uses eyes as the "facial detection" this means there is no other detail (face dimensions, mouth location, etc.) and faces that are taken from the side will not be detected. Sunglasses/glasses seem to interfere with detection.
- The bigger the image the easier it can detect images. However there is a limit to how big of an image you can load into Android's memory. The images I used were all under 1000x1000 but at least 400x300.
- Regardless of how many faces you specify in the FaceDetector constructor, it seems that it takes the same amount of time, i.e. if there are only 5 faces in the image you won't be penalized for asking for 10.
- The FaceDetector.Face class cannot be extended, all its constructors are privatized, which means you cannot change the Face class's CONFIDENCE_THRESHOLD.
- Maximum number of faces you can ask for is 64 after that it won't bother loading the face detection.
- pose() in class FaceDetector.Face does not seem to do anything.
To make it as simple as possible, I only created 2 classes for this tutorial. You will also need to add an image into your res/drawable folder to use as a test image.
/src/package_name/FaceTest.java
| Java: |
package com.jrr.facetest;
import android.app.Activity;
import android.os.Bundle;
public class FaceTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FaceView faceView = new FaceView(this);
setContentView(faceView);
}
}
|
/src/package_name/FaceView.java
Note you must change R.drawable.bao102 with the actual resource image you use.
| Java: |
package com.jrr.facetest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.FaceDetector;
import android.util.Log;
import android.view.View;
public class FaceView extends View {
private static final int NUM_FACES = 10; // max is 64
private static final boolean DEBUG = true;
private FaceDetector arrayFaces;
private FaceDetector.Face getAllFaces[] = new FaceDetector.Face[NUM_FACES];
private FaceDetector.Face getFace = null;
private PointF eyesMidPts[] = new PointF[NUM_FACES];
private float eyesDistance[] = new float[NUM_FACES];
private Bitmap sourceImage;
private Paint tmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pOuterBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint pInnerBullsEye = new Paint(Paint.ANTI_ALIAS_FLAG);
private int picWidth, picHeight;
private float xRatio, yRatio;
public FaceView(Context context) {
super(context);
pInnerBullsEye.setStyle(Paint.Style.FILL);
pInnerBullsEye.setColor(Color.RED);
pOuterBullsEye.setStyle(Paint.Style.STROKE);
pOuterBullsEye.setColor(Color.RED);
tmpPaint.setStyle(Paint.Style.STROKE);
tmpPaint.setTextAlign(Paint.Align.CENTER);
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inPreferredConfig = Bitmap.Config.RGB_565;
sourceImage = BitmapFactory.decodeResource( getResources() ,R.drawable.bao102, bfo);
picWidth = sourceImage.getWidth();
picHeight = sourceImage.getHeight();
arrayFaces = new FaceDetector( picWidth, picHeight, NUM_FACES );
arrayFaces.findFaces(sourceImage, getAllFaces);
for (int i = 0; i < getAllFaces.length; i++)
{
getFace = getAllFaces[i];
try {
PointF eyesMP = new PointF();
getFace.getMidPoint(eyesMP);
eyesDistance[i] = getFace.eyesDistance();
eyesMidPts[i] = eyesMP;
if (DEBUG)
{
Log.i("Face",
i + " " + getFace.confidence() + " " + getFace.eyesDistance() + " "
+ "Pose: ("+ getFace.pose(FaceDetector.Face.EULER_X) + ","
+ getFace.pose(FaceDetector.Face.EULER_Y) + ","
+ getFace.pose(FaceDetector.Face.EULER_Z) + ")"
+ "Eyes Midpoint: ("+eyesMidPts[i].x + "," + eyesMidPts[i].y +")"
);
}
}
catch (Exception e)
{
if (DEBUG) Log.e("Face", i + " is null");
}
}
}
@Override
protected void onDraw(Canvas canvas)
{
xRatio = getWidth()*1.0f / picWidth;
yRatio = getHeight()*1.0f / picHeight;
canvas.drawBitmap( sourceImage, null , new Rect(0,0,getWidth(),getHeight()),tmpPaint);
for (int i = 0; i < eyesMidPts.length; i++)
{
if (eyesMidPts[i] != null)
{
pOuterBullsEye.setStrokeWidth(eyesDistance[i] /6);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 2 , pOuterBullsEye);
canvas.drawCircle(eyesMidPts[i].x*xRatio, eyesMidPts[i].y*yRatio, eyesDistance[i] / 6 , pInnerBullsEye);
}
}
}
}
|
| Description: |
|
| Filesize: |
35.58 KB |
| Viewed: |
9074 Time(s) |

|
|
|
| Back to top |
|
 |
|
|
 |
Houseonfire Freshman

Joined: 05 Dec 2008 Posts: 3
|
Posted: Fri Dec 05, 2008 8:49 am Post subject: |
|
|
This is very interesting.
I was wondering if you could comment in your code the part that actually identifies the face.
Thank you for this script.
|
|
| Back to top |
|
 |
liaowg Junior Developer

Joined: 03 Jun 2008 Posts: 12
|
Posted: Thu Feb 05, 2009 10:02 am Post subject: |
|
|
| It seems the neven vision detection is very poor, I try 4 pictures, only one succeed
|
|
| Back to top |
|
 |
Craigo Junior Developer

Joined: 17 Mar 2009 Posts: 10 Location: Sydney, Australia
|
Posted: Tue Mar 17, 2009 3:53 am Post subject: |
|
|
| Houseonfire wrote: | This is very interesting.
I was wondering if you could comment in your code the part that actually identifies the face.
Thank you for this script. |
The line of code is: arrayFaces.findFaces(sourceImage, getAllFaces);
The calls to pose(FaceDetector.Face.EULER_X,Y,Z) always return 0 for me. Anyone ever get values for these?
|
|
| Back to top |
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Wed Mar 18, 2009 8:19 am Post subject: unable to get the red mark |
|
|
Hi,
I tried but some problem please help.
I am able to get the picture displayed but detection is not happening. I am using the same code posted in the article and my xml file is as follows:
main.xml
| XML: | <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ImageView android:id="@+id/image"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_width="200.0sp"
android:layout_height="300.0sp"
android:src="@drawable/image"
android:layout_x="70.0sp"
android:layout_y="130.0sp">
</ImageView>
</LinearLayout> |
And also the adb logcat out put is as follows:
| Code: | I/jdwp ( 455): received file descriptor 24 from ADB
I/ActivityManager( 46): Starting activity: Intent { flags=0x10000000 comp={com.android.facegetapp/com.android.facegetapp.facegetapp} }
D/AndroidRuntime( 455): Shutting down VM
D/dalvikvm( 455): DestroyJavaVM waiting for non-daemon threads to exit
I/dalvikvm( 455): DestroyJavaVM shutting VM down
D/dalvikvm( 455): HeapWorker thread shutting down
D/dalvikvm( 455): HeapWorker thread has shut down
D/jdwp ( 455): JDWP shutting down net...
D/jdwp ( 455): +++ peer disconnected
I/dalvikvm( 455): Debugger has detached; object registry had 1 entries
D/dalvikvm( 455): VM cleaning up
E/dalvikvm( 455): pthread_setspecific failed, err=22
I/ActivityManager( 46): Start proc com.android.facegetapp for activity com.android.facegetapp/.facegetapp: pid=464 uid=10029 gids={}
D/dalvikvm( 455): LinearAlloc 0x0 used 541284 of 4194304 (12%)
I/jdwp ( 464): received file descriptor 10 from ADB
D/dalvikvm( 464): GC freed 512 objects / 34504 bytes in 85ms
D/dalvikvm( 464): Trying to load lib /system/lib/libFFTEm.so 0x0
D/dalvikvm( 464): Added shared lib /system/lib/libFFTEm.so 0x0
E/Face ( 464): 0 is null
E/Face ( 464): 1 is null
I/ActivityManager( 46): Displayed activity com.android.facegetapp/.facegetapp: 1214 ms
D/dalvikvm( 90): GC freed 1719 objects / 92536 bytes in 82ms
D/GpsLocationProvider( 46): NetworkThread out of wake loop
D/GpsLocationProvider( 46): Requesting time from NTP server pool.ntp.org
D/SntpClient( 46): request time failed: java.net.SocketTimeoutException: The operation timed out
D/GpsLocationProvider( 46): requestTime failed
D/GpsLocationProvider( 46): NetworkThread wait for 300000ms |
Please advice me where i am wrong or anything missing in xml file ?
|
|
| Back to top |
|
 |
Craigo Junior Developer

Joined: 17 Mar 2009 Posts: 10 Location: Sydney, Australia
|
Posted: Wed Mar 18, 2009 9:18 am Post subject: Re: unable to get the red mark |
|
|
| shyjumon.n wrote: | | ...or anything missing in xml file ? |
I didn't bother with changing the xml file. I just stuck the view straight onto the Activity ContentView:
setContentView(new FaceView(this)).
Worked great, got about 90% of the faces. However, the pose(FaceDetector.Face.EULER_...) always returns 0 for me?
|
|
| Back to top |
|
 |
|
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Wed Mar 18, 2009 10:32 am Post subject: |
|
|
Thank you.
xml is not important.
For me call to getFace = getAllFaces[i]; are success in all cases. but "getFace.getMidPoint(eyesMP);" fails ( java.lang.NullPointerException). and the following is my debug prints.
E/Face: ( 231): exception thrown
E/Face ( 231): 0 is null
E/Face: ( 231): exception thrown
E/Face ( 231): 1 is null
E/Face: ( 231): exception thrown
E/Face ( 231): 2 is null
Are you guys able to succeed ? I tried 10-15 different resolution images.
|
|
| Back to top |
|
 |
Craigo Junior Developer

Joined: 17 Mar 2009 Posts: 10 Location: Sydney, Australia
|
Posted: Wed Mar 18, 2009 10:39 am Post subject: |
|
|
| shyjumon.n wrote: | Thank you.
For me call to getFace = getAllFaces[i]; are success in all cases. but "getFace.getMidPoint(eyesMP);" fails ( java.lang.NullPointerException). and the following is my debug prints.
|
Sorry, the (somewhat obvious) thing I can suggest is debugging into the Face object to see if you can see all it's values. It works great for me. I'm using android-sdk-windows-1.1_r1.
|
|
| Back to top |
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Wed Mar 18, 2009 10:55 am Post subject: |
|
|
>> Sorry, the (somewhat obvious) thing I can suggest is debugging into the Face object to see if you can see all it's values. It works great for me. I'm using android-sdk-windows-1.1_r1.
Thank you for the reply.
Could you please be able to share the diff of the code (if any) or the image which succeeded for you ?
I am using the same SDK's Linux version.
Thank you.
|
|
| Back to top |
|
 |
Craigo Junior Developer

Joined: 17 Mar 2009 Posts: 10 Location: Sydney, Australia
|
Posted: Wed Mar 18, 2009 10:59 am Post subject: |
|
|
| shyjumon.n wrote: |
Could you please be able to share the diff of the code (if any) or the image which succeeded for you ?
I am using the same SDK's Linux version.
Thank you. |
Sorry, my code is now very different as I have been playing around with it. You should be able to inspect the values in the Face object to verify the face detection worked correctly.
|
|
| Back to top |
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Wed Mar 18, 2009 11:03 am Post subject: |
|
|
| Thank you. Let me do some debug and will be back with some good news. Once again thanks for the support.
|
|
| Back to top |
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Wed Mar 25, 2009 8:13 am Post subject: |
|
|
Thanks a lot for the support. I could able to succeed in the example. The problem was with my test images. Converted formats are not accepting but the raw jpg files are accepted.
special thanks to Craigo
|
|
| Back to top |
|
 |
chandrasekhar.m Once Poster

Joined: 07 Apr 2009 Posts: 1
|
Posted: Tue Apr 07, 2009 10:51 am Post subject: Re: Quick and easy FaceDetector demo |
|
|
Kudos....It works !!....cool application
_________________ ^^
C. |
|
| Back to top |
|
 |
shyjumon.n Freshman

Joined: 18 Mar 2009 Posts: 9
|
Posted: Sat Apr 25, 2009 8:07 pm Post subject: |
|
|
How can i add a button to the FaceView and upon clicking the button, i would like to load a layout which is there in layout1.xml ????
any idea....
Also how can i put this FaceView to an Imageview which is there in my main.xml...
Please help if you have clues ....
Thank you.
|
|
| Back to top |
|
 |
nbadal Junior Developer

Joined: 26 May 2009 Posts: 23
|
Posted: Tue May 26, 2009 4:07 pm Post subject: |
|
|
| Very cool! It worked on an old family photo of mine perfectly
|
|
| Back to top |
|
 |
|