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

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

 前言:

涉及到三个模型  静默活体检测模型<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, 
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值