前言

1.开发环境是win10,IDE是Android studio 北极狐,用到的库有NCNN,OpenCV。
2.NCNN库可以用官方编译好的releases库,也可以按官方文档自己编译。
3.OpenCV用的是nihui大佬简化过的opencv-mobile,大小只有10多M,如果不嫌大也可以用OpenCV官方的版本。
4.项目的各种依赖版本:

一、人脸检测

人脸活体检测的前提条件是先检测到当前的画面是否存在人脸,这里用的人脸检测用的yolov5-face,yolov5-face是一种实时、高精度的人脸检测,搭配NCNN在安卓上(华为Mate 30 pro)cpu 能跑出18 FPS左右,GPU能跑出25 FPS。算法源码地址:https://github.com/deepcam-cn/yolov5-face 。论文地址:https://arxiv.org/abs/2105.12931 。

二、活体检测

1、人脸活体检测是用来检测当前摄像头所检测到的人脸是否是伪造的,是人脸验证和人脸识别的前提条件,如果不能检测出来是否是活体,那么就会出现比如常见用照片,人脸面具,3D人像等其他媒介来骗过人脸识别系统。
2、目前主流的活体解决方案分为配合式活体检测和非配合式活体检测(静默活体检测)。配合式活体检测需要用户根据提示完成指定的动作(比如眨眼,头往哪边转一下),然后再进行活体校验,静默活体则在用户无感的情况下直接进行活体校验。
3、这里演示的是静默活体检测,算法地址:https://github.com/minivision-ai/Silent-Face-Anti-Spoofing 。

三、创建项目

1.创建一个Native C++工程。

2.在CPP目录下导入OpenCV和NCNN库。

四、代码

1.添加打开安卓摄像头的ndkcamera,这是一个快速打开前后摄像头的轻量级C++库。
2.添加用于检测人脸的代码yoloface.h和yoloface.cpp。
3.添加活体检测代码facelive.h和ffacelive.cpp 。
4.在资源里面添加到的模型。

5.添加布局代码。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><SurfaceViewandroid:id="@+id/cameraview"android:layout_width="fill_parent"android:layout_height="fill_parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="1.0"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.0" /><ImageButtonandroid:id="@+id/button_switch_camera"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="20dp"android:layout_marginBottom="30dp"android:src="@drawable/ic_switch_camera"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"></ImageButton><ImageButtonandroid:id="@+id/btn_open_image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="30dp"android:src="@drawable/ic_gallery"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"></ImageButton><ImageButtonandroid:id="@+id/spinner_CPUGPU"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="330dp"android:layout_marginBottom="30dp"android:src="@drawable/ic_baseline"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"></ImageButton></androidx.constraintlayout.widget.ConstraintLayout>

6.编写makefile文件。

project(ncnnyoloface)cmake_minimum_required(VERSION 3.10)set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni)
find_package(OpenCV REQUIRED core imgproc)set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)add_library(livedetect SHARED yoloface.cpp facelive.cpp yolofacencnn.cpp  ndkcamera.cpp)target_link_libraries(livedetect  ncnn ${OpenCV_LIBS} camera2ndk mediandk)

7.JNI交互代码
7.1 在Java里面面定义与C++交互的接口如下:

public class LiveDetect
{public native boolean loadModel(AssetManager mgr, int cpugpu);public native boolean openCamera(int facing);public native boolean closeCamera();public native boolean setOutputWindow(Surface surface);public  native Bitmap yoloTarget(Bitmap bitmap);static {System.loadLibrary("livedetect");}
}

7.2 在Native C++里面实现接口。

