前言

最近又开始进行人脸检测方向的内容,看到于仕琪老师的多角度检测想试一下,还不清楚原理,先测试效果如何。

libfacedetect人脸检测库是深圳大学于仕琪老师发布的开源库,与opencv自带的人脸检测器相比,在速度和精度上都有较大的优势。

本文主要基于libfacedetect库测试人脸检测的效果。

环境

系统:win10_x64;

opencv版本:2410;

VisualStudio版本:VS2013;

注意,libfacedetect目前仅支持windows系统,86和64均可,且不支持多线程并行计算;

配置

1.下载libfacedetect开源库;

于老师的github

2.新建VS工程项目(此处为x64版本),添加或者配置opencv的属性表,opencv环境配置请参见here

3.项目属性中VC++目录选项中添加opencv和libfacedetect的包含目录和库目录;

libfacedetect包含目录:

.\libfacedetection-master\include

libfacedetect库目录:

.\libfacedetection-master\lib

3.链接器选项添加库文件到附加依赖项选项;

libfacedetect.lib       ------------ x86
libfacedetect-x64.lib ------------ x64

4.将bin目录下的dll文件放在exe的同一个目录,对应版本同步骤3;

至此,完成项目的环境配置;

测试

code:

单张图片测试

/*
The MIT License (MIT) Copyright (c) 2015-2017 Shiqi Yu
shiqi.yu@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ #include <stdio.h>
#include <opencv2/opencv.hpp>
#include "facedetect-dll.h"
//#pragma comment(lib,"libfacedetect.lib")
#pragma comment(lib,"libfacedetect-x64.lib") //define the buffer size. Do not change the size!
#define DETECT_BUFFER_SIZE 0x20000
using namespace cv; //int main(int argc, char* argv[])
int main( )
{
//load an image and convert it to gray (single-channel)
char* image_name = ".\\..\\images\\chloecalmon.png";
std::cout << image_name << std::endl;
Mat image = imread(image_name);
if (image.empty())
{
fprintf(stderr, "Can not load the image file %s.\n", image_name);
return -;
}
Mat gray;
cvtColor(image, gray, CV_BGR2GRAY); int * pResults = NULL;
//pBuffer is used in the detection functions.
//If you call functions in multiple threads, please create one buffer for each thread!
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
if (!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return -;
} int doLandmark = ; ///////////////////////////////////////////
// frontal face detection / 68 landmark detection
// it's fast, but cannot detect side view faces
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_frontal(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_frontal = image.clone();
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_frontal, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_frontal, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("Results_frontal", result_frontal); ///////////////////////////////////////////
// frontal face detection designed for video surveillance / 68 landmark detection
// it can detect faces with bad illumination.
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_frontal_surveillance(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark);
printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_frontal_surveillance = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_frontal_surveillance, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_frontal_surveillance, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("Results_frontal_surveillance", result_frontal_surveillance); ///////////////////////////////////////////
// multiview face detection / 68 landmark detection
// it can detect side view faces, but slower than facedetect_frontal().
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_multiview(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_multiview = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_multiview, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_multiview, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("Results_multiview", result_multiview); ///////////////////////////////////////////
// reinforced multiview face detection / 68 landmark detection
// it can detect side view faces, better but slower than facedetect_multiview().
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_multiview_reinforce = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_multiview_reinforce, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_multiview_reinforce, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("Results_multiview_reinforce", result_multiview_reinforce);
waitKey(); //release the buffer
free(pBuffer);
return ;
}

camera测试

/*
The MIT License (MIT) Copyright (c) 2015-2017 Shiqi Yu
shiqi.yu@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ #include <stdio.h>
#include <opencv2/opencv.hpp>
#include "facedetect-dll.h"
//#pragma comment(lib,"libfacedetect.lib")
#pragma comment(lib,"libfacedetect-x64.lib") //define the buffer size. Do not change the size!
#define DETECT_BUFFER_SIZE 0x20000
using namespace cv; //int main(int argc, char* argv[])
int main()
{
cv::VideoCapture capture;
capture.open();
if (!capture.isOpened())
{
std::cout << "video capture failed..." << std::endl;
return ;
}
cv::Mat image;
cv::namedWindow("video test", CV_WINDOW_NORMAL);
while (true)
{
image.release();
capture >> image;
cv::Mat gray;
cv::cvtColor(image, gray, CV_BGR2GRAY);
int * pResults = NULL;
//pBuffer is used in the detection functions.
//If you call functions in multiple threads, please create one buffer for each thread!
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
if (!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return -;
} int doLandmark = ; ///////////////////////////////////////////
// frontal face detection / 68 landmark detection
// it's fast, but cannot detect side view faces
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_frontal(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_frontal = image.clone();
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_frontal, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_frontal, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("video test", result_frontal); ///////////////////////////////////////////
// frontal face detection designed for video surveillance / 68 landmark detection
// it can detect faces with bad illumination.
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_frontal_surveillance(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark);
printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_frontal_surveillance = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_frontal_surveillance, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_frontal_surveillance, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("video test", result_frontal_surveillance); ///////////////////////////////////////////
// multiview face detection / 68 landmark detection
// it can detect side view faces, but slower than facedetect_frontal().
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_multiview(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_multiview = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_multiview, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_multiview, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("video test", result_multiview); ///////////////////////////////////////////
// reinforced multiview face detection / 68 landmark detection
// it can detect side view faces, better but slower than facedetect_multiview().
//////////////////////////////////////////
//!!! The input image must be a gray one (single-channel)
//!!! DO NOT RELEASE pResults !!!
pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr()), gray.cols, gray.rows, (int)gray.step,
1.2f, , , , doLandmark); printf("%d faces detected.\n", (pResults ? *pResults : ));
Mat result_multiview_reinforce = image.clone();;
//print the detection results
for (int i = ; i < (pResults ? *pResults : ); i++)
{
short * p = ((short*)(pResults + )) + * i;
int x = p[];
int y = p[];
int w = p[];
int h = p[];
int neighbors = p[];
int angle = p[]; printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(result_multiview_reinforce, Rect(x, y, w, h), Scalar(, , ), );
if (doLandmark)
{
for (int j = ; j < ; j++)
circle(result_multiview_reinforce, Point((int)p[ + * j], (int)p[ + * j + ]), , Scalar(, , ));
}
}
imshow("video test", result_multiview_reinforce);
waitKey(); //release the buffer
free(pBuffer); }
return ;
}

其中的neighbours的含义是

 int min_neighbors, //how many neighbors each candidate rectangle should have to retain it

注意,工程记得添加头文件;

参考

1.github

2.如何使用libfacedetect

3.人脸检测算法

4.CSDN大神介绍

5.如何将人脸检测的速度做到极致

【计算机视觉】如何使用于仕琪老师的libfacedetect人脸检测库的更多相关文章

  1. 如何快糙好猛的使用Shiqi.Yu老师的公开人脸检测库(附源码)

    前言 本次编写所用的库为于仕祺老师免费提供的人脸检测库.真心好用,识别率和识别速度完全不是Opencv自带的程序能够比拟的.将其配合Opencv的EigenFace算法,基本上可以形成一个小型的毕业设 ...

  2. 【计算机视觉】如何使用opencv自带工具训练人脸检测分类器

    前言 使用opencv自带的分类器效果并不是很好,由此想要训练自己的分类器,正好opencv有自带的工具进行训练.本文就对此进行展开. 步骤 1.查找工具文件: 2.准备样本数据: 3.训练分类器: ...

  3. 【计算机视觉】ARM平台实现人脸检测YSQfastfd

    ARM平台实现于仕琪人脸检测库YSQfastfd 平台要求 ARM32 platform hardware board Ubuntu 16.04 with GTK3 library USB camer ...

  4. 用于数据科学的顶级 C/C++ 机器学习库整理

    用于数据科学的顶级 C/C++ 机器学习库整理 介绍和动机--为什么选择 C++ C++ 非常适合 动态负载平衡. 自适应缓存以及开发大型大数据框架 和库.Google 的MapReduce.Mong ...

  5. CSV.js – 用于 CSV 解析和编码的 JS 工具库

    逗号分隔值(CSV )文件用于以以纯文本的形式存储表格化数据(数字和文本). CSV 文件包含任意数量的记录,通过某种换行符分隔,每条记录由字段,其他一些字符或字符串分隔,最常用的是文字逗号或制表符. ...

  6. App.js – 用于移动 Web App 开发的 JS 界面库

    App.js 是一个轻量级的 JavaScript UI 库,用于创建像本地应用程序的移动 Web 应用而不牺牲性能和体验.它是跨平台的,特定的UI设计,配置类似原生的过渡效果.App.js 的目的是 ...

  7. 更改虚拟内存(使用于win7、win8系统)

    在使用电脑的过程中你肯定有这样的抱怨吧!电脑为什么越来越慢?C盘为什么越来越小?我们都非常清楚:C盘剩余空间量的大小,很大程度上决定着我们在使用电脑的过程中程序运行的速度.随着电脑软件越装越多,尽管我 ...

  8. onchange事件可以使用于: <input>, <select>, 和 <textarea>。

    onchange 事件会在域的内容改变时发生. onchange 事件也可用于单选框与复选框改变后触发的事件.

  9. sql把表格拼成字符串,多半使用于GROUP BY

    --假定要聚合的字段是id ,要统计的字段是tname --select a.tname from @T1 a for xml path('row') select id,REPLACE(replac ...

随机推荐

  1. Mac OS下 selenium 驱动safari日志

    /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/bin/java "-javaagent:/Applicat ...

  2. MongoDB(课时20 游标)

    3.5 游标(重点) 所谓游标就是指数据可以一行行的进行操作,非常类似于ResultSet数据处理.在MongoDB里对游标的控制使用find()函数就可以返回游标.对于返回的游标如果想进行操作,使用 ...

  3. TimeZone 时区 (JS .NET JSON MYSQL) + work week 闰年

    来源参考 : http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html 来源参考 : http://walkingice.blogs ...

  4. codeforces 516c// Drazil and Park// Codeforces Round #292(Div. 1)

    题意:一个圆环上有树,猴子上下其中一棵树,再沿着换跑,再上下另一棵树.给出一个区间,问最大的运动距离是. 给出区间大小dst,和数高数组arr. 设区间[x,y],a[x]=2*arr[x]+dst[ ...

  5. Confluence 6 选项 2 – 转移 Crowd/Jira 应用程序中的用户和用户组到 Confluence 数据库

    当你打算合并的外部目录服务器(Crowd 或 Jira 应用)有大量的用户到 Confluence 数据库中的时候,请使用这个选项.你需要有基本的 SQL 知识才能完成这个任务. 下面的 SQL 命令 ...

  6. Java基础-集合(12)

    存储数据的容器有数组和StringBuilder.StringBuilder的结果是一个字符串,不满足要求,所以只能选择数组,这就是对象数组.而对象数组又不能适应变化的需求,因为数组的长度是固定的,这 ...

  7. 『PyTorch』第十弹_循环神经网络

    RNN基础: 『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 TensorFlow RNN: 『TensotFlow』基础RNN网络分类问题 『TensotFlow』基础R ...

  8. FNDLOAD移植Lookup Type

    通过OAF WEB页面添加的lookup type不能使用fndload直接移植,移植之后无法包含code值,必须使用FORM窗口定义.

  9. java连接MySql数据库 zeroDateTimeBehavior

    JAVA连接MySQL数据库,在操作值为0的timestamp类型时不能正确的处理,而是默认抛出一个异常, 就是所见的:java.sql.SQLException: Cannot convert va ...

  10. 网络SSID是什么意思

    ssid是网络的ID(名称).一般用在无线网络上.搜索无线网络名一般就是在搜索无线网络的ssid. SSID是Service Set Identifier的缩写,意思是:服务集标识.SSID技术可以将 ...