基于Xcode10的Seetaface人脸检测
未经本人授权,禁止转载
1. 简介
毕业设计需要用到人脸检测,本人对此并不了解,导师推荐了几个近几年比较新的算法,决定先来试试这个山世光老师的Seetaface,那么废话不多说,我们一起开始吧。
2. 准备
2.1 下载Seetaface引擎
继Seetaface之后,山世光团队公布了Seetaface2。这里使用Seetaface,贴出Github Seetaface。
2.2 其他工具
OpenCV 2.4.13.1
CMake 3.7.2
推荐使用homebrew进行安装,如果不会的话请自行百度(百度有很多详细教程,这里就不介绍啦)。
3. 生成动态链接库
这里借鉴了seutwom_J的简书,在此表示衷心的感谢。
正式开始吧,Seetaface总共包含FaceDetection、FaceAlignment、FaceIdentification三个模块,简单的可以理解为这三个模块循序渐进的实现了人脸检测。第一个FaceDetection模块给出的示例是检测人脸,第二个FaceAlignment模块给出的示例是检测五官,第三个FaceIdentification模块给出的示例是人脸相似度检测。此次只用到了前两个模块,以后有机会会尝试使用第三个模块。
3.1 FaceDetection
在终端进入FaceDetection目录下,依次执行每行命令:
mkdir build
cd build
cmake ..
make
执行完make后得到如下结果:

在终端继续执行命令:
./facedet_test ../data/0_1_1.jpg ../model/seeta_fd_frontal_v1.0.bin
执行完后得出如下结果:

测试结果表示FaceDetection模块的动态链接库已经编译成功了。
3.2 FaceAlignment
在终端进入FaceAlignment目录下,依次执行每行命令:
mkdir build
cd build
将FaceDetection中的/include/face_detection.h和/build/libseeta_facedet_lib.dylib和/model/seeta_fd_frontal_v1.0.bin拷贝到/FaceAlignment/build文件夹下。如下:

修改FaceAlignment目录中的CMakeLists.txt的第一行为:
cmake_minimum_required(VERSION 3.0)
修改FaceAlignment中的/src/test/face_alignmen_test.cpp文件,将第47、48、54行的路径修改为"../data/"、"../model/"、"../build/seeta_fd_frontal_v1.0.bin",如下:

在终端继续依次执行每行命令:
cmake ..
make
执行完make后得到如下结果:

在终端继续执行命令:
./fa_test
在FaceAlignment中的/build目录下生成了图片文件"result.jpg"如下:

测试结果表示FaceAlignment模块的动态链接库已经编译成功了,至此为止我们需要的东西都已经准备就绪,赶紧正式开始使用Seetaface吧。
4. 配置Xcode环境
- 创建新项目,选择Command line Tool,语言选择C++


- 配置OpenCV
找到你的OpenCV文件夹,如果你是使用homebrew下载的,那么路径应该是/usr/local/Cellar/opencv@2/2.4.13.7_2,如下:

将lib文件夹内的所有文件拖入项目设置General中的Linked Frameworks and LibraLibraries中:

在Build Settings中添加环境变量(根据自己的路径):

注意在Build Settings中修改一下Documentation Comments,忽略掉第三方注释:

OpenCV配置完毕。
- 配置Seetaface
将/FaceAlignment/build目录中的两个.dylib文件拖入项目设置General中的Linked Frameworks and LibraLibraries中,并修改Required为Optional:

关键的一步,同时将这两个.dylib文件拷贝到项目文件夹Products中:

在Build Settings中添加环境变量(根据自己的路径):


最后一步,将/FaceDetection/model/seeta_fd_frontal_v1.0.bin和/FaceAlignment/model/seeta_fa_v1.1.bin两个训练模型放入项目文件夹中:

至此为止所有训练模型配置完毕,环境变量配置完毕,动态链接库添加完毕。
5. 示例代码测试
直接拷贝以下代码到main.cpp中,一定注意设置好路径。
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include "face_detection.h"
#include "face_alignment.h"
int main()
{
// Initialize face detection model
seeta::FaceDetection detector("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("seeta_fa_v1.1.bin");//相对路径
//load image
IplImage *img_grayscale = NULL;
img_grayscale = cvLoadImage("image_0001.png", 0);//相对路径
if (img_grayscale == NULL)
{
return 0;
}
IplImage *img_color = cvLoadImage("image_0001.png", 1);//相对路径
int pts_num = 5;
int im_width = img_grayscale->width;
int im_height = img_grayscale->height;
unsigned char* data = new unsigned char[im_width * im_height];
unsigned char* data_ptr = data;
unsigned char* image_data_ptr = (unsigned char*)img_grayscale->imageData;
int h = 0;
for (h = 0; h < im_height; h++) {
memcpy(data_ptr, image_data_ptr, im_width);
data_ptr += im_width;
image_data_ptr += img_grayscale->widthStep;
}
seeta::ImageData image_data;
image_data.data = data;
image_data.width = im_width;
image_data.height = im_height;
image_data.num_channels = 1;
// Detect faces
std::vector<seeta::FaceInfo> faces = detector.Detect(image_data);
int32_t face_num = static_cast<int32_t>(faces.size());
if (face_num == 0)
{
delete[]data;
cvReleaseImage(&img_grayscale);
cvReleaseImage(&img_color);
return 0;
}
// Detect 5 facial landmarks
seeta::FacialLandmark points[5];
point_detector.PointDetectLandmarks(image_data, faces[0], points);
// Visualize the results
cvRectangle(img_color, cvPoint(faces[0].bbox.x, faces[0].bbox.y), cvPoint(faces[0].bbox.x + faces[0].bbox.width - 1, faces[0].bbox.y + faces[0].bbox.height - 1), CV_RGB(255, 0, 0));
for (int i = 0; i<pts_num; i++)
{
cvCircle(img_color, cvPoint(points[i].x, points[i].y), 2, CV_RGB(0, 255, 0), CV_FILLED);
}
cvSaveImage("result.jpg", img_color);
// Release memory
cvReleaseImage(&img_color);
cvReleaseImage(&img_grayscale);
delete[]data;
return 0;
}
最后得到结果如下:

后续就可以参照Seetaface给出的示例代码进行自己的开发了。
最后希望大家能关注一下,点个喜欢,后续一定会有更多高质量的干货,感谢不尽!