前言

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

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. Python day9函数部分

    函数的学习:函数对于一门编程语言来说挺重要的,尤其是c语言,是完全使用函数来编写的 1.函数的定义:逻辑结构化和过程化的一种编程方法 def squre(x): "求一个数的平方 retur ...

  2. R6

    RC 的加强版是 R6 , R6 是一个扩展包,能够实现支持公共和私有字段与方法的更有效的引用类,还有一些其他强大的功能.运行以下代码安装这个包:install.packages("R6&q ...

  3. 《剑指offer》第三十二题(不分行从上往下打印二叉树)

    // 面试题32(一):不分行从上往下打印二叉树 // 题目:从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印. #include <iostream> #include ...

  4. C++ 利用栈解决运算问题

    2017-06-27 19:19:18 第一步需要将中缀表达式转为后缀表达式.这步的转化可以说是本题的核心. 主要的转化手段是利用栈,有如下几个规则: 数字直接输出 "("直接进栈 ...

  5. python通过get方式,post方式发送http请求和接收http响应-urllib urllib2

    python通过get方式,post方式发送http请求和接收http响应-- import urllib模块,urllib2模块, httplib模块 http://blog.163.com/xyc ...

  6. English trip V1 - 8.What's in My Bag? 我的包里面有什么? Teacher:Corrine Key: plular(复数) and singular(单数)

    In this lesson you will learn to talk about the things you have.   您将学习如何谈论您拥有的东西 课上内容(Lesson) What' ...

  7. English trip -- VC(情景课)1 B Countries

    Vocabulary focus 核心词汇 Vo ca bu la ry   fo cus [və(ʊ)'kæbjʊlərɪ]      ['fəʊkəs] Listen and repeat  听并 ...

  8. Vue.js教程--基础(实例 模版语法template computed, watch v-if, v-show v-for, 一个组件的v-for.)

    官网:https://cn.vuejs.org/v2/guide/index.html Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统. 视频教程:https: ...

  9. OAF 功能中的参数含义

    OA.jsp?OAFunc=POS_HT_SP_B_SUPP&OAPB=POS_SM_PRODUCT_BRANDING&OAHP=POS_SM_ADMIN_HOME&OASF= ...

  10. 最新的ES 5.0路由算法底层实现

    http://www.cnblogs.com/bonelee/p/6078947.html 里分析了ES bulk实现,其中路由代码: ShardId shardId = clusterService ...