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

来源:互联网 发布:淘宝客源码自动采集 编辑:程序博客网 时间:2024/06/05 16:06

一 主要流程:

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();                            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
 
原创粉丝点击