extern "C" {JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnLoad");g_camera = new MyNdkCamera;return JNI_VERSION_1_4;
}JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
{__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnUnload");{ncnn::MutexLockGuard g(lock);delete yolo_detect;delete face_live;face_live = 0;yolo_detect = 0;}delete g_camera;g_camera = 0;
}JNIEXPORT jboolean JNICALL Java_com_dashu_livedetect_LiveDetect_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint cpugpu)
{if ( cpugpu < 0 || cpugpu > 1){return JNI_FALSE;}AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);bool use_gpu = (int)cpugpu == 1;// reload{ncnn::MutexLockGuard g(lock);if (use_gpu && ncnn::get_gpu_count() == 0){// no gpudelete yolo_detect;delete face_live;yolo_detect = 0;face_live = 0;}else{if (!yolo_detect){yolo_detect = new YoloFace;face_live = new FaceLive;}yolo_detect->loadModel(mgr,face_model,use_gpu);face_live->LoadModel(mgr,live_model,use_gpu);}}return JNI_TRUE;
}JNIEXPORT jobject JNICALL
Java_com_dashu_livedetect_LiveDetect_yoloTarget(JNIEnv *env,jobject, jobject image)
{cv::Mat cv_src,cv_dst,cv_doc;//bitmap转化成matBitmapToMat(env,image,cv_src);cv::cvtColor(cv_src,cv_doc,cv::COLOR_BGRA2BGR);std::vector<Object> objects;yolo_detect->detection(cv_doc, objects);yolo_detect->drawTarget(cv_doc, objects);MatToBitmap(env,cv_doc,image);cv_dst.release();return image;
}JNIEXPORT jboolean JNICALL Java_com_dashu_livedetect_LiveDetect_openCamera(JNIEnv* env, jobject thiz, jint facing)
{if (facing < 0 || facing > 1)return JNI_FALSE;__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "openCamera %d", facing);g_camera->open((int)facing);return JNI_TRUE;
}JNIEXPORT jboolean JNICALL Java_com_dashu_livedetect_LiveDetect_closeCamera(JNIEnv* env, jobject thiz)
{__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "closeCamera");g_camera->close();return JNI_TRUE;
}// public native boolean setOutputWindow(Surface surface);
JNIEXPORT jboolean JNICALL Java_com_dashu_livedetect_LiveDetect_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)
{ANativeWindow* win = ANativeWindow_fromSurface(env, surface);__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "setOutputWindow %p", win);g_camera->set_window(win);return JNI_TRUE;
}

7.3 MainActivity里面调用Java类与C++交互的接口实现功能。

 //切换摄像头ImageButton buttonSwitchCamera = (ImageButton) findViewById(R.id.button_switch_camera);buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {int new_facing = 1 - facing;yolo_fire.closeCamera();yolo_fire.openCamera(new_facing);facing = new_facing;}});//打开图像open_image = (ImageButton) findViewById(R.id.btn_open_image);open_image.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View arg0){Intent i = new Intent(Intent.ACTION_PICK);i.setType("image/*");startActivityForResult(i, SELECT_IMAGE);yolo_fire.closeCamera();}});//切换CPU/GPUspinnerCPUGPU = (ImageButton) findViewById(R.id.spinner_CPUGPU);spinnerCPUGPU.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {if(current_cpugpu == 0){current_cpugpu = 1;Toast.makeText(MainActivity.this, "启用CPU推理", Toast.LENGTH_SHORT).show();}else{current_cpugpu = 0;Toast.makeText(MainActivity.this, "启用GPU推理", Toast.LENGTH_SHORT).show();}reload();}});reload();}

7.4 运行效果。

五.资源文件

1.可执行的apk文件:https://download.csdn.net/download/matt45m/85007518
2.整个工程源码和模型:https://download.csdn.net/download/matt45m/85007554

