您的位置:首页 > 移动开发 > Android开发

Android FaceDetector实现人脸检测,人脸追踪(框出人脸)(MVP模式)

2017-08-02 19:19 579 查看
一 主要流程:

1.通过FaceDetector类来检测人脸,返回获取到的人脸信息,以及人脸的坐标,通过人脸坐标可以做人脸追踪的操作。

2.通过两个surfaceview,一个surfaceview用来做相机的预览,另外一个surfaceview附着在相机预览surfaceview上面,用来绘制人脸的相框。

demo 链接http://download.csdn.net/download/a289973483/10108205

二 核心代码:

1.人脸检测类的使用

import android.graphics.Bitmap;
import android.media.FaceDetector;

import com.skyee.medicalrobot.common.Config;
import com.skyee.medicalrobot.recognitionface.view.CameraView;

/**
* Created by qiandu on 2017/7/4.
*/

public class FaceCheckManager {
private FaceDetector mFaceDetector;
private FaceDetector.Face[] mFace = new FaceDetector.Face[Config.FACE_MAX_NUM];
private FaceCheckManager(Bitmap bitmap){
mFaceDetector = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), Config.FACE_MAX_NUM);
}
public static class Builder{
private CameraView mCmView;
private Bitmap mBitmap;
public Builder setImgData(Bitmap image){
this.mBitmap = image;
return this;
}
public Builder setCmView(CameraView mCmView){
this.mCmView = mCmView;
return this;
}
public FaceCheckManager create(){
return new FaceCheckManager(mBitmap);
}

}
public void findFace(final FaceCheckCallback faceCallback,Bitmap bitmap){
if(bitmap == null){
faceCallback.onError("mBitmap == null");
return;
}
//Bitmap.Config.RGB_565 这句很重要,可以提高检测率







Bitmap mBitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
final int faceResult = mFaceDetector.findFaces(mBitmap, mFace);
faceCallback.onResult(faceResult, mFace, mBitmap); bitmap.recycle(); }}


2.绘制人脸相框

/**
* 开始预览
*/
public void takePreview() {
// Logger.v("takePreview");
if(mCamera != null){
if(isPreviewing){
mCamera.stopPreview();
return;
}
parameters = mCamera.getParameters();
parameters.setFlashMode("off"); // 无闪光灯
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setPreviewFormat(ImageFormat.NV21);
//mCamera.setDisplayOrientation(90);

CamParaUtil.getInstance().printSupportPictureSize(parameters);
CamParaUtil.getInstance().printSupportPreviewSize(parameters);
Camera.Size pictureSize = CamParaUtil.getInstance().getPropPictureSize(
parameters.getSupportedPictureSizes(), previewRate, 800);
parameters.setPictureSize(pictureSize.width, pictureSize.height);
Camera.Size previewSize = CamParaUtil.getInstance().getPropPreviewSize(
parameters.getSupportedPreviewSizes(), previewRate
, 800);
//这里的 pictureSize 和 PreviewSize很重要,  一般平板采用上面的CamParaUtil可以获取到默认支持最低的分辨率。偶尔也会出现分辨率不正确的情况,建议采用
自己打印出来看看系统支持的分辨率,然后根据需要,选择相应的分辨率
parameters.setPictureSize(pictureSize.width, pictureSize.height);
parameters.setPreviewSize(previewSize.width, previewSize.height);
mCamera.setParameters(parameters);
//Logger.v("setPreviewCallback前" + pictureSize.width + "//" + pictureSize.height + " oo "+ previewSize.width + "//" + previewSize.height);
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
// Logger.v("setPreviewCallback");
Camera.Size size = camera.getParameters().getPreviewSize();
YuvImage image = new YuvImage(bytes, ImageFormat.NV21, size.width, size.height, null);
if(bytes != null){
ByteArrayOutputStream out = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, size.width, size.height), 50, out);
byte[] datas = out.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap mBitmap = BitmapFactory.decodeByteArray(datas, 0, datas.length, options);
long l = System.nanoTime();
//FileUtil.saveBitmap("cccc/"+l+"ee.png", mBitmap);
Matrix matrix = new Matrix();
//matrix.postRotate((float)90);
matrix.postScale(0.4f, 0.3125f); //照片的大小使 1280*960 屏幕的大小使 1024*600 这里需要注意换算比例
// Logger.v("MyCameraManager faceCheckFlag");
//synchronized (this) {
//Logger.v("MyCameraManager synchronized");
//if(faceCheckFlag){
//setFaceCheckFlag(false);
//Logger.v("MyCameraManager synchronized" + errornum + mBitmap.getWidth() + "dd " + mBitmap.getHeight());
Bitmap bitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);
FaceCheckManager faceCheckManager = new FaceCheckManager.Builder().setCmView(mCameraView).setImgData(bitmap).create();
faceCheckManager.findFace(MyCameraManager.this, bitmap);
//}
// }
mBitmap.recycle();
}
}
});
// Logger.v("setPreviewCallback后");
mCamera.startPreview();
isPreviewing = true;
}
}
@Override
public void onResult(int faceNum, final FaceDetector.Face[] faceData, final Bitmap bitmap) {
//Logger.v("MyCameraManager 发现了几个脸" +faceNum);
if(faceNum <= 0){
errornum ++;
if(errornum>2){
clear();
errornum = 0;
}
setFaceCheckFlag(true);
return;
}
if(befmSurfaceHolder != null ){//&& threadNum < 6)
//锁定整个SurfaceView
/* new Thread(){
@Override
public void run() {
super.run();*/
// threadNum ++;
Canvas mCanvas = befmSurfaceHolder.lockCanvas();

4000
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
for(FaceDetector.Face face : faceData){
if (face == null) {
break;
}
errornum = 0;
//mCanvas.drawBitmap(MainApplication.mRotaBitmap, 0, 0 ,paint);
PointF pointF = new PointF();
face.getMidPoint(pointF);
float eyesDistance = face.eyesDistance();

//Logger.v("onResult"+ pointF.x + "_" + pointF.y);
mCanvas.drawRect(new Rect((int)(pointF.x - eyesDistance)*2,
(int)(pointF.y- eyesDistance)*2,
(int)(pointF.x + eyesDistance)*2,
(int)(pointF.y + eyesDistance)*2),paint);//绘制矩形
}
befmSurfaceHolder.unlockCanvasAndPost(mCanvas);
// threadNum --;
//mCameraView.onDetectFace(bitmap);
}

//}.start();

//}
}

</pre


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息