Home » Android » Android Core » Android Detect Face

About Francesco Azzola

I'm a senior software engineer with more than 15 yrs old experience in JEE architecture. I'm SCEA certified (Sun Certified Enterprise Architect), SCWCD, SCJP. I'm an android enthusiast and i've worked for long time in the mobile development field.

Android Detect Face

In this post I want to describe how to detect faces in an image using Android. I will use the camera to get the picture and then the app will draws some rectangle around the faces detected in the image. To do it we simply use the Android API like:

  • FaceDetector used to detect face in the bitmap
  • Face  object that contains information about face detected

So we have to make three steps in our apps:

  • Take the picture
  • Detect faces in the picture
  • Draws the rectangles around the faces detected

Android Emulated camera[4]

Take the picture with camera using Android

This step is quite simple because we have simply to invoke an intent and get ready to receive the result. The Intent is very simple:

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_RETURN_CODE);

To retrieve the result (the picture taken) we have to override a method in our activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAMERA_RETURN_CODE) {
        Bitmap cameraBmp = (Bitmap) data.getExtras().get("data");        
    }
}

At line 4 we retrieve our picture using extra with data key.

Detect faces in the picture

At this point, we use the API shipped with Android SDK since level 1. To implement our logic we create a custom component that extends
ImageView, we call it FaceImageView.

public class FaceImageView extends ImageView {
...
}

To detect the faces, we have first convert the image in Bitmap in 556 format otherwise we can’t use the image as stated in API, so we have:

Bitmap tmpBmp = image.copy(Config.RGB_565, true);

Now we have our image in the right format, we create an instance of the FaceDetector:

FaceDetector faceDet = new FaceDetector(tmpBmp.getWidth(), tmpBmp.getHeight(), MAX_FACES);

passing the image width and image height and the number of faces we want to detect (in our case it is simple constant). Now we invoke the findFaces method to detect the faces, as a result we expect an array of Face instance that must have the length equals to the number of faces we want to detect:

faceDet.findFaces(tmpBmp, faceList);

where faceList is our array.

Now we have to analyze each item in our array and get the result. We simply want to get the face midpoint and the eyes distance. We use these two information to draw the rectangle for each face detected:

for (int i=0; i < faceList.length; i++) {
    Face face = faceList[i];
    Log.d("FaceDet", "Face ["+face+"]");
    if (face != null) {
        Log.d("FaceDet", "Face ["+i+"] - Confidence ["+face.confidence()+"]");
        PointF pf = new PointF();
        face.getMidPoint(pf);
        Log.d("FaceDet", "\t Eyes distance ["+face.eyesDistance()+"] - Face midpoint ["+pf+"]");
        RectF r = new RectF();
        r.left = pf.x - face.eyesDistance() / 2;
        r.right = pf.x + face.eyesDistance() / 2;
        r.top = pf.y - face.eyesDistance() / 2;
        r.bottom = pf.y + face.eyesDistance() / 2;
        rects[i] = r;
    }
}

At line (9-13) we calculate the rectangle vertex and we store them in a RectF object. If we want to run the app we can use a real smartphone or avd configured in our dev environment. In this case be sure you have configured the camera to use:

Immagine2[4]

Running the example and looking at the log we have:Immagine[4]

We notice that the app detected one face while others are null because no more faces exist in the picture.

Draw rectangles around the faces detected

The last step is drawing rectangles around the faces detected. In this case we can use the information, retrieved before, in this way:

@Override
protected void onDraw(Canvas canvas) {        
    super.onDraw(canvas);
    Paint p = new Paint();

    canvas.drawBitmap(image, 0, 0, p);
    Paint rectPaint = new Paint();
    rectPaint.setStrokeWidth(2);
    rectPaint.setColor(Color.BLUE);
    rectPaint.setStyle(Style.STROKE);

    for (int i=0; i < MAX_FACES; i++) {
        RectF r = rects[i];
        if (r != null)
            canvas.drawRect(r, rectPaint);
    }
}
  • Source code available @ github

 

Reference: Android Detect Face from our JCG partner Francesco Azzola at the Surviving w/ Android blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

One comment

  1. hi i am new to android ,, my project is that to detect face and crop it… how wil i implement it to crop thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*


7 + seven =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Want to take your Java Skills to the next level?
Grab our programming books for FREE!
  • Save time by leveraging our field-tested solutions to common problems.
  • The books cover a wide range of topics, from JPA and JUnit, to JMeter and Android.
  • Each book comes as a standalone guide (with source code provided), so that you use it as reference.
Last Step ...

Where should we send the free eBooks?

Good Work!
To download the books, please verify your email address by following the instructions found on the email we just sent you.