文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 开发笔记 07-02 篇:OpenCV 人脸检测篇

2022-06-06 13:02

关注

OpenCV 库导入可参考:https://blog.csdn.net/zhrjyl/article/details/104442030

Demo:链接:https://pan.baidu.com/s/1z0WsF0nI5GuXilcBHnPWPA  提取码:5a0m 

目录

人脸检测效果

开发环境

人脸检测原理

人脸检测实践

步骤 1:权限声明与申请

步骤 2:布局文件中导入 JavaCameraView 控件

步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口

步骤 4:Activity 初始化 JavaCameraView 控件

步骤 5:导入 OpenCV 提供的人脸模型

步骤 6:初始化 CascadeClassifier 级联分类器

步骤 7:重写 onCameraFrame 检测人脸

补充

补充 1:Activity 中的 onCreate 方法

人脸检测效果

开发环境 Android Studio:3.5 OpenCV:opencv-3.4.1-android-sdk 工程基础:已经实现 OpenCV 的库导入 人脸检测原理 初步认知 OpenCV 的人脸检测逻辑: 步骤 1:通过 JavaCameraView 控件实现相机预览。 步骤 2:通过 CameraBridgeViewBase.CvCameraViewListener2 获取预览时每一帧的数据。 步骤 3:通过 CascadeClassifier,将每一帧的数据与训练好的人脸模型数据比对。 步骤 4:通过 Imgproc.rectangle 给识别出的人脸画框。 人脸检测实践

人脸检测实践分为以下几个步骤:

步骤 1:权限声明与申请 步骤 2:布局文件中导入 JavaCameraView 控件 步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口 步骤 4:Activity 初始化 JavaCameraView 控件 步骤 5:导入 OpenCV 提供的人脸模型 步骤 6:初始化 CascadeClassifier 级联分类器 步骤 7:重写 onCameraFrame 检测人脸 步骤 1:权限声明与申请


private void askPermission(){
    ActivityCompat.requestPermissions(
            this,
            new String[]{
                    Manifest.permission.CAMERA
            },
            1
    );
}
步骤 2:布局文件中导入 JavaCameraView 控件

步骤 3:Activity 实现 CameraBridgeViewBase.CvCameraViewListener2 接口
private Mat matRgba;// 彩色图象容器
private Mat matGray;// 灰色图象容器
@Override
public void onCameraViewStarted(int width, int height) {
    matRgba = new Mat();
    matGray = new Mat();
}
@Override
public void onCameraViewStopped() {
    matRgba.release();
    matGray.release();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    matRgba = inputFrame.rgba();
    matGray = inputFrame.gray();
    return matRgba;
}
步骤 4:Activity 初始化 JavaCameraView 控件
private JavaCameraView mCameraView;

private void initCamera(){
    mCameraView = findViewById(R.id.javaCameraView);
    if(mCameraView != null){
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        mCameraView.setCvCameraViewListener(this);
        mCameraView.enableFpsMeter();// 显示fps信息
        mCameraView.setCameraIndex(0);// 设置摄像头 0 后置摄像头 1 前置摄像头
        mCameraView.enableView();
    }
}

注意:

为了更改相机预览方向做了以下修改

至此已静可以实现相机预览。 步骤 5:导入 OpenCV 提供的人脸模型

将 \opencv-3.4.1-android-sdk\OpenCV-android-sdk\sdk\etc\lbpcascades 下的 lbpcascade_profileface.xml 与 lbpcascade_frontalface.xml 文件拷贝到 MyApplication\app\src\main\res\raw 目录下

步骤 6:初始化 CascadeClassifier 级联分类器

private CascadeClassifier frontClassifier;// 正脸,级分类器
private CascadeClassifier profileClassifier;// 侧脸,级分类器

private void initClassifier() {
    // 初始化正脸,级分类器
    try {
        InputStream is =
                getResources().openRawResource(R.raw.lbpcascade_frontalface);// 正脸模型
        File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
        File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
        FileOutputStream os = new FileOutputStream(cascadeFile);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        is.close();
        os.close();
        frontClassifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
    // 初始化侧脸,级分类器
    try {
        InputStream is =
                getResources().openRawResource(R.raw.lbpcascade_profileface);//侧脸模式
        File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
        File cascadeFile = new File(cascadeDir, "lbpcascade_profileface.xml");
        FileOutputStream os = new FileOutputStream(cascadeFile);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        is.close();
        os.close();
        profileClassifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
步骤 7:重写 onCameraFrame 检测人脸

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    // 步骤 1:获取相机捕捉到的帧的彩色和灰色数据,并保存到 Mat 图象容器中
    matRgba = inputFrame.rgba();
    matGray = inputFrame.gray();
    // 步骤 2:计算绝对面尺寸
    float mRelativeFaceSize = 0.15f;
    int mAbsoluteFaceSize = 0;
    int height = matGray.rows();
    if (Math.round(height * mRelativeFaceSize) > 0) {
        mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
    }
    // 步骤 3:定义矩阵图象容器,存放检测出来的人脸数据矩阵
    MatOfRect frontFaces = new MatOfRect();
    MatOfRect profileFaces = new MatOfRect();
    // 步骤 4:人脸检测
    if (frontClassifier != null)
        frontClassifier.detectMultiScale(
                matGray,
                frontFaces,
                1.1,
                3,
                0,
                new Size(mAbsoluteFaceSize, mAbsoluteFaceSize),
                new Size());
    if (profileClassifier != null)
        profileClassifier.detectMultiScale(
                matGray,
                profileFaces,
                1.1,
                3,
                0,
                new Size(mAbsoluteFaceSize, mAbsoluteFaceSize),
                new Size());
    // 步骤 5:根据检测出来的人脸矩阵数据在彩色图像上画方框
    for (Rect faceRect : frontFaces.toArray())
        Imgproc.rectangle(
                matRgba,                   // 图象源
                faceRect.tl(),             // 矩形框的 x 起点
                faceRect.br(),             // 矩形框的 y 起点
                new Scalar(0, 255, 0, 255),// 矩形框颜色
                3);             // 矩形框厚度
    for (Rect faceRect : profileFaces.toArray())
        Imgproc.rectangle(
                matRgba,
                faceRect.tl(),
                faceRect.br(),
                new Scalar(0, 255, 0, 255),
                3);
    return matRgba;
}
补充 补充 1:Activity 中的 onCreate 方法

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a2);
    askPermission();
    initCamera();
    initClassifier();
}

作者:Look For Answer


阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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