AI学习者 · 2021年10月25日

OpenCV4.5.4人脸识别详解与代码演示

之前写了一篇文章介绍了OpenCV4.5.4中人脸检测与landmark五点提取的方法,这里就再写一篇,介绍OpenCV4.5.4中最新收录的人脸识别模型使用与代码演示。

人脸识别原理与模型

基于深度学习的人脸识别基本上分为两步完成,第一步是人脸检测与对齐;第二步是人脸特征提取与比对;在第一步中人脸检测与landmark检测,实现人脸对齐,对齐又分为2D/3D对齐;第二步中提取人脸特征数据,从128维到024维都有可能,获取特征之后识别分为两种模型,一种是1:1称为验证,另外一种1:N称为鉴别。整个流程图示如下:

image.png

OpenCV4.5.4发布中包含了一个新的人脸识别算法支持,算法来自北邮邓伟洪教授团队贡献,SFace模型大小为37MB,属于轻量级的人脸识别模型,输出特征维度是128维。该模型采用一种新损失功能,如下所示:

image.png

SFace的损失函数通过在超球面流形上增加类内和类间约束以增大类间距离而减小类内距离,从而提升模型稳定性与泛化性能,实现更高精度的人脸识别。模型下载之后可以查看输入,图示如下:

image.png

要求输入的人脸大小为112x112,输出是128维人脸特征向量。

人脸识别函数支持与演示

OpenCV4.5.4中有个新的类FaceRecognizerSF,它有几个特别有用的方法分别实现了人脸对齐、特征提取、人脸特征匹配(支持余弦相似与L2距离),这些函数分别如下:


virtual void cv::FaceRecognizerSF::alignCrop  (  // 对齐
  InputArray  src_img, 
  InputArray  face_box, 
  OutputArray  aligned_img 
 )  const
 
virtual void cv::FaceRecognizerSF::feature  ( // 提取128维度特征
  InputArray  aligned_img, 
  OutputArray  face_feature 
)

virtual double cv::FaceRecognizerSF::match  ( // 特征比对,默认余弦相似
    InputArray  _face_feature1, 
    InputArray  _face_feature2, 
    int  dis_type = FaceRecognizerSF::FR_COSINE 
 )  const

小编最终把人脸检测跟识别都放到了一个类中,封装成了一个人脸检测与识别的通用类,支持人脸注册、检测、识别、FPS显示功能。其中识别人脸比对的方法如下:

void FaceAlgo::matchFace(cv::Mat &frame, std::vector<std::shared_ptr<faceInfo>> &infoList, bool l2) {
    double cosine_similar_thresh = 0.363;
    double l2norm_similar_thresh = 1.128;
    for(auto face : infoList) {
        cv::Mat aligned_face, feature;
        faceRecognizer->alignCrop(frame, face->detResult, aligned_face);
        faceRecognizer->feature(aligned_face, feature);
        double min_dist = 100.0;
        double max_cosine = 0.0;
        std::string matchedName = "Unknown";
        for(auto item : this->face_models) {
            //std::cout<<"face_models.item :" << item.first << std::endl;
            //std::cout<<"face_models.item :" << item.second << std::endl;
            if(l2) {
                double L2_score = faceRecognizer->match(feature, item.second, cv::FaceRecognizerSF::DisType::FR_NORM_L2);
                if(L2_score < min_dist) {
                    min_dist = L2_score;
                    matchedName = item.first;
                }
            } else {
                double cos_score = faceRecognizer->match(feature, item.second, cv::FaceRecognizerSF::DisType::FR_COSINE);
                if(cos_score > max_cosine) {
                    max_cosine = cos_score;
                    matchedName = item.first;
                }
            }
        }
        //std::cout<<"matchedName :" << matchedName << std::endl;
        if(max_cosine > cosine_similar_thresh) {
            face->name.clear();
            face->name.append(matchedName);
        }
        if(l2 && min_dist < l2norm_similar_thresh) {
            face->name.clear();
            face->name.append(matchedName);
        }
        // std::cout<<"face.name :" << face->name << std::endl;
        // std::cout<<"max_cosine :" << max_cosine<< std::endl;
        // std::cout<<"min_dist :" << min_dist<< std::endl;
    }
}

代码演示部分是我基于QT5+OpenCV4.5.4完成的,主要功能包括人脸注册、人脸比对、支持1:N与1:1两种模型、支持显示设置、支持图象与视频实时识别。从注册到识别演示如下:

image.png

选择视频,开始识别(可以看到识别结果跟注册的一致):

image.png

其实本人自己也注册,测试了一波,运行图示如下:

image.png

文章转载于:OpenCV学堂
作者:gloomyfish

推荐阅读

更多嵌入式AI技术相关内容请关注嵌入式AI专栏。
推荐阅读
关注数
16463
内容数
1229
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息