标签:facedetect 人脸识别 人脸检测 face++
Android SDK从1.0版本中(API level 1)就已经集成了简单的人脸识别功能,通过调用FaceDetector 我们可以在Android平台上实现Bitmap多人脸识别(一张图中可以有多个人脸)。它查找人脸的原理是:找眼睛。它返回的人脸数据face,通过调用public float eyesDistance (),public void getMidPoint (PointF point),我们可以得到探测到的两眼间距,以及两眼中心点位置(MidPoint)。public float confidence () 可以返回该人脸数据的可信度(0~1),这个值越大,该人脸数据的准确度也就越高。
流程
1. 读取一张图片至Bitmap (从Resource中,或是从手机相册中选取)
2. 使用FaceDetector API分析Bitmap,将探测到的人脸数据以FaceDetector.Face存储在一个Face list中;
3.将人脸框显示在图片上。
源码
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp" >
<Button
android:id="@+id/btn_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="选择图片" />
<Button
android:id="@+id/btn_detect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="检测人脸" />
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="5dp" />
</LinearLayout>
MainActivity.java
package com.example.faceandroidtest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
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.media.FaceDetector;
import android.media.FaceDetector.Face;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private static final int REQUEST_CODE_SELECT_PIC = 120;
private static final int MAX_FACE_NUM = 10;//最大可以检测出的人脸数量
private int realFaceNum = 0;//实际检测出的人脸数量
private Button selectBtn;
private Button detectBtn;
private ImageView image;
private ProgressDialog pd;
private Bitmap bm;//选择的图片的Bitmap对象
private Paint paint;//画人脸区域用到的Paint
private boolean hasDetected = false;//标记是否检测到人脸
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);//设置话出的是空心方框而不是实心方块
pd = new ProgressDialog(this);
pd.setTitle("提示");
pd.setMessage("正在检测,请稍等");
}
/**
* 控件初始化
*/
private void initView(){
selectBtn = (Button) findViewById(R.id.btn_select);
selectBtn.setOnClickListener(this);
detectBtn = (Button) findViewById(R.id.btn_detect);
detectBtn.setOnClickListener(this);
image = (ImageView) findViewById(R.id.image);
}
/**
* 从图库选择图片
*/
private void selectPicture(){
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_SELECT_PIC);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE_SELECT_PIC && resultCode == Activity.RESULT_OK){
//获取选择的图片
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String selectedImagePath = cursor.getString(columnIndex);
bm = BitmapFactory.decodeFile(selectedImagePath);
//要使用Android内置的人脸识别,需要将Bitmap对象转为RGB_565格式,否则无法识别
bm = bm.copy(Bitmap.Config.RGB_565, true);
cursor.close();
image.setImageBitmap(bm);
hasDetected = false;
}
}
// private void selectPicture(){
// bm = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
// bm = bm.copy(Bitmap.Config.RGB_565, true);
// image.setImageBitmap(bm);
// hasDetected = false;
// }
/**
* 检测人脸
*/
private void detectFace(){
if(bm == null){
Toast.makeText(this, "请先选择图片", Toast.LENGTH_SHORT).show();
return ;
}
if(hasDetected){
Toast.makeText(this, "已检测出人脸", Toast.LENGTH_SHORT).show();
}else{
new FindFaceTask().execute();
}
}
private void drawFacesArea(FaceDetector.Face[] faces){
Toast.makeText(this, "图片中检测到" + realFaceNum + "张人脸", Toast.LENGTH_SHORT).show();
float eyesDistance = 0f;//两眼间距
Canvas canvas = new Canvas(bm);
for(int i = 0; i < faces.length; i++){
FaceDetector.Face face = faces[i];
if(face != null){
PointF pointF = new PointF();
face.getMidPoint(pointF);//获取人脸中心点
eyesDistance = face.eyesDistance();//获取人脸两眼的间距
//画出人脸的区域
canvas.drawRect(pointF.x - eyesDistance, pointF.y - eyesDistance, pointF.x + eyesDistance, pointF.y + eyesDistance, paint);
hasDetected = true;
}
}
//画出人脸区域后要刷新ImageView
image.invalidate();
}
/**
* 检测图像中的人脸需要一些时间,所以放到AsyncTask中去执行
* @author yubo
*
*/
private class FindFaceTask extends AsyncTask<Void, Void, FaceDetector.Face[]>{
@Override
protected void onPreExecute() {
super.onPreExecute();
pd.show();
}
@Override
protected Face[] doInBackground(Void... arg0) {
//最关键的就是下面三句代码
FaceDetector faceDetector = new FaceDetector(bm.getWidth(), bm.getHeight(), MAX_FACE_NUM);
FaceDetector.Face[] faces = new FaceDetector.Face[MAX_FACE_NUM];
realFaceNum = faceDetector.findFaces(bm, faces);
if(realFaceNum > 0){
return faces;
}
return null;
}
@Override
protected void onPostExecute(Face[] result) {
super.onPostExecute(result);
pd.dismiss();
if(result == null){
Toast.makeText(MainActivity.this, "抱歉,图片中未检测到人脸", Toast.LENGTH_SHORT).show();
}else{
drawFacesArea(result);
}
}
}
public void onClick(View arg0) {
switch(arg0.getId()){
case R.id.btn_select://选择图片
selectPicture();
break;
case R.id.btn_detect://检测人脸
detectFace();
break;
}
}
}
在源码中先将MAX_FACE_NUM最大可以检测出的人脸数量设为5。
private static final int MAX_FACE_NUM = 5;//最大可以检测出的人脸数量
检测结果
猜测应该是选取人群中识别率最高的5个人头像,因为最大可以检测出的人脸数量为5,所以只显示识别率最高的前5个人头像。
当将MAX_FACE_NUM最大可以检测出的人脸数量设为10。
private static final int MAX_FACE_NUM = 10;//最大可以检测出的人脸数量
同一张图片检测结果
参考引用
标签:facedetect 人脸识别 人脸检测 face++
原文地址:http://blog.csdn.net/wtyvhreal/article/details/46548403