diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java index 94d0d79..1c6d7bf 100644 --- a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java +++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java @@ -5,8 +5,11 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; import android.hardware.Camera; import android.media.FaceDetector; +import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.TextView; @@ -16,6 +19,7 @@ import com.casic.birmm.hxrq.R; import com.casic.birmm.hxrq.base.BaseActivity; import com.casic.birmm.hxrq.utils.ImageHelper; +import com.casic.birmm.hxrq.widgets.FaceDetectView; import java.io.IOException; import java.util.List; @@ -28,6 +32,8 @@ private static final String TAG = "FacePreViewActivity"; @BindView(R.id.surfaceView) SurfaceView surfaceView; + @BindView(R.id.faceDetectView) + FaceDetectView faceDetectView; @BindView(R.id.faceTipsView) TextView faceTipsView; private SurfaceHolder mSurfaceHolder; @@ -70,6 +76,28 @@ } //开始预览 mCamera.startPreview(); + //人脸检测 + mCamera.startFaceDetection(); + mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() { + @Override + public void onFaceDetection(Camera.Face[] faces, Camera camera) { + if (faces.length > 0) { + Camera.Face face = faces[0]; + Rect rect = face.rect; + Log.d(TAG, "可信度:" + face.score + + " ,face detected: " + faces.length + + " ,X: " + rect.centerX() + + " ,Y: " + rect.centerY() + + " ,[" + rect.left + "," + rect.top + "," + rect.right + "," + rect.bottom + "]"); + Matrix matrix = updateFaceRect(); + faceDetectView.updateFace(matrix, faces); + faceTipsView.setText("已检测到人脸,识别中"); + faceTipsView.setTextColor(Color.GREEN); + } else { + faceDetectView.removeRect(); + } + } + }); } @Override @@ -85,6 +113,21 @@ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置 } + private Matrix updateFaceRect() { + Matrix matrix = new Matrix(); + Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); + // Need mirror for front camera. + boolean mirror = (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT); + matrix.setScale(mirror ? -1 : 1, 1); + // This is the value for android.hardware.Camera.setDisplayOrientation. + // 刚才我们设置了camera的旋转参数,所以这里也要设置一下 + matrix.postRotate(90); + // Camera driver coordinates range from (-1000, -1000) to (1000, 1000). + // UI coordinates range from (0, 0) to (width, height). + matrix.postScale(surfaceView.getWidth() / 2000f, surfaceView.getHeight() / 2000f); + matrix.postTranslate(surfaceView.getWidth() / 2f, surfaceView.getHeight() / 2f); + return matrix; + } @Override public void onPreviewFrame(byte[] data, Camera camera) { @@ -97,8 +140,6 @@ FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1); int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces); if (faceSum == 1) { - faceTipsView.setText("已检测到人脸,识别中"); - faceTipsView.setTextColor(Color.GREEN); bitmapStack.push(originBitmap); if (bitmapStack.size() >= 3) {//当栈里有3张bitmap之后才开始识别 Bitmap bitmap = bitmapStack.pop(); diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java index 94d0d79..1c6d7bf 100644 --- a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java +++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java @@ -5,8 +5,11 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; import android.hardware.Camera; import android.media.FaceDetector; +import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.TextView; @@ -16,6 +19,7 @@ import com.casic.birmm.hxrq.R; import com.casic.birmm.hxrq.base.BaseActivity; import com.casic.birmm.hxrq.utils.ImageHelper; +import com.casic.birmm.hxrq.widgets.FaceDetectView; import java.io.IOException; import java.util.List; @@ -28,6 +32,8 @@ private static final String TAG = "FacePreViewActivity"; @BindView(R.id.surfaceView) SurfaceView surfaceView; + @BindView(R.id.faceDetectView) + FaceDetectView faceDetectView; @BindView(R.id.faceTipsView) TextView faceTipsView; private SurfaceHolder mSurfaceHolder; @@ -70,6 +76,28 @@ } //开始预览 mCamera.startPreview(); + //人脸检测 + mCamera.startFaceDetection(); + mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() { + @Override + public void onFaceDetection(Camera.Face[] faces, Camera camera) { + if (faces.length > 0) { + Camera.Face face = faces[0]; + Rect rect = face.rect; + Log.d(TAG, "可信度:" + face.score + + " ,face detected: " + faces.length + + " ,X: " + rect.centerX() + + " ,Y: " + rect.centerY() + + " ,[" + rect.left + "," + rect.top + "," + rect.right + "," + rect.bottom + "]"); + Matrix matrix = updateFaceRect(); + faceDetectView.updateFace(matrix, faces); + faceTipsView.setText("已检测到人脸,识别中"); + faceTipsView.setTextColor(Color.GREEN); + } else { + faceDetectView.removeRect(); + } + } + }); } @Override @@ -85,6 +113,21 @@ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置 } + private Matrix updateFaceRect() { + Matrix matrix = new Matrix(); + Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); + // Need mirror for front camera. + boolean mirror = (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT); + matrix.setScale(mirror ? -1 : 1, 1); + // This is the value for android.hardware.Camera.setDisplayOrientation. + // 刚才我们设置了camera的旋转参数,所以这里也要设置一下 + matrix.postRotate(90); + // Camera driver coordinates range from (-1000, -1000) to (1000, 1000). + // UI coordinates range from (0, 0) to (width, height). + matrix.postScale(surfaceView.getWidth() / 2000f, surfaceView.getHeight() / 2000f); + matrix.postTranslate(surfaceView.getWidth() / 2f, surfaceView.getHeight() / 2f); + return matrix; + } @Override public void onPreviewFrame(byte[] data, Camera camera) { @@ -97,8 +140,6 @@ FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1); int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces); if (faceSum == 1) { - faceTipsView.setText("已检测到人脸,识别中"); - faceTipsView.setTextColor(Color.GREEN); bitmapStack.push(originBitmap); if (bitmapStack.size() >= 3) {//当栈里有3张bitmap之后才开始识别 Bitmap bitmap = bitmapStack.pop(); diff --git a/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java b/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java new file mode 100644 index 0000000..1f236fd --- /dev/null +++ b/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java @@ -0,0 +1,84 @@ +package com.casic.birmm.hxrq.widgets; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.hardware.Camera; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.Nullable; + +import com.qmuiteam.qmui.util.QMUIDisplayHelper; + +/** + * @author : Pengxh + * @time : 2021/4/14 8:45 + * @email : 290677893@qq.com + * @apiNote :人脸框 + **/ +public class FaceDetectView extends View { + private Matrix matrix; + private Paint mPaint; + private Camera.Face[] faces; + private boolean isClear; + + public FaceDetectView(Context context) { + super(context); + init(context); + } + + public FaceDetectView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public FaceDetectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + mPaint = new Paint(); + mPaint.setColor(Color.GREEN); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeWidth(QMUIDisplayHelper.dp2px(context, 2)); + //设置抗锯齿 + mPaint.setAntiAlias(true); + faces = new Camera.Face[]{}; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.setMatrix(matrix); + for (Camera.Face face : faces) { + if (face == null) break; + canvas.drawRect(face.rect, mPaint); + if (face.leftEye != null) + canvas.drawPoint(face.leftEye.x, face.leftEye.y, mPaint); + if (face.rightEye != null) + canvas.drawPoint(face.rightEye.x, face.rightEye.y, mPaint); + if (face.mouth != null) + canvas.drawPoint(face.mouth.x, face.mouth.y, mPaint); + } + if (isClear) { + canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR); + isClear = false; + } + } + + public void updateFace(Matrix matrix, Camera.Face[] faces) { + this.matrix = matrix; + this.faces = faces; + invalidate(); + } + + public void removeRect() { + isClear = true; + invalidate(); + } +} diff --git a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java index 94d0d79..1c6d7bf 100644 --- a/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java +++ b/app/src/main/java/com/casic/birmm/hxrq/ui/FacePreViewActivity.java @@ -5,8 +5,11 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; import android.hardware.Camera; import android.media.FaceDetector; +import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.TextView; @@ -16,6 +19,7 @@ import com.casic.birmm.hxrq.R; import com.casic.birmm.hxrq.base.BaseActivity; import com.casic.birmm.hxrq.utils.ImageHelper; +import com.casic.birmm.hxrq.widgets.FaceDetectView; import java.io.IOException; import java.util.List; @@ -28,6 +32,8 @@ private static final String TAG = "FacePreViewActivity"; @BindView(R.id.surfaceView) SurfaceView surfaceView; + @BindView(R.id.faceDetectView) + FaceDetectView faceDetectView; @BindView(R.id.faceTipsView) TextView faceTipsView; private SurfaceHolder mSurfaceHolder; @@ -70,6 +76,28 @@ } //开始预览 mCamera.startPreview(); + //人脸检测 + mCamera.startFaceDetection(); + mCamera.setFaceDetectionListener(new Camera.FaceDetectionListener() { + @Override + public void onFaceDetection(Camera.Face[] faces, Camera camera) { + if (faces.length > 0) { + Camera.Face face = faces[0]; + Rect rect = face.rect; + Log.d(TAG, "可信度:" + face.score + + " ,face detected: " + faces.length + + " ,X: " + rect.centerX() + + " ,Y: " + rect.centerY() + + " ,[" + rect.left + "," + rect.top + "," + rect.right + "," + rect.bottom + "]"); + Matrix matrix = updateFaceRect(); + faceDetectView.updateFace(matrix, faces); + faceTipsView.setText("已检测到人脸,识别中"); + faceTipsView.setTextColor(Color.GREEN); + } else { + faceDetectView.removeRect(); + } + } + }); } @Override @@ -85,6 +113,21 @@ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置 } + private Matrix updateFaceRect() { + Matrix matrix = new Matrix(); + Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); + // Need mirror for front camera. + boolean mirror = (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT); + matrix.setScale(mirror ? -1 : 1, 1); + // This is the value for android.hardware.Camera.setDisplayOrientation. + // 刚才我们设置了camera的旋转参数,所以这里也要设置一下 + matrix.postRotate(90); + // Camera driver coordinates range from (-1000, -1000) to (1000, 1000). + // UI coordinates range from (0, 0) to (width, height). + matrix.postScale(surfaceView.getWidth() / 2000f, surfaceView.getHeight() / 2000f); + matrix.postTranslate(surfaceView.getWidth() / 2f, surfaceView.getHeight() / 2f); + return matrix; + } @Override public void onPreviewFrame(byte[] data, Camera camera) { @@ -97,8 +140,6 @@ FaceDetector faceDetector = new FaceDetector(faceDetectorBitmap.getWidth(), faceDetectorBitmap.getHeight(), 1); int faceSum = faceDetector.findFaces(faceDetectorBitmap, faces); if (faceSum == 1) { - faceTipsView.setText("已检测到人脸,识别中"); - faceTipsView.setTextColor(Color.GREEN); bitmapStack.push(originBitmap); if (bitmapStack.size() >= 3) {//当栈里有3张bitmap之后才开始识别 Bitmap bitmap = bitmapStack.pop(); diff --git a/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java b/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java new file mode 100644 index 0000000..1f236fd --- /dev/null +++ b/app/src/main/java/com/casic/birmm/hxrq/widgets/FaceDetectView.java @@ -0,0 +1,84 @@ +package com.casic.birmm.hxrq.widgets; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.hardware.Camera; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.Nullable; + +import com.qmuiteam.qmui.util.QMUIDisplayHelper; + +/** + * @author : Pengxh + * @time : 2021/4/14 8:45 + * @email : 290677893@qq.com + * @apiNote :人脸框 + **/ +public class FaceDetectView extends View { + private Matrix matrix; + private Paint mPaint; + private Camera.Face[] faces; + private boolean isClear; + + public FaceDetectView(Context context) { + super(context); + init(context); + } + + public FaceDetectView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public FaceDetectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + mPaint = new Paint(); + mPaint.setColor(Color.GREEN); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeWidth(QMUIDisplayHelper.dp2px(context, 2)); + //设置抗锯齿 + mPaint.setAntiAlias(true); + faces = new Camera.Face[]{}; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.setMatrix(matrix); + for (Camera.Face face : faces) { + if (face == null) break; + canvas.drawRect(face.rect, mPaint); + if (face.leftEye != null) + canvas.drawPoint(face.leftEye.x, face.leftEye.y, mPaint); + if (face.rightEye != null) + canvas.drawPoint(face.rightEye.x, face.rightEye.y, mPaint); + if (face.mouth != null) + canvas.drawPoint(face.mouth.x, face.mouth.y, mPaint); + } + if (isClear) { + canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR); + isClear = false; + } + } + + public void updateFace(Matrix matrix, Camera.Face[] faces) { + this.matrix = matrix; + this.faces = faces; + invalidate(); + } + + public void removeRect() { + isClear = true; + invalidate(); + } +} diff --git a/app/src/main/res/layout/activity_face.xml b/app/src/main/res/layout/activity_face.xml index b6d8a43..d502c29 100644 --- a/app/src/main/res/layout/activity_face.xml +++ b/app/src/main/res/layout/activity_face.xml @@ -16,11 +16,10 @@ android:layout_height="match_parent" android:layout_gravity="center" /> - +