微信公众号:OpenCV学堂
关注获取更多计算机视觉与深度学习知识
人脸识别原理与模型
基于深度学习的人脸识别基本上分为两步完成,第一步是人脸检测与对齐;第二步是人脸特征提取与比对;在第一步中人脸检测与landmark检测,实现人脸对齐,对齐又分为2D/3D对齐;第二步中提取人脸特征数据,从128维到024维都有可能,获取特征之后识别分为两种模型,一种是1:1称为验证,另外一种1:N称为鉴别。整个流程图示如下:
OpenCV4.5.4发布中包含了一个新的人脸识别算法支持,算法来自北邮邓伟洪教授团队贡献,SFace模型大小为37MB,属于轻量级的人脸识别模型,输出特征维度是128维。该模型采用一种新损失功能,如下所示:
SFace的损失函数通过在超球面流形上增加类内和类间约束以增大类间距离而减小类内距离,从而提升模型稳定性与泛化性能,实现更高精度的人脸识别。模型下载之后可以查看输入,图示如下:
要求输入的人脸大小为112x112,输出是128维人脸特征向量。
人脸识别函数支持与演示
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> &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两种模型、支持显示设置、支持图象与视频实时识别。从注册到识别演示如下:
选择视频,开始识别(可以看到识别结果跟注册的一致):
其实本人自己也注册,测试了一波,运行图示如下:
多说其它的都是废话,想获取源码,扫码即可:
课程总计课时数超过80+,提供了超过100页详细电子文档,近万行C++代码,数十个各种QT+OpenCV+深度学习 案例,提供电子书资料
推荐阅读
OpenCV4.8+YOLOv8对象检测C++推理演示
ZXING+OpenCV打造开源条码检测应用
攻略 | 学习深度学习只需要三个月的好方法
三行代码实现 TensorRT8.6 C++ 深度学习模型部署
实战 | YOLOv8+OpenCV 实现DM码定位检测与解析
对象检测边界框损失 – 从IOU到ProbIOU
初学者必看 | 学习深度学习的五个误区