SeetaFaceEngine系列3:Face Identification编译和使用
前面两篇介绍了怎样编译SeetaFace的前两部分,现在就来讲下第三部分Face Identification的编译和使用。
其实,步骤基本上是一直的,如下:
1、新建一个空的DLL工程;
2、修改配置器;
3、添加include
4、添加lib文件路径和依赖项
5、修改预处理器
6、打开OpenMP
7、添加源文件到工程中
这里,将FaceIdentification\src文件夹下的所有文件(test除外)添加到工程中:
8、编译工程得到lib文件和dll文件(Release的步骤也是一样的)
9、使用Face Identification进行人脸匹配
FaceIdentification\src\test文件夹下有两个测试文件test_face_recognizer.cpp和test_face_verification.cpp,其中test_face_recognizer.cpp是测试各项功能的,包括人脸剪切、特征提取和匹配,后者是直接输入两幅图,计算匹配度,这里我测试了第二个的功能。
代码如下:
int testFaceRecognizer(std::string src_Path1, std::string src_Path2)
{
seeta::FaceDetection detector("D:/SeetaFaceEngine/include_lib/model/FaceDetection/seeta_fd_frontal_v1.0.bin");
detector.SetMinFaceSize(40);
detector.SetScoreThresh(2.f);
detector.SetImagePyramidScaleFactor(0.8f);
detector.SetWindowStep(4, 4);
// Initialize face alignment model
seeta::FaceAlignment point_detector("D:/SeetaFaceEngine/include_lib/model/FaceAlignment/seeta_fa_v1.1.bin");
// Initialize face Identification model
seeta::FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str());
std::string test_dir = DATA_DIR + "test_face_recognizer/";
//load image
cv::Mat gallery_img_color = cv::imread(src_Path1, 1);
cv::Mat gallery_img_gray;
cv::cvtColor(gallery_img_color, gallery_img_gray, CV_BGR2GRAY);
cv::Mat probe_img_color = cv::imread(src_Path2, 1);
cv::Mat probe_img_gray;
cv::cvtColor(probe_img_color, probe_img_gray, CV_BGR2GRAY);
seeta::ImageData gallery_img_data_color(gallery_img_color.cols, gallery_img_color.rows, gallery_img_color.channels());
gallery_img_data_color.data = gallery_img_color.data;
seeta::ImageData gallery_img_data_gray(gallery_img_gray.cols, gallery_img_gray.rows, gallery_img_gray.channels());
gallery_img_data_gray.data = gallery_img_gray.data;
seeta::ImageData probe_img_data_color(probe_img_color.cols, probe_img_color.rows, probe_img_color.channels());
probe_img_data_color.data = probe_img_color.data;
seeta::ImageData probe_img_data_gray(probe_img_gray.cols, probe_img_gray.rows, probe_img_gray.channels());
probe_img_data_gray.data = probe_img_gray.data;
// Detect faces
std::vector<seeta::FaceInfo> gallery_faces = detector.Detect(gallery_img_data_gray);
int32_t gallery_face_num = static_cast<int32_t>(gallery_faces.size());
std::vector<seeta::FaceInfo> probe_faces = detector.Detect(probe_img_data_gray);
int32_t probe_face_num = static_cast<int32_t>(probe_faces.size());
if (gallery_face_num == 0 || probe_face_num == 0)
{
std::cout << "Faces are not detected.";
return 0;
}
// Detect 5 facial landmarks
seeta::FacialLandmark gallery_points[5];
point_detector.PointDetectLandmarks(gallery_img_data_gray, gallery_faces[0], gallery_points);
seeta::FacialLandmark probe_points[5];
point_detector.PointDetectLandmarks(probe_img_data_gray, probe_faces[0], probe_points);
for (int i = 0; i < 5; i++)
{
cv::circle(gallery_img_color, cv::Point(gallery_points[i].x, gallery_points[i].y), 2,CV_RGB(0, 255, 0));
cv::circle(probe_img_color, cv::Point(probe_points[i].x, probe_points[i].y), 2, CV_RGB(0, 255, 0));
}
cv::imshow("gallery_point_result.jpg", gallery_img_color);
cv::imshow("probe_point_result.jpg", probe_img_color);
// Extract face identity feature
float gallery_fea[2048];
float probe_fea[2048];
face_recognizer.ExtractFeatureWithCrop(gallery_img_data_color, gallery_points, gallery_fea);
face_recognizer.ExtractFeatureWithCrop(probe_img_data_color, probe_points, probe_fea);
// Caculate similarity of two faces
float sim = face_recognizer.CalcSimilarity(gallery_fea, probe_fea);
std::cout << sim << std::endl;
cv::waitKey(0);
}
匹配的结果如下:
两幅人脸的相似度是0.6850。
OK,至此,SeetaFace的三个功能基本就介绍完了。那人脸检测和识别的库有很多很多很多很多...很多,然后我之所以要用下这个,原因也很简单,其他开源库要依赖的东西稍微多一些,这个库相对就少,唯一一个依赖的也是OpenCV,配置真的也挺简单的,速度也勉强可以接受,所以如果不是要求多高的话,还是可以用这个库玩一下的。
你可以重复着初恋
却不能重复热情
你可以重复那些后悔
却重复不了 最爱
--旖旎 《永远的夏娃·断章》
SeetaFaceEngine系列3:Face Identification编译和使用的更多相关文章
- SeetaFaceEngine系列1:Face Detection编译和使用
SeetaFace,根据GitHub上的介绍,就是一个开源的人脸检测.矫正和识别的开源库,是采用C++来编写的,并且是在CPU上执行的,没有用到GPU,但是可以用SSE或者OpenMP来加速.整个库分 ...
- SeetaFaceEngine系列2:Face Alignment编译和使用
前面一篇写了编译人脸检测部分,现在就介绍下人脸配准部分,SeetaFace的Face Alignment通过人脸的五个关键点来配准人脸,也就是双眼.鼻尖.两个嘴角. 这部分的编译也和上一篇一样,步骤如 ...
- Linux Kernel系列三:Kernel编译和链接中的linker script语法详解
先要讲讲这个问题是怎么来的.(咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么). 我在编译内核的时候,发现arch/arm/kernel目录下有 ...
- spring源代码系列(一)sring源代码编译 spring源代码下载 spring源代码阅读
想对spring框架进行深入的学习一下,看看源码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建好开发环境吧. 环境搭建 sping源代码之前是svn管理,如今已经迁移到了github中了.新版本 ...
- [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
在mingw32如果想编译libopenjpeg 会比较麻烦 会出现undefined reference to `_imp__opj_destroy_cstr_info@4' 等错误 因此编译时候需 ...
- [ffmpeg 扩展第三方库编译系列] 关于libvpx mingw32编译问题
在编译libvpx的时候遇到挺多的问题, 1.[STRIP] libvpx.a < libvpx_g.a strip: Bad file number 这个错误也是比较难搞的,一开始以为只是 ...
- [ffmpeg 扩展第三方库编译系列] frei0r mingw32 下编译问题
在编译安装frei0r的时候遇到两个错误地方, 两个都是在install的时候. 一开始编译都很顺利,输入了 make install之后就走开了,回来一看,报错误. 提示mkdir -p //usr ...
- [ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca
在编译前最好先看一下帮助 ./configure --help 开始编译 ./configure --disable-shared --disable-cxx \ --disable-csharp ...
- 初识google多语言通信框架gRPC系列(二)编译gRPC
目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义类之外,还需要 ...
随机推荐
- Live555研究之一 源代码编译
Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编码格式的音视频数据的流化 ...
- C++(五)构造函数
//构造函数的作用:就是在函数被创建时使用特定的值构造对象,将对象初始化为一个特定的初始状态//例如在构造一个clock类对象的时候,将初始的时间设定为0:0:0//构造函数的名必须与类名相同,不能定 ...
- Rabbitmq之高级特性——实现消费端限流&NACK重回队列
如果是高并发下,rabbitmq服务器上收到成千上万条消息,那么当打开消费端时,这些消息必定喷涌而来,导致消费端消费不过来甚至挂掉都有可能. 在非自动确认的模式下,可以采用限流模式,rabbitmq ...
- Oracle IF-ELSE条件判断结构
关于条件判断的几个函数: 一.IF-ELSE 判断语句1.IF 语法 IF 表达式 THEN ... END IF; 输入账号名 kiki 以登陆账号 declare v_name ):='& ...
- 149-PHP大小写转换函数
<?php $str='PHP is a very good programming language.'; //定义一个字符串 echo "未经处理的字符串:<br /> ...
- 102-PHP多维数组的元素输出
<?php //定义一个三维数组 $grade=array('class1'=>array('stu1'=>array('yuwen'=>85,'shuxue'=>95, ...
- StackExchange.Redis.DLL 操作redis加强版
直接引用StackExchange.Redis.dll这一个dll来操作redis App.config配置 <?xml version="1.0" encoding=&qu ...
- POJ 3461:Oulipo
Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28155 Accepted: 11251 Descript ...
- Java算法练习——最长公共前缀
题目链接 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 说明: 所有输入只包含小写字母 a-z . 示例 1 输入: [&qu ...
- 不得了的try catch
try catch:几乎所有语言都有这个语句 try { //可能会导致错误的代码 } catch (error) { //在错误发生时怎么处理 }finally { //即使报错始终执行 } 1. ...