文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Android App】人脸识别中借助摄像头和OpenCV实时检测人脸讲解及实战(附源码和演示 超详细)

2023-08-31 10:02

关注

需要全部代码请点赞关注收藏后评论区留言私信~~~

与Android自带的人脸检测器相比,OpenCV具备更强劲的人脸识别功能,它可以通过摄像头实时检测人脸,实时检测的预览空间是JavaCameraView 常用方法说明如下

setCvCameraViewListener:设置OpenCV的相机视图监听器。监听器需要写下列三个状态变更方法:

onCameraViewStarted:相机视图开始预览时回调。

onCameraViewStopped:相机视图停止预览时回调。

onCameraFrame:相机视图预览变更时回调。

enableView:启用OpenCV的相机视图。

 disableView:禁用OpenCV的相机视图。

接下来把JavaCameraView加入App工程,走一遍它的详细使用过程,首先修改AndroidManifest.xml补充一行相机权限配置

实时检测人脸有如下四个步骤

(1)从布局文件中获得相机视图对象后,调用它的setCvCameraViewListener方法,设置OpenCV的相机视图监听器。

(2)OpenCV初始化与资源加载完成后,调用enableView方法开启相机视图。

(3)活动类由继承AppCompatActivity改为继承CameraActivity类,并重写getCameraViewList方法,返回相机视图的单例列表。

(4)第一步重写监听器接口的onCameraFrame方法时,补充人脸识别等处理逻辑,也就是先检测人脸,再给人脸标上相框。

运行测试App 会自动打开手机摄像机 然后检测摄像机内的人脸

由顶部状态栏可以看到打开了相机功能 此处用了博主小时候的照片~~~

部分代码如下 需要全部源码请点赞关注收藏后评论区留言~~~

package com.example.face;import android.content.Context;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.widget.TextView;import com.example.face.util.DateUtil;import org.opencv.android.CameraActivity;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.CameraBridgeViewBase;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.OpenCVLoader;import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.core.MatOfRect;import org.opencv.core.Rect;import org.opencv.core.Scalar;import org.opencv.core.Size;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;import org.opencv.objdetect.CascadeClassifier;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.util.Collections;import java.util.List;//OpenCV的实时扫描页面必须继承CameraActivitypublic class DetectRealtimeActivity extends CameraActivity implements CameraBridgeViewBase.CvCameraViewListener2 {    private static final String TAG = "DetectRealtimeActivity";    private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255);    private Mat mRgba, mGray; // 全彩矩阵,灰度矩阵    private CascadeClassifier mJavaDetector; // OpenCV的人脸检测器    private int mAbsoluteFaceSize = 0; // 绝对人脸大小    // OpenCV默认横屏扫描,需要旋转90度改成竖屏预览,详细改动见CameraBridgeViewBase.java的deliverAndDrawFrame方法    private CameraBridgeViewBase jcv_detect; // 声明一个OpenCV的相机视图对象    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_detect_realtime);        findViewById(R.id.iv_back).setOnClickListener(v -> finish());        TextView tv_title = findViewById(R.id.tv_title);        tv_title.setText("实时检测人脸");        jcv_detect = findViewById(R.id.jcv_detect);        jcv_detect.setVisibility(CameraBridgeViewBase.VISIBLE);        jcv_detect.setCvCameraViewListener(this); // 设置OpenCV的相机视图监听器    }    @Override    public void onPause() {        super.onPause();        if (jcv_detect != null) {            jcv_detect.disableView(); // 禁用OpenCV的相机视图        }    }    @Override    public void onResume() {        super.onResume();        if (!OpenCVLoader.initDebug()) {            Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);        } else {            Log.d(TAG, "OpenCV library found inside package. Using it!");            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);        }    }    @Override    protected List getCameraViewList() {        return Collections.singletonList(jcv_detect);    }    @Override    public void onDestroy() {        super.onDestroy();        jcv_detect.disableView(); // 禁用OpenCV的相机视图    }    @Override    public void onCameraViewStarted(int width, int height) {        mGray = new Mat();        mRgba = new Mat();    }    @Override    public void onCameraViewStopped() {        mGray.release();        mRgba.release();    }    // 相机预览回调    @Override    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {        mRgba = inputFrame.rgba();        mGray = inputFrame.gray();        Core.rotate(mRgba, mRgba, Core.ROTATE_90_CLOCKWISE); // 适配竖屏,顺时针旋转90度        Core.rotate(mGray, mGray, Core.ROTATE_90_CLOCKWISE); // 适配竖屏,顺时针旋转90度        if (mAbsoluteFaceSize == 0) {            Log.d(TAG, "width="+mGray.width()+", height="+mGray.height()+", cols="+mGray.cols()+", rows="+mGray.rows());            int height = mGray.rows();            if (Math.round(height * 0.2f) > 0) {                mAbsoluteFaceSize = Math.round(height * 0.2f);            }//            String filePath = String.format("%s/%s.jpg",//                    getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),//                    DateUtil.getNowDateTime());//            Imgcodecs.imwrite(filePath, mRgba);//            Log.d(TAG, "filePath="+filePath);        }        MatOfRect faces = new MatOfRect();        if (mJavaDetector != null) { // 检测器开始识别人脸            mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2,                    new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());        }        Rect[] faceArray = faces.toArray();        for (Rect rect : faceArray) { // 给找到的人脸标上相框            Imgproc.rectangle(mRgba, rect.tl(), rect.br(), FACE_RECT_COLOR, 3);            Log.d(TAG, rect.toString());        }        Core.rotate(mRgba, mRgba, Core.ROTATE_90_COUNTERCLOCKWISE); // 恢复原状,逆时针旋转90度        return mRgba;    }    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {        @Override        public void onManagerConnected(int status) {            if (status == LoaderCallbackInterface.SUCCESS) {                Log.d(TAG, "OpenCV loaded successfully");                // 在OpenCV初始化完成后加载so库                System.loadLibrary("detection_based_tracker");                File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);                File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");                // 从应用程序资源加载级联文件                try (InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);                     FileOutputStream os = new FileOutputStream(cascadeFile)) {                    byte[] buffer = new byte[4096];                    int bytesRead;                    while ((bytesRead = is.read(buffer)) != -1) {                        os.write(buffer, 0, bytesRead);                    }                } catch (Exception e) {                    e.printStackTrace();                }                // 根据级联文件创建OpenCV的人脸检测器                mJavaDetector = new CascadeClassifier(cascadeFile.getAbsolutePath());                if (mJavaDetector.empty()) {                    Log.d(TAG, "Failed to load cascade classifier");                    mJavaDetector = null;                } else {                    Log.d(TAG, "Loaded cascade classifier from " + cascadeFile.getAbsolutePath());                }                cascadeDir.delete();                jcv_detect.enableView(); // 启用OpenCV的相机视图            } else {                super.onManagerConnected(status);            }        }    };}

创作不易  觉得有帮助请点赞关注收藏~~~

来源地址:https://blog.csdn.net/jiebaoshayebuhui/article/details/128157645

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