人臉活體識別4:Android實現人臉眨眼 張嘴 點頭 搖頭識別(可實時檢測)
目錄
人臉活體識別4:Android實現人臉眨眼 張嘴 點頭 搖頭識別(可實時檢測)
1. 前言
2.人臉活體識別方法
(1)基于人臉動作的檢測??
(2)??基于紅外的活體識別??
(3)基于深度的活體識別??
?3.人臉檢測模型
?4. 活體識別模型
(1) 將Pytorch模型轉換ONNX模型
(2) 將Pytorch模型轉換為NCNN模型
5. 活體識別Android部署
(1) Android部署NCNN模型
(2) Android編譯異常解決方法
6.活體識別效果(Android版本)
7. 項目Android源碼下載
1. 前言
人臉活體識別技術是確保人臉識別系統安全性的關鍵,主要用于區分真實人臉與偽造攻擊(如照片、視頻、3D面具等)。本項目基于深度學習技術,構建了一套高魯棒性的面部活體檢測系統,可精準識別眨眼(閉眼)、張嘴、點頭(低頭)、搖頭(側臉)等生物特征動作,可有效防范照片、視頻、3D面具等偽造攻擊等多種場景,??可應用于金融支付、遠程身份核驗(如銀行開戶)等場景。
整套項目分為人臉活體識別數據集說明,模型開發和訓練,模型邊緣側部署C++/Android等多個章節,本篇是項目《????人臉活體識別》系列文章之《Android實現人臉眨眼 張嘴 點頭 搖頭識別》;為了方便后續模型工程化和Android平臺部署,項目對活體識別模型進行輕量化,并提供Python/C++/Android多個版本;
整套活體識別系統,在普通Android手機上可以達到實時的檢測效果,CPU(4線程)約40ms左右,GPU約30ms左右 ,基本滿足業務的性能需求。準確率還挺高的,采用輕量級mobilenet_v2模型的人臉活體識別準確率也可以高達99.9661%左右,滿足業務性能需求。
模型 | input size | Test準確率 |
Mobilenet | 112×112 | 99.9661 |
Resnet18 | 112×112 | 99.9322 |
MobileVit | 112×112 | 99.9322 |
? ?
??
【尊重原創,轉載請注明出處】https://blog.csdn.net/guyuealian/article/details/148774240
?【Android APP Demo體驗】https://download.csdn.net/download/guyuealian/91133467
?更多人臉識別和活體識別文章,請參考:
- 人臉活體識別1:眨眼 張嘴 點頭 搖頭人臉數據集
- 人臉活體識別2:Pytorch實現人臉眨眼 張嘴 點頭 搖頭識別(含訓練代碼和數據集)
- 人臉活體識別3:C/C++實現人臉眨眼 張嘴 點頭 搖頭識別(可實時檢測)
- 人臉活體識別4:Android實現人臉眨眼 張嘴 點頭 搖頭識別(可實時檢測)
- 人臉識別2:InsightFace實現人臉識別Face Recognition(含源碼下載)
- 人臉識別3:C/C++ InsightFace實現人臉識別Face Recognition(含源碼)
- 人臉識別4:Android InsightFace實現人臉識別Face Recognition(含源碼)
2.人臉活體識別方法
人臉活體識別的方法有很多,如基于人臉動作的活體識別?,基于紅外的活體識別,基于深度的活體識別等等方法。
(1)基于人臉動作的檢測??
? ? 要求用戶配合完成隨機指令動作(如眨眼、點頭、張嘴、搖頭等),通過計算機視覺算法(如光流法、關鍵點跟蹤)分析動作的自然性和時序連貫性。
優點??:實現簡單,能有效抵御照片和靜態視頻攻擊。??
缺點??:依賴用戶配合,體驗較差;可能被高仿動態視頻(如Deepfake)欺騙。
(2)??基于紅外的活體識別??
??? ? ?利用紅外攝像頭捕捉人臉的紅外反射特性或熱輻射分布,如采用紅外光譜分析??,活體皮膚對特定波長紅外光的吸收/反射模式與非活體不同。??
優點??:無需用戶配合,可抵御照片、視頻及部分3D面具攻擊。
缺點??:設備成本較高;受環境溫度影響(如低溫可能降低檢測精度)。
(3)基于深度的活體識別??
? ? 通過3D深度攝像頭(如結構光、ToF)獲取人臉的三維幾何信息(如鼻梁高度、曲面曲率),非活體(照片、屏幕)缺乏真實的深度結構。??
優點??:防御能力最強,可識別高級3D頭套攻擊。
??缺點??:硬件成本高,需專用3D傳感器。
本項目實現方案是采用基于人臉動作的活體識別方法,即先采用通用的人臉檢測模型,進行人臉檢測定位人臉區域,然后按照一定規則裁剪人臉檢測區域,再訓練一個人臉活體識別分類器,完成人臉活體識別的任務。人臉動作主要包含:眨眼(閉眼)、張嘴、點頭(低頭)、搖頭(側臉)。
?3.人臉檢測模型
本項目人臉檢測訓練代碼請參考:https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB?
這是一個基于SSD改進且輕量化后人臉檢測模型,很slim,整個模型僅僅1.7M左右,在普通Android手機都可以實時檢測。人臉檢測方法在網上有一大堆現成的方法可以使用,完全可以不局限我這個方法。
當然可以基于YOLOv5訓練一個人臉檢測模型:人臉檢測和行人檢測2:YOLOv5實現人臉檢測和行人檢測(含數據集和訓練代碼)
?
?4. 活體識別模型
關于人臉活體識別模型訓練,請參考《人臉活體識別2:Pytorch實現人臉眨眼 張嘴 點頭 搖頭識別(含訓練代碼和數據集)》
整套活體識別系統,在NCNN加速下,可以達到實時的檢測效果,基本滿足業務的性能需求。下表格給出Mobilenet,Resnet18和MobileVit模型識別的準確率:
模型 | input size | Test準確率 |
Mobilenet | 112×112 | 99.9661 |
Resnet18 | 112×112 | 99.9322 |
MobileVit | 112×112 | 99.9322 |
模型訓練完成后,需要將Pytorch模型轉換為NCNN格式,轉換方法請參考如下
考慮到端上硬件處理性能比較弱雞,項目C++和Android部署僅使用Mobilenet模型。
(1) 將Pytorch模型轉換ONNX模型
項目Python源碼提供了轉換工具,可實現將Pytorch的模型轉換為ONNX模型文件,且文件會默認保存在Pytorch的模型文件同一目錄下。
python libs/convertor/convert2onnx.py
(2) 將Pytorch模型轉換為NCNN模型
你也可以一步到位,使用PNNX工具,直接將Pytorch模型直接轉換為NCNN文件
python libs/convertor/convert2ncnn.py
NCNN轉換工具說明,請參考:
- https://github.com/Tencent/ncnn/wiki/use-ncnn-with-pytorch-or-onnx
- ?將ONNX模型轉換為NCNN模型,請參考NCNN官方說明:GitHub - Tencent/ncnn: ncnn is a high-performance neural network inference framework optimized for the mobile platform
5. 活體識別Android部署
項目實現了Android版本的活體識別,模型部署框架采用NCNN,支持多線程CPU和GPU加速推理,在普通手機上可以實時處理。
(1) Android部署NCNN模型
模型推理采用NCNN,圖像處理和Android核心算法部分均采用C++實現,上層Java通過JNI接口調用C++算法。
如果你想在這個Android Demo部署你自己訓練的模型,你可將訓練好的Pytorch模型轉換ONNX ,再轉換成NCNN模型,然后把原始的模型替換成你自己的TNCNN模型即可。
package com.cv.dl.model;import android.graphics.Bitmap;public class Detector {static {System.loadLibrary("cvdl-lib");}/**** 初始化檢測模型* @param root:模型文件的根目錄,放在assets文件夾下* @param det_model: 檢測模型(不含后綴名)* @param rec_model: 識別模型(不含后綴名)* @param model_type:模型類型* @param num_thread:開啟線程數* @param useGPU:是否開啟GPU進行加速*/public static native void init(String root, String det_model, String rec_model, int model_type, int num_thread, boolean useGPU);/**** 進行檢測(用于靜態圖)* @param bitmap 圖像(bitmap),ARGB_8888格式* @param score_thresh:置信度閾值* @param iou_thresh: IOU閾值* @return*/public static native FrameInfo[] detect(Bitmap bitmap, float score_thresh, float iou_thresh);}
JNI接口
#include <jni.h>
#include <string>
#include <fstream>
#include "src/classifier.h"
#include "src/object_detection.h"
#include "src/Types.h"
#include "debug.h"
#include "android_utils.h"
#include "opencv2/opencv.hpp"
#include "file_utils.h"using namespace dl;
using namespace vision;static ObjectDetection *detector = nullptr;
static Classifier *recognize = nullptr;JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {return JNI_VERSION_1_6;
}JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) {}extern "C"
JNIEXPORT void JNICALL
Java_com_cv_dl_model_Detector_init(JNIEnv *env,jclass clazz,jstring root,jstring det_model,jstring rec_model,jint model_type,jint num_thread,jboolean use_gpu) {if (detector != nullptr) {delete detector;detector = nullptr;}std::string parent = env->GetStringUTFChars(root, 0);std::string det_model_ = env->GetStringUTFChars(det_model, 0);std::string rec_model_ = env->GetStringUTFChars(rec_model, 0);string det_pam_file = path_joint(parent, det_model_ + ".param");string det_bin_file = path_joint(parent, det_model_ + ".bin");string rec_pam_file = path_joint(parent, rec_model_ + ".param");string rec_bin_file = path_joint(parent, rec_model_ + ".bin");DeviceType device = use_gpu ? GPU : CPU;LOGW("parent : %s", parent.c_str());LOGW("useGPU : %d", use_gpu);LOGW("device_type : %d", device);LOGW("model_type : %d", model_type);LOGW("num_thread : %d", num_thread);DetParam det_param = MODEL_TYPE[model_type];//模型參數detector = new ObjectDetection(det_bin_file, det_pam_file, det_param, num_thread, device, -1);RecParam rec_param = REC_MODEL;recognize = new Classifier(rec_bin_file, rec_pam_file, rec_param, num_thread, device);}extern "C"
JNIEXPORT jobjectArray JNICALL
Java_com_cv_dl_model_Detector_detect(JNIEnv *env, jclass clazz, jobject bitmap,jfloat score_thresh, jfloat iou_thresh) {cv::Mat bgr;BitmapToMatrix(env, bitmap, bgr);int src_h = bgr.rows;int src_w = bgr.cols;// 檢測區域為整張圖片的大小FrameInfo resultInfo;// 開始檢測detector->detect(bgr, &resultInfo, score_thresh, iou_thresh);recognize->detect(bgr, &resultInfo);int nums = resultInfo.info.size();LOGW("image is (%d,%d,%d),score_thresh=%3.3f, iou_thresh=%3.3f, object nums: %d\n", bgr.cols,bgr.rows, bgr.channels(), score_thresh, iou_thresh, nums);auto BoxInfo = env->FindClass("com/cv/dl/model/FrameInfo");auto init_id = env->GetMethodID(BoxInfo, "<init>", "()V");auto box_id = env->GetMethodID(BoxInfo, "addBox", "(FFFFIFLjava/lang/String;)V");auto ky_id = env->GetMethodID(BoxInfo, "addKeyPoint", "(FFF)V");auto po_id = env->GetMethodID(BoxInfo, "addPolygon", "(FFFI)V");jobjectArray ret = env->NewObjectArray(resultInfo.info.size(), BoxInfo, nullptr);for (int i = 0; i < nums; ++i) {auto info = resultInfo.info[i];env->PushLocalFrame(1);//jobject obj = env->AllocObject(BoxInfo);jobject obj = env->NewObject(BoxInfo, init_id);// set bbox//LOGW("rect:[%f,%f,%f,%f] label:%d,score:%f \n", info.rect.x,info.rect.y, info.rect.w, info.rect.h, 0, 1.0f);jstring name = env->NewStringUTF(info.name.c_str());env->CallVoidMethod(obj, box_id, info.x1, info.y1, info.x2 - info.x1, info.y2 - info.y1,info.category.label, info.category.score, name);// set keypointfor (const auto &kps: info.points) {//LOGW("point:[%f,%f] score:%f \n", lm.point.x, lm.point.y, lm.score);env->CallVoidMethod(obj, ky_id, (float) kps.x, (float) kps.y, 1.0f);}// set contours// LOGW("jni contours.size=%d\n", info.segInfo.contours.size());for (int group = 0; group < info.segInfo.contours.size(); ++group) {for (const auto &kps: info.segInfo.contours.at(group)) {//LOGW("jni contours group=%d,point:[%f,%f]\n", group, (float)kps.x, (float)kps.y);env->CallVoidMethod(obj, po_id, (float) kps.x, (float) kps.y, 1.0f, group);}}obj = env->PopLocalFrame(obj);env->SetObjectArrayElement(ret, i, obj);}return ret;
}
(2) Android編譯異常解決方法
參考解決方法:Android項目常見問題解決辦法
6.活體識別效果(Android版本)
活體識別Android APP在普通Android手機上可以達到實時的檢測和識別效果,CPU(4線程)約40ms左右,GPU約30ms左右 ,基本滿足業務的性能需求。
?【Android APP Demo體驗】https://download.csdn.net/download/guyuealian/91133467
??? ?
7. 項目Android源碼下載
??【Android APP Demo體驗】https://download.csdn.net/download/guyuealian/91133467
如需下載項目源碼,請WX關注【AI吃大瓜】,回復【活體識別】即可下載
項目資源內容包含:
- 提供輕量化人臉檢測模型
- 提供輕量化人臉活體識別模型(Mobilenet),支持眨眼(閉眼)、張嘴、點頭(低頭)、搖頭(側臉)動作識別,識別準確率可以高達99.9661%左右。
- 提供整套人臉活體識別Android Demo項目源碼
- Android Demo源碼可用于二次開發
- Android Demo在普通手機CPU/GPU上可以實時檢測,CPU約40ms,GPU約30ms左右
- Android Demo支持圖片、視頻和攝像頭測試
- 所有依賴庫都已經配置好,可直接build運行,若運行出現異常,請參考Android項目常見問題解決辦法