人脸识别原理与模型
基于深度学习的人脸识别基本上分为两步完成,第一步是人脸检测与对齐;第二步是人脸特征提取与比对;在第一步中人脸检测与landmark检测,实现人脸对齐,对齐又分为2D/3D对齐;第二步中提取人脸特征数据,从128维到024维都有可能,获取特征之后识别分为两种模型,一种是1:1称为验证,另外一种1:N称为鉴别。整个流程图示如下:
OpenCV4.5.4发布中包含了一个新的人脸识别算法支持,算法来自北邮邓伟洪教授团队贡献,SFace模型大小为37MB,属于轻量级的人脸识别模型,输出特征维度是128维。该模型采用一种新损失功能,如下所示:
SFace的损失函数通过在超球面流形上增加类内和类间约束以增大类间距离而减小类内距离,从而提升模型稳定性与泛化性能,实现更高精度的人脸识别。模型下载之后可以查看输入,图示如下:
要求输入的人脸大小为112x112,输出是128维人脸特征向量。
人脸识别函数支持与演示
OpenCV4.5.4中有个新的类FaceRecognizerSF,它有几个特别有用的方法分别实现了人脸对齐、特征提取、人脸特征匹配(支持余弦相似与L2距离),这些函数分别如下:
代码语言:javascript复制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显示功能。其中识别人脸比对的方法如下:
代码语言:javascript复制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两种模型、支持显示设置、支持图象与视频实时识别。从注册到识别演示如下:
选择视频,开始识别(可以看到识别结果跟注册的一致):
其实本人自己也注册,测试了一波,运行图示如下:
人脸检测与识别模型请这里下载:https://gitee.com/opencv_ai/opencv_tutorial_data