美文网首页
基于Camera实现人脸检测

基于Camera实现人脸检测

作者: 编程的猫 | 来源:发表于2020-03-18 18:12 被阅读0次

先看效果:


faceDetech.jpg

在原来Camera1的代码的基础上添加以下代码:
Camera1Helper中添加,追踪人脸信息:

   /**
     * 开启人脸检测
     */
    public void startFaceDetech() {
        if (mCamera != null) {
            mCamera.startFaceDetection();
            mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() {
                @Override
                public void onFaceDetection(Camera.Face[] faces, Camera camera) {
                    if (facesListener != null) {
                        if (faces != null && faces.length > 0)
                            facesListener.faces(transform(faces));
                        else
                            facesListener.clearFace();
                    }
                }
            });
        }
    }

  /**
     * 绘制矩形检测框
     */
    private ArrayList<RectF> transform(Camera.Face[] faces) {
        Matrix matrix = new Matrix();
        if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            matrix.setScale(-1, 1);
        } else {
            matrix.setScale(1, 1);
        }
        int width = surfaceView.getWidth();
        int height = surfaceView.getHeight();
        matrix.postRotate(mDisplayOrientation);
        matrix.postScale(width / 2000F, height / 2000F);
        matrix.postTranslate(width / 2F, height / 2F);
        ArrayList<RectF> rectFS = new ArrayList<>();
        for (Camera.Face face : faces) {
            RectF srcRectF = new RectF(face.rect);
            RectF descRectF = new RectF(0, 0, 0, 0);
            matrix.mapRect(descRectF, srcRectF);
            rectFS.add(descRectF);
        }
        return rectFS;
    }

在开启相机预览之后调用,开启人脸追踪:

  /**
     * 第四步:开启预览
     */
    private void startPreview() {
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            //设置预览时相机的旋转角度
            setCameraDisplayOrientation();
            mCamera.startPreview();
            //开启人脸检测
            startFaceDetech();
            isActivedPreview = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

自定义一个FaceView:

public class FaceView extends View {

    private static final String TAG = "FaceView";

    private ArrayList<RectF> faces;
    private Paint paint;

    public FaceView(Context context) {
        super(context);
        init(context);
    }

    public FaceView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public FaceView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化paint
     *
     * @param context context
     */
    private void init(Context context) {
        paint = new Paint();
        paint.setColor(Color.GREEN);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f,
                context.getResources().getDisplayMetrics()));
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        Log.i(TAG, "       draw");
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG, "       onDraw");
        if (faces != null && faces.size() > 0) {
            //因为会同时存在多张人脸,所以用循环
            for (RectF face : faces) {
                //绘制人脸所在位置的矩形
                Log.i(TAG, "绘制:" + face.top + "  " + face.bottom);
                canvas.drawRect(face, paint);
            }
        }
    }

    /**
     * 设置人脸信息,然后刷新FaceView
     *
     * @param mFace mFace
     */
    public void setFaces(ArrayList<RectF> mFace) {
        this.faces = mFace;
        postInvalidate();
    }

    public void clearRect() {
        if (faces != null && faces.size() > 0)
            faces.clear();
        postInvalidate();
    }
}

人脸信息回调:

public interface FacesListener {
    void faces(ArrayList<RectF> rectFS);
    void clearFace();
}

activity中调用

 @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        surfaceView = view.findViewById(R.id.surfaceView);
        switchCamera = view.findViewById(R.id.switchCamera);
        takePhoto = view.findViewById(R.id.takePhoto);
        faceView = view.findViewById(R.id.faceView);

        if (camera1Helper == null)
            camera1Helper = new Camera1Helper(Objects.requireNonNull(getActivity()), surfaceView);

        switchCamera.setOnClickListener(this);
        takePhoto.setOnClickListener(this);
        camera1Helper.setFacesListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.switchCamera) {
            faceView.clearRect();
            camera1Helper.switchCamera();
        } else if (v.getId() == R.id.takePhoto) {
            camera1Helper.takePhoto();
        }
    }

    @Override
    public void faces(ArrayList<RectF> rectFS) {
        faceView.setFaces(rectFS);
    }

    @Override
    public void clearFace() {
        faceView.clearRect();
    }

可参考这篇博文的注解:
Android: Camera相机开发详解(下) —— 实现人脸检测功能

相关文章

网友评论

      本文标题:基于Camera实现人脸检测

      本文链接:https://www.haomeiwen.com/subject/owucyhtx.html