前言

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

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. 软件测试实习生 带人计划 Plan for Training Inten

    临时拟了个提纲,以后慢慢补充吧 序号 培训内容 时间安排 1 根据项目需求,编写测试用例,针对存储过程 2 存储过程的走读,以及怎样执行测试用例和查看结果 3 根据项目需求,编写测试用例,针对接口[C ...

  2. CKEditor5 基本使用

    1.引入 <script type="text/javascript" src="/plugin/ckeditor5/ckeditor.js">&l ...

  3. Django模板语言详解

    本节将介绍Django模版系统的语法.Django模版语言致力于在性能和简单性上取得平衡. 如果你有过其它编程背景,或者使用过一些在HTML中直接混入程序代码的语言,那么你需要记住,Django的模版 ...

  4. 日志_测试代码_Qt532

    1. int LogFile(QString &_str) { QDateTime datetime = QDateTime::currentDateTime();//获取系统现在的时间 QS ...

  5. 《剑指offer》第二十五题(合并两个排序的链表)

    // 面试题25:合并两个排序的链表 // 题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按 // 照递增排序的.例如输入图3.11中的链表1和链表2,则合并之后的升序链表如链 ...

  6. Shell循环输入符合条件为止

    提供用户输入,直到输入d/D/r/R为止. #!/bin/bash ]; do echo -n "(D)ebug or (R)elease?" read select_build_ ...

  7. Codeforces 101628A - Arthur's Language

    101628A - Arthur's Language 思路:dp,状态转移见代码. 代码: #include<bits/stdc++.h> using namespace std; #d ...

  8. FASTQ 数据质量统计工具

    主流工具: FastQC fqcheck readfq 拿到测序数据的第一步就是做质量控制 fqcheck之后得到的结果: 它会统计每条reads,按read 1-100位点计算每个位置的ACGTN含 ...

  9. 20170624xlVBA生成通讯录文件

    Public Sub QqYunContactTransferCsvFile() '应用程序设置 Application.ScreenUpdating = False Application.Disp ...

  10. python-day42--单表查询

    1. 简单查询select * from employee;select name,salary from employee; 2. where条件           1.比较运算符:> &l ...