前言
基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库)、Caffe(深度学习库)、Dlib(机器学习库)、libfacedetection(人脸检测库)、cudnn(gpu加速库)。
用到了一个开源的深度学习模型:VGG model。
最终的效果是很赞的,识别一张人脸的速度是0.039秒,而且最重要的是:精度高啊!!!
CPU:intel i5-4590
GPU:GTX 980
系统:Win 10
OpenCV版本:3.1(这个无所谓)
Caffe版本:Microsoft caffe (微软编译的Caffe,安装方便,在这里安利一波)
Dlib版本:19.0(也无所谓
CUDA版本:7.5
cudnn版本:4
libfacedetection:6月份之后的(这个有所谓,6月后出了64位版本的)
这个系列纯C++构成,有问题的各位朋同学可以直接在博客下留言,我们互相交流学习。
====================================================================
本篇是该系列的第二篇博客,介绍我如何设计人脸检测与预处理的接口。
思路
人脸检测与预处理作为人脸识别的步骤之一,其质量能够直接影响识别的精度。而如何在保持精度的条件下最大化运行速度也是需要注意的地方。这里我们不使用OpenCV自带的分类器,而使用一个开源的windows平台下的人脸检测库。具体可以看我的这篇博客:
http://blog.csdn.net/mr_curry/article/details/51804072
那么首先,我们先需要检测出人脸。新建FaceDetect.h,FaceRotate.h,FaceProcessing.h,一个FaceDetect.cpp,FaceProcessing.cpp开始编写。(这里假定你已经添加好dlib的属性表了)
注:下面的人脸预处理函数,是IEEE数据库上的一篇论文所述的方法,2011年的
FaceDetect.h:(提供一个总的接口)
#include "facedetect-dll.h"
#include <opencv.hpp>
using namespace cv;
// define
Mat Facedetect(Mat frame);
//dlib的配置函数 后面几章会讲
void Dlib_Prodefine();
FaceRotate.h:(用于关键点矫正)
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include<dlib/opencv/cv_image.h>
#include <dlib/opencv.h>
using namespace dlib;
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor sp;//Already get
FaceProcessing.h:(用于对人脸进行预处理)
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat FaceProcessing(const Mat &img_, double gamma = 0.2, double sigma0 = 1, double sigma1 = -2, double mask = 0, double do_norm = 10);
FaceProcessing.cpp:
#include"FaceProcessing.h"
int gauss(float x[], float y[], int length, float sigma);
Mat gaussianfilter(Mat img, double sigma0, double sigma1, double shift1, double shift2);
Mat FaceProcessing(const Mat &img_, double gamma = 0.2, double sigma0 = 1, double sigma1 = -2, double mask = 0, double do_norm = 10);
//找出矩阵中的最大值或最小值,输入MAX,或MIN
double MatMaxMin(Mat im, String flag = "MAX")
{
double value = im.ptr<float>(0)[0];
if (flag == "MAX")
{
for (int i = 0; i<im.rows; i++)
for (int j = 0; j<im.cols; j++)
if (im.ptr<float>(i)[j]>value)
value = im.ptr<float>(i)[j];
return value;
}
else if (flag == "MIN")
{
for