seetaface6教程:封装人脸识别,人脸检测,,眼睛检测,状态,特征.....
seetaface是中科视扩开发的一个项目,目前,seetaface2是开源的,可以自己下载编译,我没有具体用过,所以不是很清楚,今年3月底,seetaface6出来了,它并不开源,但是可以免费做商用,而且其中的功能还是不错的,而且它不依赖于其他任何库,但是它对于opencv还是挺支持的,这个项目的主要功能包括
1,人脸检测
2,关键点提取
3,人脸识别
4,眼睛状态
5,/活体检测
6,人脸追踪
7,状态评估
我把它的大部分功能都封装成了一个类,大家需要注意我封装文件中所对应的模型文件路径,我把它都放在同目录的model下
这个项目我感觉是非常好用的,我用的是vs2017搭配的环境,至于配置方法,可以参考vs2017搭配opencv环境,百度一搜就有,
这个封装非常精炼,可以说涵盖了它大部分主要功能.话不多说,代码奉上
ps:你看不懂封装代码没关系,尽管我已经在里面写了很多注释,我在问着末尾写了测试代码,是针对封装代码的测试,通俗易懂
ps2:一定要注意封装代码的模型路径否则会出错
#pragma once
#include<opencv2/opencv.hpp>
#include<memory>
#include<iostream>#include<seeta/FaceDetector.h>//人脸检测器
#include<seeta/FaceLandmarker.h>//关键点提取
#include<seeta/Common/Struct.h>
#include<seeta/FaceRecognizer.h>//人脸识别
#include<seeta/EyeStateDetector.h>//眼睛状态
#include<seeta/FaceAntiSpoofing.h>//活体检测
#include<seeta/FaceTracker.h>//人脸追踪#include<seeta/QualityOfBrightness.h>//亮度评估,判断人脸亮度值是都正常,过量或过暗评价LOW,0,1,2
#include<seeta/QualityOfClarity.h>//清晰度评估
#include<seeta/QualityOfIntegrity.h>//人脸完整度评估,判断人脸是否完全进入摄像头
#include<seeta/QualityOfPose.h>//姿态评估,通过人脸5点坐标值来判断姿态是否为正面。
#include<seeta/QualityOfResolution.h>//分辨率评估
#include<seeta/QualityStructure.h>//===============================补充
namespace seeta {class QualityOfNoMask : public QualityRule {public:QualityOfNoMask() {m_marker = std::make_shared<seeta::FaceLandmarker>(ModelSetting("./model/face_landmarker_mask_pts5.csta"));}QualityResult check(const SeetaImageData &image, const SeetaRect &face, const SeetaPointF *points, int32_t N) override {auto mask_points = m_marker->mark_v2(image, face);int mask_count = 0;for (auto point : mask_points) {if (point.mask) mask_count++;}QualityResult result;if (mask_count > 0) {return { QualityLevel::LOW, 1 - float(mask_count) / mask_points.size() };}else {return { QualityLevel::HIGH, 1 };}}private:std::shared_ptr<seeta::FaceLandmarker> m_marker;};
}/*
使用任何一个模型都一定要初始化,否则它会为一个空的检测器
*/
namespace seeta_pacakge {//========/============================================
#define Brightness 0
#define Clarity 1
#define Integrity 2
#define Pose 3
#define Resolution 4
#define NoMask 5//======================================================================================================存放检测器地址seeta::FaceLandmarker *facelandmarker;seeta::FaceDetector *facedector;seeta::FaceRecognizer *facerecognizer;seeta::EyeStateDetector *eyestatedector;seeta::FaceAntiSpoofing *faceantspoofing;seeta::FaceTracker *facetracker;seeta::QualityRule *qualityrelu;//======================================================================================================const char* FaceDector_path = "./model/face_detector.csta";//人脸检测模型const char* FaceLandmarker_path = "./model/face_landmarker_pts5.csta";//五点检测模型const char* FaceRecognizer_path = "./model/face_recognizer.csta";//人脸特征匹配和对比模型const char* EyeStateDetector_path = "./model/eye_state.csta";//眼睛状态检测模型const char* fasfirst_path = "./model/fas_first.csta";//局部活体const char* fassecond_path = "./model/fas_second.csta";//全局活体const char* face_landmarker_mask_pts5_path = "./model/face_landmarker_mask_pts5.ctsa";//===============================================================================================================人脸识别块=void facerecognizer_init(){seeta::ModelSetting setting;setting.append(FaceRecognizer_path);facerecognizer = new seeta::FaceRecognizer(setting);}//获取图片中特征float* extract_feature(const SeetaImageData& simg, std::vector<SeetaPointF> faces){if (facerecognizer == NULL){std::cout << "dont init facerecongizer";throw 1;}SeetaPointF points[5];for (int i = 0; i < 5; i++){points[i] = faces.at(i);// std::cout << points[i].x << "," << points[i].y << std::endl;}float* feature = new float[facerecognizer->GetExtractFeatureSize()];facerecognizer->Extract(simg, points, feature);return feature;}
//比较两个特征判断是否相似float compare(float* feature1, float* feature2){return facerecognizer->CalculateSimilarity(feature1, feature2);}//====================================================================================人脸特征点提取块===================void facelandmarker_init(){seeta::ModelSetting setting;setting.append(FaceLandmarker_path);facelandmarker = new seeta::FaceLandmarker(setting);}//提取图像中人脸的特征点std::vector<SeetaPointF> mark(const SeetaImageData& image, const SeetaRect& face){if (facelandmarker == NULL){std::cout << "dont init facelandmarker";throw 1;}return facelandmarker->mark(image, face);//这里检测到的5点坐标循序依次为,左眼中心、右眼中心、鼻尖、左嘴角和右嘴角。}//==================================================================================================人脸检测(base)======void facedector_init(){seeta::ModelSetting setting;setting.append(FaceDector_path);facedector = new seeta::FaceDetector(setting);}//检测人脸并放到数组中SeetaFaceInfoArray detect(const SeetaImageData &image){if (facedector == NULL){std::cout << "dont init facedector";throw 1;}return facedector->detect(image);}
//按人脸大小排列人脸数组void sort(SeetaFaceInfoArray face_sfia){int m = face_sfia.size;std::vector<SeetaFaceInfo> faces(m);for (int i = 0; i < face_sfia.size; i++){faces.at(i) = face_sfia.data[i];}std::partial_sort(faces.begin(), faces.begin() + 1, faces.end(), [](SeetaFaceInfo a, SeetaFaceInfo b) {return a.pos.width > b.pos.width;});for (int i = 0; i < face_sfia.size; i++){face_sfia.data[i] = faces.at(i);}}//==========================================================眼部特征提取const char *EYE_STATE_STR[] = { "close", "open", "random", "unknown" };void eyestatedector_init(){seeta::ModelSetting setting;setting.append(EyeStateDetector_path);eyestatedector = new seeta::EyeStateDetector(setting);}int* eye_state(const SeetaImageData &img, const std::vector<SeetaPointF> &points){if (eyestatedector == NULL){std::cout << "eyestatedector dont init";throw 1;}seeta::EyeStateDetector::EYE_STATE left_eye, right_eye;int status[2];eyestatedector->Detect(img, points.data(), left_eye, right_eye);status[0] = left_eye;status[1] = right_eye;return status;}//==============================活体检测==================================================================const char *SPOOF_STATE_STR[] = { "real face","spoof face","unknown","judging" };//0局部//1全局//2局部+全局void faceantspoofing_init(int version = 0){seeta::ModelSetting setting;switch (version){case 0:setting.append(fasfirst_path);break;case 1:setting.append(fassecond_path);break;case 2:setting.append(fasfirst_path);setting.append(fassecond_path);break;default:std::cout << "version input error";throw 2;}faceantspoofing = new seeta::FaceAntiSpoofing(setting);}int predict(const SeetaImageData &image,const SeetaRect &face,std::vector<SeetaPointF> v_points,int way = 0)//如果是0为单帧识别,1为多帧识别{if (faceantspoofing == NULL){std::cout << "faceantspoofing dont init";throw 1;}SeetaPointF points[5];for (int i = 0; i < 5; i++){points[i] = v_points.at(i);}int status;switch (way){case 0:status = faceantspoofing->Predict(image, face, points);break;case 1:status = faceantspoofing->PredictVideo(image, face, points);break;default:std::cout << "way input error";throw 2;}auto status1 = faceantspoofing->PredictVideo(image, face, points);switch (status1) {case seeta::FaceAntiSpoofing::REAL:std::cout << "真实人脸" << std::endl; break;case seeta::FaceAntiSpoofing::SPOOF:std::cout << "攻击人脸" << std::endl; break;case seeta::FaceAntiSpoofing::FUZZY:std::cout << "无法判断" << std::endl; break;case seeta::FaceAntiSpoofing::DETECTING:std::cout << "正在检测" << std::endl; break;}return status;}void reset_video() {faceantspoofing->ResetVideo();}void set_frame(int32_t number){faceantspoofing->SetVideoFrameCount(number);//默认是10;}//=======================================================================================================SeetaImageData mat_to_seetaImageData(cv::Mat& m){SeetaImageData* sid = new SeetaImageData();sid->data = m.data;sid->channels = m.channels();sid->height = m.rows;sid->width = m.cols;return *sid;}//=======================================人脸追踪=====================================void facetracker_init(int width, int height){seeta::ModelSetting setting;setting.append(FaceDector_path);facetracker = new seeta::FaceTracker(setting, width, height);}std::vector<SeetaTrackingFaceInfo> tracker(const SeetaImageData &image){if (facetracker == NULL){std::cout << "facetracker dont init";throw 1;}SeetaTrackingFaceInfoArray cfaces = facetracker->Track(image);std::vector<SeetaTrackingFaceInfo> faces(cfaces.data, cfaces.data + cfaces.size);return faces;}//========================质量评估==================================================void qualityrelu_init(int choose){switch (choose){case Brightness: qualityrelu = new seeta::QualityOfBrightness();//亮度case Clarity: qualityrelu = new seeta::QualityOfClarity();//清晰度case Integrity:qualityrelu = new seeta::QualityOfIntegrity();//完整度case Pose:qualityrelu = new seeta::QualityOfPose();//姿态case Resolution: qualityrelu = new seeta::QualityOfResolution();//分辨率case NoMask:qualityrelu = new seeta::QualityOfNoMask();}}const char *level_string[] = { "LOW", "MEDIUM", "HIGH" };int plot_quality(const SeetaImageData &image,const SeetaRect &face,const std::vector < SeetaPointF>& points){seeta::QualityResult result = qualityrelu->check(image, face, points.data(), int(points.size()));return result.level;}
}
当然,这个包装库我写的时候也一一测试了功能了,测试代码奉上
#include"seeta_own.h"
#include<Windows.h>using namespace std;
using namespace cv;
using namespace seeta_pacakge;
//打开E:/source/test.jpg检测人脸并显示
//打开E:/source/test2.jpg检测到人脸后与test.jpg的人脸进行匹配
//最后会打印这两张脸相似度,注意,如果一张照片有多张脸,这里设置的是只提取最大的一张脸
void test1()
{Mat m = imread("E:/source/test.jpg");facedector_init();facelandmarker_init();facerecognizer_init();SeetaImageData sid = mat_to_seetaImageData(m);SeetaFaceInfoArray sfia = detect(sid);sort(sfia);if (sfia.data <= 0){cout << "未检测到脸";system("pause");}vector<SeetaPointF> spf = mark(sid, sfia.data[0].pos);rectangle(m, Rect(sfia.data[0].pos.x, sfia.data[0].pos.y, sfia.data[0].pos.width, sfia.data[0].pos.height), Scalar(0, 0, 255));for (int i = 0; i < 5; i++){circle(m, Point(spf.at(i).x, spf.at(i).y), 5, Scalar(0, 255, 0));}imshow("1", m);float* feature = extract_feature(sid, spf);Mat m2 = imread("E:/source/test2.jpg");SeetaImageData sid2 = mat_to_seetaImageData(m2);SeetaFaceInfoArray sfia2 = detect(sid2);sort(sfia2);vector<SeetaPointF> spf2 = mark(sid2, sfia2.data[0].pos);float* feature2 = extract_feature(sid2, spf2);cout << "大小" << facerecognizer->GetExtractFeatureSize();std::cout << "相似度" << facerecognizer->CalculateSimilarity(feature, feature2) << std::endl;for (int j = 0; j < 2048; j++)std::cout << j << "...." << feature2[j] << std::endl;float* f = new float[1024];for (int o = 0; o < 1024; o++)f[o] = feature[o];std::cout << "2相似度" << compare(f, feature2);waitKey(0);
}
//打开摄像头,检测眼睛状态并显示以及打印
void test2()
{facedector_init();facelandmarker_init();eyestatedector_init();VideoCapture videocapture(0);Mat mat;while (videocapture.isOpened()){videocapture.read(mat);flip(mat, mat,1);SeetaImageData sid=mat_to_seetaImageData(mat);SeetaFaceInfoArray sfia=detect(sid);sort(sfia);vector<SeetaPointF> spf =mark(sid, sfia.data[0].pos);int* eye=eye_state(sid, spf);cout << "左眼:" << eye[0] << EYE_STATE_STR[eye[0]]<< " "<< "右眼:" << eye[1] << EYE_STATE_STR[eye[1]]<<std::endl;imshow("1", mat);waitKey(1);}
}
//读取test.jpg,打开摄像头,分析摄像头的人脸与test.jpg是否相似,并在控制台打印结果
void test3()
{facedector_init();facelandmarker_init();eyestatedector_init();facerecognizer_init();Mat ori = imread("E:/source/test2.jpg");SeetaImageData sid_ori = mat_to_seetaImageData(ori);SeetaFaceInfoArray sfia_ori = detect(sid_ori);sort(sfia_ori);vector<SeetaPointF> spf2=mark(sid_ori, sfia_ori.data[0].pos);float* ori_ss = extract_feature(sid_ori, spf2);VideoCapture videocapture(0);Mat mat;while (videocapture.isOpened()){videocapture.read(mat);flip(mat, mat, 1);SeetaImageData sid = mat_to_seetaImageData(mat);SeetaFaceInfoArray sfia = detect(sid);sort(sfia);vector<SeetaPointF> spf = mark(sid, sfia.data[0].pos);float* curr=extract_feature(sid, spf);std::cout << compare(curr, ori_ss) << std::endl;imshow("1", mat);waitKey(1);}
}//下面的自己看吧,活体检测,状态检测等等void test4()
{facedector_init();facelandmarker_init();eyestatedector_init();facerecognizer_init();faceantspoofing_init();VideoCapture videocapture(0);Mat mat;while (videocapture.isOpened()){videocapture.read(mat);flip(mat, mat, 1);SeetaImageData sid = mat_to_seetaImageData(mat);SeetaFaceInfoArray sfia = detect(sid);sort(sfia);vector<SeetaPointF> spf = mark(sid, sfia.data[0].pos);int status=predict(sid, sfia.data[0].pos, spf,1);cout << status << SPOOF_STATE_STR[status] << std::endl;imshow("1", mat);waitKey(1);}}
void test5()
{facedector_init();facelandmarker_init();eyestatedector_init();facerecognizer_init();faceantspoofing_init();VideoCapture videocapture(0);facetracker_init(videocapture.get(CAP_PROP_FRAME_WIDTH),videocapture.get(CAP_PROP_FRAME_HEIGHT));Mat mat;while (videocapture.isOpened()){videocapture.read(mat);flip(mat, mat, 1);SeetaImageData sid = mat_to_seetaImageData(mat);auto tra=tracker(sid);for (int i = 0; i < tra.size(); i++){SeetaTrackingFaceInfo id=tra.at(i);rectangle(mat, Rect(id.pos.x, id.pos.y, id.pos.width, id.pos.height), Scalar(255, 0, 0));putText(mat, to_string(id.PID), Point(id.pos.x, id.pos.y), FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 23, 0), 4, 8);}imshow("1", mat);waitKey(1);}
}
void test6()
{facedector_init();facelandmarker_init();eyestatedector_init();facerecognizer_init();faceantspoofing_init();qualityrelu_init(NoMask);VideoCapture videocapture(0);Mat mat;while (videocapture.isOpened()){videocapture.read(mat);flip(mat, mat, 1);SeetaImageData sid = mat_to_seetaImageData(mat);SeetaFaceInfoArray sfia = detect(sid);sort(sfia);vector<SeetaPointF> spf = mark(sid, sfia.data[0].pos);imshow("1", mat);waitKey(1);int status=plot_quality(sid, sfia.data[0].pos, spf);std::cout << level_string[status] << std::endl;}
}
int main()
{test6();
}
如果有什么不对的地方可以给我留言
封装是没有问题的,我已经多次使用这个封装做过项目,如果遇到其他问题也可以给我留言
seetaface6教程:封装人脸识别,人脸检测,,眼睛检测,状态,特征.....相关推荐
- [转]人脸识别中的活体检测
https://zhuanlan.zhihu.com/p/25401788 早在指纹识别应用中就有针对于活体手指的检测技术,即使机器只对真人活体指纹产生识别反应,对其他一切物质不作识别,用于指纹识别产 ...
- 计算机视觉子方向,计算机视觉方向简介 | 人脸识别中的活体检测算法综述
原标题:计算机视觉方向简介 | 人脸识别中的活体检测算法综述 本文转载自"SIGAI人工智能学习与实践平台"(ID:SIGAICN) 导言 1. 什么是活体检测? 判断捕捉到的人脸 ...
- 人脸识别中的活体检测算法
人脸识别中的活体检测算法综述 1. 什么是活体检测? 判断捕捉到的人脸是真实人脸,还是伪造的人脸攻击(如:彩色纸张打印人脸图,电子设备屏幕中的人脸数字图像 以及 面具 等) 2. 为什么需要活体检测? ...
- CV之FR之MTCNN:基于TF框架利用MTCNN算法检测并对齐人脸图像进(人脸识别/人脸相似度)而得出人脸特征向量从而计算两张人脸图片距离案例应用之详细攻略
CV之FR之MTCNN:基于TF框架利用MTCNN算法检测并对齐人脸图像进(人脸识别/人脸相似度)而得出人脸特征向量从而计算两张人脸图片距离案例应用之详细攻略 目录 基于TF框架利用MTCNN算法检测 ...
- 虹软人脸识别 - 人脸特征数据的存取
虹软人脸识别 - 人脸特征数据的存取 文章目录 虹软人脸识别 - 人脸特征数据的存取 一.简介 二.数据库应用 1. 连接数据库 2. 建表 3. 注册人脸并保存其特征值到数据库 4. 获取人脸特征数 ...
- K210人脸识别+人脸信息存储
K210系列教程 使用MaixPy IDE开发K210 K210实现人脸识别(附代码解读) K210人脸识别+人脸信息存储 K210人脸识别+RFID录入信息 在我的上一篇博客中已经介绍了如何使用K2 ...
- 人脸识别_云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案
云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案 人脸识别闸机-人脸识别闸机解决方案 软硬一体的人脸识别闸机解决方案,提升人员系统化管理的安全性与便捷性 方案构成 针对人员出入的闸机及门禁场 ...
- 人脸反光识别和读数识别_云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案...
云端人脸识别-人脸识别SDK+API-人脸识别闸机解决方案 人脸识别闸机-人脸识别闸机解决方案 软硬一体的人脸识别闸机解决方案,提升人员系统化管理的安全性与便捷性 方案构成 针对人员出入的闸机及门禁场 ...
- 初识人脸识别---人脸识别研究报告(概述篇)
不知道自己喜欢做什么,这对于一个可能打算成为程序员的程序员来说,可能是悲哀的.--------写在之前 经过有一段时间的思考,觉得自己有必要对那些几年来特别火的词语重新做个了解,人工智能,大数据,云计 ...
- 微信小程序公众号支付宝小程序的登录授权、支付、分享、人脸识别人脸核身
文章目录 一.微信小程序 1. 获取信息用户信息 2.支付 3.分享 4. 腾讯云小程序人脸核身 二.微信公众号 1.获取信息用户信息 2.支付 3. 分享(普通分享) 4.分享(vue单页面 配置分 ...
最新文章
- cisco aaa 授权后门测试
- Oracle日期转换处理
- Go 面向对象三大特性
- wcf系列学习5天速成——第五天 服务托管
- 如何把一个软件嵌入另一个软件_自动化正在成为一个“软件”行业
- 中小学计算机教学大纲,中小学信息技术教材教法教学大纲
- 电子产品设计emc风险评估_书籍介绍:EMC设计方法与风险评估技术
- Linux故障之grub
- react native 学习
- Linux系统java进程产生的core文件导致宕机原因排查
- 安卓系统如何访问wincc服务器,wincc客户端读取服务器数据库
- Favicon网页收藏图标在线制作PHP网站源码/ICO图片在线生成/支持多种图片格式转换
- 关于梅花雪 MzTreeView2.0 checkbox 的用法
- 写计算机课的作文,电脑课作文(小学生作文写不好怎么办)
- 启动修复 您想用系统还原还原计算机吗,sony笔记本电脑如何恢复系统
- 在光伏并网柜保护监测领域安科瑞给出的解决方案
- 2017年下半年中学综合素质问答题
- 滚动条兼容火狐浏览器
- Symantex Endpoint Protection赛门铁克杀毒软件安装
- 12306系统架构优化