前面两篇介绍了怎样编译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编译和使用的更多相关文章

  1. SeetaFaceEngine系列1:Face Detection编译和使用

    SeetaFace,根据GitHub上的介绍,就是一个开源的人脸检测.矫正和识别的开源库,是采用C++来编写的,并且是在CPU上执行的,没有用到GPU,但是可以用SSE或者OpenMP来加速.整个库分 ...

  2. SeetaFaceEngine系列2:Face Alignment编译和使用

    前面一篇写了编译人脸检测部分,现在就介绍下人脸配准部分,SeetaFace的Face Alignment通过人脸的五个关键点来配准人脸,也就是双眼.鼻尖.两个嘴角. 这部分的编译也和上一篇一样,步骤如 ...

  3. Linux Kernel系列三:Kernel编译和链接中的linker script语法详解

    先要讲讲这个问题是怎么来的.(咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么). 我在编译内核的时候,发现arch/arm/kernel目录下有 ...

  4. spring源代码系列(一)sring源代码编译 spring源代码下载 spring源代码阅读

    想对spring框架进行深入的学习一下,看看源码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建好开发环境吧. 环境搭建 sping源代码之前是svn管理,如今已经迁移到了github中了.新版本 ...

  5. [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题

    在mingw32如果想编译libopenjpeg 会比较麻烦 会出现undefined reference to `_imp__opj_destroy_cstr_info@4' 等错误 因此编译时候需 ...

  6. [ffmpeg 扩展第三方库编译系列] 关于libvpx mingw32编译问题

    在编译libvpx的时候遇到挺多的问题, 1.[STRIP] libvpx.a < libvpx_g.a strip: Bad file number   这个错误也是比较难搞的,一开始以为只是 ...

  7. [ffmpeg 扩展第三方库编译系列] frei0r mingw32 下编译问题

    在编译安装frei0r的时候遇到两个错误地方, 两个都是在install的时候. 一开始编译都很顺利,输入了 make install之后就走开了,回来一看,报错误. 提示mkdir -p //usr ...

  8. [ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca

    在编译前最好先看一下帮助 ./configure --help 开始编译 ./configure  --disable-shared --disable-cxx \ --disable-csharp ...

  9. 初识google多语言通信框架gRPC系列(二)编译gRPC

    目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义类之外,还需要 ...

随机推荐

  1. Metasploitable学习(一)

    划红线的是执行语句,对已知的服务器的IP地址进行扫描.嗅探

  2. windows下java项目打包、启动批处理 .bat文件

    maven打包,脚本内容: @echo off echo 正在设置临时环境变量 set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_45 set MAVEN_HO ...

  3. Java对象序列化输入输出

    在网上看到一篇有关于对象序列化的代码,自己仿着写了把 在Java中,entity通过implements Serializable,然后使用ObjectInputStream和ObjectOutput ...

  4. Spring Cloud 支付宝支付的流程

    沙箱环境又称沙盘,为了开发与调试所提供的环境,它与生产环境互相隔离,但具有生产环境几乎完全相同的功能蚂蚁金服开放平台——开发者中心1.https://openhome.alipay.com2.提供的调 ...

  5. U盘安装Debian KDE 输入法 Manjaro Linux WPS 字体

    Manjaro: 首先下载Manjaro Linux,然后用USBWriter(https://pan.baidu.com/s/1bZGb5k)写入,重启选择USB启动. 更改软件仓库(Debian称 ...

  6. Impala 笔记

    简介 Cloudera公司推出,提供对HDFS.Hbase数据的高性能.低延迟的交互式SQL查询功能. 基于Hive使用内存计算,兼顾数据仓库.具有实时.批处理.多并发等优点 是CDH平台首选的PB级 ...

  7. 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法

    一.概述 React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. [父子组件]:组件的相互调用中,我们把调用者称为父 ...

  8. c++程序—输入

    #include<iostream> using namespace std; #include<string> int main() { string str = " ...

  9. tx2--开机启动

    TX2上电自动开机 参考:http://121.42.13.250/?p=168 问题描述 Jetson TX2在接通电源后,按下板子上的PWOER BTN开机键(S4)后,便能够正常启动.但这对于一 ...

  10. EUI库 - 9 - 数据集合 - 列表

      List 和DataGroup的区别 1 选中一项 会触发 eui.ItemEvent.ITEM_TAP 事件, 2 有选中项的概念,可以设置 List 里的默认选中项    selectedIn ...