您的位置:首页 > 其它

Dlib人脸特征点检测性能测试(光照+各部分功能模块运行时间)

2016-12-11 23:54 691 查看
惯例开头放结论:

1.光照对于人脸检测的影响非常大,光照充足且均匀更方便人脸检测

2.特征点匹配花费时间较少(每个大约3-5ms),人脸检测用640*480的摄像头大概每帧需要100ms,之后有空写一篇博客针对这个缺点进行算法改进。

-----------------------------------------------------------------------

今天上午在食堂测试Dlib人脸特征点检测程序,效果好到爆炸,所以忍不住来写一篇博客了……

首先放一张效果图吧,可以看出来即便扭头角度达到近乎九十度也能较好地识别出来(比之前在图书馆以及寝室以及实验室的效果要好很多)



初步分析为光照问题,本次测试是在光线充足且均匀的食堂,环境如下:



在寝室环境下80%的情况会检测不到人脸(效果很差),故而在结果层面,至少人脸检测部分对于光照的依赖性非常强。

在食堂环境下的动态效果如下:



在实验室光照一般情况下的效果:



在寝室基本检测不出人脸就不放图了

可以看得出来在实验室的时候脸稍微测一下基本就检测不出人脸了,但是在食堂环境下偏侧较大的角度仍能较为准确地检测出人脸……

故而均匀的光照是这种人脸检测方法的鲁棒性的必要条件

-----------------------------------

下面来看下Dlib人脸检测部分的代码,总共有两块核心内容:

1.人脸检测(也就是检测出有人脸)

核心代码如下:

        frontal_face_detector detector = get_frontal_face_detector();  

2.特定点定位(在人脸检测的矩形框基础之上进行特征点标定)

核心关键代码如下:

①载入训练好的模型:

        shape_predictor pose_model;  

        deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;  

②进行特征点定位:

            for (unsigned long i = 0; i < faces.size(); ++i)  

                shapes.push_back(pose_model(cimg, faces[i]));  

再返回来看之前的效果图(代码粘在下面):



这台笔记本的配置如下:



可以看出在I5四代标压双核处理器的笔记本上,载入模型花费时间大约在3秒左右

 

每帧检测人脸Detector函数耗时大约稳定在100ms(软件运行过多的情况下会到180ms)

 

每张脸特征点的提取大约在3-5ms,没有脸的时候近乎是0ms,测试两个人的时候大约在6-10ms。

两个人的检测效果如下(2333,女票实力马赛克):

 


可以料想的是绝大部分耗时都用在了人脸检测提取之上,这也是后续可能要花费大力气去解决的问题。

 

如果想移植到其他处理性能一般的平台上,检测人脸的部分肯定是需要大改的……

 

配置Dlib见博客:

http://blog.csdn.net/zmdsjtu/article/category/6399432

详细测试代码如下:
//@zmdsjtu@163.com
//2016-12-9

//http://blog.csdn.net/zmdsjtu/article/details/53454071
#include <dlib/opencv.h>
#include <opencv2/opencv.hpp>
#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 <Windows.h>
using namespace dlib;
using namespace std;
class 高精度计时
{
public:
高精度计时(void);
~高精度计时(void);//析构函数

private:
LARGE_INTEGER 开始时间;

LARGE_INTEGER 结束时间;

LARGE_INTEGER CPU频率;

public:
double 间隔;

public:
void 开始();
void 结束();
};

高精度计时::高精度计时(void)
{
QueryPerformanceFrequency(&CPU频率);
}

高精度计时::~高精度计时(void)
{
}

void 高精度计时::开始()
{
QueryPerformanceCounter(&开始时间);
}

void 高精度计时::结束()
{
QueryPerformanceCounter(&结束时间);

间隔 = ((double)结束时间.QuadPart - (double)开始时间.QuadPart) / (double)CPU频率.QuadPart;

}
int main()
{
高精度计时 时间;
try
{
时间.开始();
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Unable to connect to camera" << endl;
return 1;
}

//image_window win;

// Load face detection and pose estimation models.
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
时间.结束();
float 初始化时间 = 时间.间隔;
DWORD k = ::GetTickCount(); //获取毫秒级数目
// Grab and process frames until the main window is closed by the user.
while (cv::waitKey(30) != 27)
{
// Grab a frame
cv::Mat temp;
cap >> temp;

cv::putText(temp, "Initial Time/ms : " + to_string(初始化时间 * 1000), cv::Point(20, 380),5, 2, cvScalar(0, 0, 255));

cv_image<bgr_pixel> cimg(temp);
// Detect faces
// DWORD k = ::GetTickCount(); //获取毫秒级数目

std::vector<rectangle> faces = detector(cimg);
时间.结束();

cout << "检测人脸部分耗时:" << 时间.间隔*1000 << endl;
cv::putText(temp, "Face Detector/ms : " + to_string(时间.间隔 * 1000), cv::Point(20, 420),5,2, cvScalar(0, 0, 255));

// cout << (::GetTickCount() - k) << endl;
// Find the pose of each face.
std::vector<full_object_detection> shapes;
// k = ::GetTickCount();
时间.开始();
for (unsigned long i = 0; i < faces.size(); ++i)
shapes.push_back(pose_model(cimg, faces[i]));

if (!shapes.empty()) {
for (int j = 0; j < shapes.size();j++){
for (int i = 0; i < 68; i++) {
circle(temp, cvPoint(shapes[j].part(i).x(), shapes[j].part(i).y()), 2, cvScalar(255, 0, 0), -1);
// shapes[0].part(i).x();//68个
}
}

}
时间.结束();
cout << "剩余部分的总时间:"<< 时间.间隔 * 1000 << endl<<endl<<endl;
cv::putText(temp, "The rest/ms: "+to_string(时间.间隔 * 1000), cv::Point(20, 460),5, 2, cv::Scalar(0,0, 255));
//Display it all on the screen
imshow("Dlib特征点", temp);

}
}
catch (serialization_error& e)
{
cout << "You need dlib's default face landmarking model file to run this example." << endl;
cout << "You can get it from the following URL: " << endl;
cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
cout << endl << e.what() << endl;
system("pause");
}
catch (exception& e)
{
cout << e.what() << endl;
}
}



最后祝被打马赛克的人天天开心~

 

当然也祝大家开发愉快咯~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息