Android + Face Detection + Cropping faces to List View
Hi Friends,
Face detection with Android may not be such a huge task after all. You can take the help of below link for detecting faces from any given image.
Face detection with Android may not be such a huge task after all. You can take the help of below link for detecting faces from any given image.
The above site provides a very good way of identifying faces for any given image.
However, having detected the faces, how can you crop and extract the faces to a Array/ArrayList which could aid selecting a particular face for processing further.
Kindly download the apk from the following link.
Kindly download the source code for this project from the following link.
Pre-Requirements
1. Eclipse with android SDK (As for the technical requirements)
2. Good understanding and knowledge of basics of Android and Java.
Running through the link will bring forward the below application flow:
Camera Activity
I would not be diving deep into the camera part concerning the application. You can get more details on camera class from my other blog concerning various types of camera in android.
However, whats important to take over from the CameraActivity.java are the below lines of code. Having received the image byte array, compress the same (by converting it to bitmap) and transfer the byte array to next activity where the actual face detection magic happens.
Detect Faces
And this is the activity where all the magic happens. Having received the image, the image is converted back to bitmap and sent to detectFaces() function. I request you to kindly run through the detectFaces function. The comments provided should be self explanatory.
detectFaces() function holds two important responsibilities:
1. Draw rectangles around the detected faces
2. Crop the detected faces and stack them into a ArrayList<Bitmap>
Display Detected Faces
The sent ArrayList<Bitmap> is received in the DisplayDetectedFaces.java activity and displayed.
Now what you intend to do with the received face bitmap is completely left you. One of the most appropriate use of the same would be to use the face for processing a face recognition algorithm and hence recognize the face.
Kindly download the apk from the following link.
Kindly download the source code for this project from the following link.
Pre-Requirements
1. Eclipse with android SDK (As for the technical requirements)
2. Good understanding and knowledge of basics of Android and Java.
Running through the link will bring forward the below application flow:
Camera View -> Display captured image with detected faces -> List View of Detected Faces
Details of the application
Starting the app launches the camera activity, which has been built using CameraActivity.java and Preview.Java classes. Camera Activity
I would not be diving deep into the camera part concerning the application. You can get more details on camera class from my other blog concerning various types of camera in android.
However, whats important to take over from the CameraActivity.java are the below lines of code. Having received the image byte array, compress the same (by converting it to bitmap) and transfer the byte array to next activity where the actual face detection magic happens.
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
//Convert image from byte[] to bitmap
Bitmap imageBitmap = BitmapFactory
.decodeByteArray(data, 0, data.length);
//Downscale and compress the image bitmap
imageBitmap = scaleDownBitmap(imageBitmap, 240, this);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
//Convert back the image from bitmap to byte[]
byte[] byteArray = stream.toByteArray();
mCamera.startPreview();
m_Progress.EndDialog();
//Send the image byte[] to next activity
Intent resultsActivity = new Intent(CameraActivity.this,
DetectFaces.class);
resultsActivity.putExtra("ImageByteArray", byteArray);
startActivity(resultsActivity);
}
Detect Faces
And this is the activity where all the magic happens. Having received the image, the image is converted back to bitmap and sent to detectFaces() function. I request you to kindly run through the detectFaces function. The comments provided should be self explanatory.
detectFaces() function holds two important responsibilities:
1. Draw rectangles around the detected faces
2. Crop the detected faces and stack them into a ArrayList<Bitmap>
private void detectFaces() {
if (null != imageBitmap) {
int width = imageBitmap.getWidth();
int height = imageBitmap.getHeight();
// Call face detector object
FaceDetector detector = new FaceDetector(width, height,
DetectFaces.MAX_FACES);
Face[] faces = new Face[DetectFaces.MAX_FACES];
Bitmap bitmap565 = Bitmap.createBitmap(width, height,
Config.RGB_565);
Paint ditherPaint = new Paint();
Paint drawPaint = new Paint();
// Set properties of the rectangle that should appear for a detected
// face
ditherPaint.setDither(true);
drawPaint.setColor(Color.GREEN);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeWidth(3);
// Create a canvas and draw the imagebitmap over the canvas
Canvas canvas = new Canvas();
canvas.setBitmap(bitmap565);
canvas.drawBitmap(imageBitmap, 0, 0, ditherPaint);
// trigger the face detector function and store the number of faces
// detected as int paramter faceFound
facesFound = detector.findFaces(bitmap565, faces);
// This parameters find the midpoint, eyeDistance and confidence in
// a face
PointF midPoint = new PointF();
float eyeDistance = 0.0f;
float confidence = 0.0f;
Log.i("FaceDetector", "Number of faces found: " + facesFound);
if (facesFound > 0) {
// Select detected faces, one after one
for (int index = 0; index < facesFound; ++index) {
// Get mid point, eye distance and confidence of the face
faces[index].getMidPoint(midPoint);
eyeDistance = faces[index].eyesDistance();
confidence = faces[index].confidence();
Log.i("FaceDetector", "Confidence: " + confidence
+ ", Eye distance: " + eyeDistance
+ ", Mid Point: (" + midPoint.x + ", " + midPoint.y
+ ")");
try {
// Draw a rectange depending upon face parameters.
// Kindly note that this is just for displaying the
// rectangle
canvas.drawRect((float) midPoint.x - (eyeDistance * 2),
(float) midPoint.y - (eyeDistance * 2),
(int) midPoint.x + (eyeDistance * 2),
(int) midPoint.y + (eyeDistance * 2), drawPaint);
// And this is for cropping the detected face from the
// image
Bitmap croppedBitmap = Bitmap.createBitmap(imageBitmap,
(int) (midPoint.x - (eyeDistance * 2)),
(int) (midPoint.y - (eyeDistance * 2)),
(int) (eyeDistance * 4),
(int) (eyeDistance * 4));
extractedFaces.add(croppedBitmap);
imageDimensions.add(midPoint.x + "," + midPoint.y + ","
+ (eyeDistance * 2) + "," + (eyeDistance * 3)
+ "," + "IMGPNG");
} catch (Exception e) {
/*
* Toast.makeText( getApplicationContext(),
* "Too many faces/face size is too small, kindly go back and try again..."
* , Toast.LENGTH_SHORT).show();
*/
}
}
}
Log.i("Number of Faces detected", extractedFaces.size() + "");
String filepath = Environment.getExternalStorageDirectory()
+ "/facedetect" + System.currentTimeMillis() + ".jpg";
try {
FileOutputStream fos = new FileOutputStream(filepath);
bitmap565.compress(CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ImageView imageView = (ImageView) findViewById(R.id.ivCapturedImage);
// Set the image view in this activity with the detected faces
// bitmap
imageView.setImageBitmap(bitmap565);
}
}
Display Detected Faces
The sent ArrayList<Bitmap> is received in the DisplayDetectedFaces.java activity and displayed.
Now what you intend to do with the received face bitmap is completely left you. One of the most appropriate use of the same would be to use the face for processing a face recognition algorithm and hence recognize the face.

Comments
Post a Comment