前言:
涉及到三个模型 静默活体检测模型<2M,人脸检测模型<2M ,人脸识别<5M(模型大小)
至于NCNN不必多说,全C++实现,不依赖第三方库实现,在第三方移动端CPU运行最快。
首先,这是三者结合的推理,这意味着从训练到转ncnn模型全部完成且作用效果的精度达到了不错的要求。
训练在此就省略了,复现的都是都是GitHub上的原项目,然后使用其最终模型进行C++上的推理。
实现的功能:
一个demo实现对单个人的识别。(因为未涉及C++的太多知识,比如通过序列化对象转储到文件并从文件中读取,或者是通过连接数据库进行数据的转储,所以测试的推理的整个流程针对单人。)
步骤:先进行静默活体检测->人脸检测->人脸识别。后面的步骤都是在前面的步骤上实现,识别完后进行静默活体检测开始循环反复。
main函数
#include <stdio.h>
#include <algorithm>
#include <vector>
#include "platform.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "iostream"
#include<sstream>
#include "net.h"
#if NCNN_VULKAN
#include "gpu.h"
#endif // NCNN_VULKAN
#define IMAGE_SIZE 80
#define CV_RGB(r,g,b) cvScalar((b),(g),(r),0)
/*声明*/
bool JudgeReal(cv::Mat bgr, ncnn::Extractor ex, ncnn::Net & SilentFaceSpoofing);
cv::Mat GetMyMat(cv::Mat img, const std::string& s);//获取人脸特征
cv::Mat GetMat(const std::string & path);//获取人脸框
cv::Mat GetMat(cv::Mat img);//重载
float* getFeatByMobileFaceNetNCNN(cv::Mat img);//获取特征向量
float CalcSimilarity_1(float* fc1,//比较出相识度
float* fc2,
long dim);
std::string Convert(float Num)
{
std:: ostringstream oss;
oss << Num;
std:: string str(oss.str());
return str;
}
int main(){
/*
先加载一个人的图片及其特征向量
*/
cv::Mat sample = GetMat("./pic/yzh1.jpg");
float *sam= getFeatByMobileFaceNetNCNN( sample);
/*
加载活体检测模型
*/
static ncnn::Net SilentFaceSpoofing;
SilentFaceSpoofing.load_param("./model/2.7_80x80_MiniFASNetV2_sim.param");
SilentFaceSpoofing.load_model("./model/2.7_80x80_MiniFASNetV2_sim.bin");
static ncnn::Extractor ex = SilentFaceSpoofing.create_extractor();
//打开摄像头
cv::VideoCapture capture(0);//创建VideoCapture对象
if (!capture.isOpened())//判断是否打开摄像头,打开isOpened返回ture
return 1;
bool stop(false);//定义一个用来停止循环的变量
cv::Mat frame;//用来存放读取的视频序列,承载每一帧的图像 ,Mat类是用于保存图像以及其他矩阵数据的数据结构
cv::namedWindow("Camera");//创建一个窗口,显示每一帧的窗口
while (!stop)
{
if (!capture.read(frame))//如果没有读取到就中断
{
break;
}
bool result;
result = JudgeReal(frame, ex, SilentFaceSpoofing);//判断真假脸
if (result) {//活体
cv::Mat frame2= GetMat(frame);//获取人脸框
float * fr= getFeatByMobileFaceNetNCNN(frame2);
float res= CalcSimilarity_1(fr, sam, 112);
std::cout << "相识度:" << res << std::endl;
delete[]fr;
if (res > 0.3) { //认为是同一个人
std::string name = "yzh-sim:" + Convert(res);
cv::Mat imgs = GetMyMat(frame, name);
putText(imgs, "realface", cv::Point(0, 100), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(123, 0, 255), 4, 4);
cv::imshow("Camera", imgs);//正常显示,把获取的视频填充到窗口中
}
else
{
cv::Mat imgs = GetMyMat(frame, "unknow");
putText(imgs, "unkonwrealface", cv::Point(0, 100), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(123, 0, 255), 4, 4);
cv::imshow("Camera", imgs);//正常显示,把获取的视频填充到窗口中
}
}
else {
putText(frame, "FalseFace", cv::Point(0, 100), cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(123, 0, 255), 4, 4);
cv::imshow("Camera", frame);//正常显示,把获取的视频填充到窗口中
std::cout << result << std::endl;
}
char c = cvWaitKey(33);
if (c == 32)break; //使用空格键来停止ASCII 为32 关闭摄像头
}
capture.release();//释放
return 0;
}
获取人的特征向量以及比较人的相识度(mobilefacenet网络实现识别)
#include<iostream>
#include "net.h"
#include <opencv2/opencv.hpp>
using namespace std;
static int flag = 0;
//Mobilefacenet 初始化
float simd_dot_1(const float* x, const float* y, const long& len) {
float inner_prod = 0.0f;
__m128 X, Y; // 128-bit values
__m128 acc = _mm_setzero_ps(); // set to (0, 0, 0,

本文介绍了一个基于ncnn的静默活体检测、人脸检测及人脸识别的单人识别系统实现。该系统通过三个模型:静默活体检测模型、人脸检测模型和人脸识别模型,实现了从活体检测到人脸特征提取再到人脸识别的全过程。文中详细展示了系统的实现过程和技术细节。
最低0.47元/天 解锁文章
2347