Android NDK开发——人脸检测与静默活体检测相关推荐

  1. 基于深度学习的人脸检测与静默活体检测——C++实现

    前言 1.系统环境是win10,显卡RTX3080;cuda10.2,cudnn7.1;OpenCV4.5,ncnn版本是20210525;C++ IDE vs2019. 2.使用NCNN作模型推理加 ...

  2. c#和java部署pytorch同事识别两个图片_人脸识别漏洞频出?这里有个开源静默活体检测算法,超低运算量、工业级可用...

    小视科技团队开源的基于 RGB 图像的活体检测模型,是专门面向工业落地场景,兼容各种复杂场景下的模型.该自研的剪枝轻量级模型,运算量为 0.081G,在麒麟 990 5G 芯片上仅需 9ms.同时基于 ...

  3. 人脸识别漏洞频出?这里有个开源静默活体检测算法,超低运算量、工业级可用...

    来源:机器之心 本文约3259字,建议阅读7分钟. 本文介绍小视科技团队开源的基于 RGB 图像的活体检测模型,是专门面向工业落地场景,兼容各种复杂场景下的模型.该自研的剪枝轻量级模型,运算量为 0. ...

  4. 浅析人脸识别中的活体检测算法的几种类型

    人脸识别技术在各种有安全性需求的身份识别鉴定场景有着广泛应用,例如手机电脑解锁, 企业住宅安全管理,公安司法刑侦等领域.目前已经有了越来越多的基于人脸识别的应用,例如我们现在应用极广的"刷脸 ...

  5. 人脸静默活体检测最新综述

    ©PaperWeekly 原创 · 作者|燕皖 单位|渊亭科技 研究方向|计算机视觉.CNN 活体检测在人脸识别中的重要环节.以前的大多数方法都将面部防欺骗人脸活体检测作为监督学习问题来检测各种预定义 ...

  6. 静默活体检测-人脸活体识别

    活体检测技术一般分为配合式活体检测和非配合式活体检测. 配合式活体检测是最常见的活体检测方式,通过眨眼.张嘴.摇头.点头.甚至读出随机数字等配合式组合动作,使用人脸关键点定位和人脸追踪等技术,验证用户 ...

  7. 静默活体检测+人脸检测+人脸识别结合在NCNN模型下的推理(Windows下的VS环境)

     前言: 涉及到三个模型  静默活体检测模型<2M,人脸检测模型<2M  ,人脸识别<5M(模型大小) 至于NCNN不必多说,全C++实现,不依赖第三方库实现,在第三方移动端CPU运 ...

  8. Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发

    Android NDK开发之旅(2):一篇文章搞定android Studio中使用CMake进行NDK/JNI开发 (码字不易,转载请声明出处:http://blog.csdn.NET/andrex ...

  9. 错过直播不用急,回顾小视科技工业级静默活体检测算法解读,视频已备好

    上周发布的『9ms 静默活体检测,小视开源工业级品质算法』得到很多小伙伴的喜欢. 23日晚间,小视科技副总裁.AI研究院院长胡建国在52CV技术交流群里进行了线上分享,为大家详解这一工业级静默活体检测 ...

最新文章

  1. android .9图片使用和一些技巧
  2. R异常数据检测及处理方法
  3. 149.从网络的作用范围分类 150.使用范围分类 151.拓扑结构分类
  4. Hadoop中-put和-copyFromLocal的区别
  5. kaggle数据集命令行下载
  6. how is group implemented for navigation list
  7. java常用jar_常用jar包含义
  8. 取代 JavaScript!Python 成 Stack Overflow 最受质疑编程语言
  9. komodo-edit
  10. 利用 WireShark 深入调试网络请求
  11. java.exe占用8081端口
  12. Apache Tomcat 文件包含漏洞(CNVD-2020-10487)修复方法
  13. 《英语语法新思维 基础版1》读书笔记(一)
  14. 基于FPGA的数据采集系统(一)
  15. 排球分组循环交叉编排_同学!中国海洋大学第一届排球联赛等你来战!
  16. Listener method could not be invoked with the incoming messageEndpoint handler details:Method
  17. 在线预览pdf(不可下载)
  18. 用R语言理解洛必达法则
  19. MySQL数据库教程天花板,mysql安装到mysql高级,强|硬 宋红康版(自用不可外传)
  20. 微信小程序实现登陆功能

热门文章

  1. c与c十十与python_浅要分析Python程序与C程序的结合使用
  2. yapi 插件_强大的开源API接口可视化管理平台——YAPI
  3. vivado中的rtl中电路图无发生成_FPGA零基础学习:数字电路中的组合逻辑
  4. jupyter notebook python插件_VS Code Python 将支持 Jupyter Notebook
  5. mysql 外键有啥用途_Mysql外键是什么?有哪些用处?(图文+视频)
  6. VS2010和opencv2.4.9的配置
  7. 【Linux】32. shell脚本 定时删除 过时 的某类文件
  8. Machine Learning - Andrew Ng on Coursera (Week 4)
  9. Redis Streams 介绍
  10. 在vue中let var 和const 区别