参考上一篇博客:LibFaceDetection开源库介绍与使用
最近很多朋友问我老版本LibFaceDetection的使用及demo,本文特此整理一下,方便大家借鉴,于老师的LibFaceDetection库已经更新了,老版本估计下载不到了,之前只是偶尔接触了一下人脸检测,现在不做这个方向了,故新版本没有学习。库的下载链接在文章末尾;
老版本的头文件.h
#ifndef _FACE_DETECTOR_H_
#define _FACE_DETECTOR_H_
#include <iostream>
#include "./LibFaceDetection/include/facedetect-dll.h"
#pragma comment(lib,"libfacedetect-x64.lib")
#define DETECT_BUFFER_SIZE (0x20000)
#define SAFE_FREE(ARG) do{ if (ARG) {free(ARG); ARG = NULL;} } while(0);
#define DO_LAND_MARK (1)
#define FACE_NUM_MEM_SIZE (4 /* byte */)
#define FACE_DETECT_DATA_SIZE ((142) * (2) /* byte */)
typedef int* (*detect_face)(unsigned char * pBuffer, unsigned char * gray_image_data, int width, int height, int step, \
float scale, int min_neighbors, int min_object_width, int max_object_width, int doLandmark);
class CFaceDetector {
public:
static CFaceDetector* GetDetector();
int* FaceDetect(detect_face detect_func, uint8_t *YData, uint32_t YDataLen, int nWidth, int nHeight, int doLandMark);
public:
private:
CFaceDetector(void);
~CFaceDetector(void);
CFaceDetector(CFaceDetector const&);
CFaceDetector& operator=(CFaceDetector const&);
private:
};
#endif
.cpp文件
#include "FaceDetector.h"
CFaceDetector::CFaceDetector(){}
CFaceDetector::~CFaceDetector(){}
CFaceDetector* CFaceDetector::GetDetector()
{
static CFaceDetector faceDetector;
return &faceDetector;
}
int *CFaceDetector::FaceDetect(detect_face detect_func, uint8_t *YData, uint32_t YDataLen, int nWidth, int nHeight, int doLandmark)
{ /* YData is unsafe, delete it after we use it */
int * pResults = NULL;
unsigned char * pBuffer = (unsigned char *)malloc(DETECT_BUFFER_SIZE);
if (!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return NULL;
}
pResults = detect_func(pBuffer, YData, nWidth, nHeight, nWidth, 1.2f, 2, 48, 0, doLandmark);
/*
//print the detection results
for (int i = 0; i < (pResults ? *pResults : 0); i++)
{
short * p = ((short*)(pResults + 1)) + 142 * i;
int x = p[0];
int y = p[1];
int w = p[2];
int h = p[3];
int neighbors = p[4];
int angle = p[5];
printf("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d\n", x, y, w, h, neighbors, angle);
rectangle(grayImg, cv::Rect(x, y, w, h), cv::Scalar(0, 255, 0), 2);
if (doLandmark)
{
for (int j = 0; j < 68; j++)
{
circle(grayImg, cv::Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 1, cv::Scalar(0, 255, 0));
}
}
}
*/
if (NULL == pResults)
{
return NULL;
}
/* copy data to heap so that avoid wrong result */
int face_num = int(*pResults); //人脸数目
int data_size = FACE_NUM_MEM_SIZE + face_num * FACE_DETECT_DATA_SIZE;
int *data = (int*)malloc(data_size);
memcpy(data, pResults, data_size);
SAFE_FREE(pBuffer);
return data; /*#### unsafe ,delete it after use it ####*/
}
要包含上面头文件,下面是核心代码,怎么调用及解析返回值:
while (!m_bQuit)
{
size_t buffSize = GetYDataRBufferSize();
if (buffSize > 0)
{
// 获取一帧Y数据(YUV中的Y)
m_YDataRBuffer.async_lock();
YDataParam * pstYDataParam = m_YDataRBuffer.front();
m_YDataRBuffer.pop_front();
m_YDataRBuffer.async_unlock();
/* YData != NULL means decoding */
if (pstYDataParam->pYData != NULL)
{
// 统计检测总帧数
m_nDetectedFrameNum++;
list<FaceAttribute> listFaceAttribute;
CFaceDetector *faceDetector = CFaceDetector::GetDetector();
/*### pResults unsafe,delete it after use it ###*/
int *pResults = faceDetector->FaceDetect(detect_methods[2], pstYDataParam->pYData,
pstYDataParam->nWidth * pstYDataParam->nHeight, pstYDataParam->nWidth, pstYDataParam->nHeight, 0);
if (NULL == pResults)
{
gDebug().Write("---Detect Failed !\n");
}
else
{
if (0 == (*pResults))//No Face
{
printf("---Detect success, but no face here.\n");
}
else
{
// 统计检测到的人脸数
m_nDetectedFaceFrameNum++;
//Got Face
for (int i = 0; i < (pResults ? *pResults : 0); i++)
{
short * p = ((short*)(pResults + 1)) + 142 * i;
FaceAttribute stFaceFrame;
stFaceFrame.x = p[0];
stFaceFrame.y = p[1];
stFaceFrame.width = p[2];
stFaceFrame.height = p[3];
stFaceFrame.neighbors = p[4];
stFaceFrame.angle = p[5];
// 统计关注角度次数
//CalcAngleAndPositionCount(stFaceFrame.angle, stFaceFrame.x, stFaceFrame.y);
// 下面是qt显示控制的代码,不用关注;
#if 1
// 换算一下,原视频分辨率不一定,但是此界面固定640*360
stFaceFrame.x = stFaceFrame.x * WIDTH / pstYDataParam->nWidth;
stFaceFrame.y = stFaceFrame.y * HEIGHT / pstYDataParam->nHeight;
stFaceFrame.width = stFaceFrame.width * WIDTH / pstYDataParam->nWidth;
stFaceFrame.height = stFaceFrame.height * HEIGHT / pstYDataParam->nHeight;
listFaceAttribute.push_back(stFaceFrame);
QString qstrLogText_add = "neighbors:";
qstrLogText_add += QString::number(stFaceFrame.neighbors, 10);
qstrLogText_add += "--angle:";
qstrLogText_add += QString::number(stFaceFrame.angle, 10);
gDebug().Write("检测结果:%s\n", qstrLogText_add.toStdString().c_str());
#endif
// 特征点
if (DO_LAND_MARK)
{
for (int j = 0; j < 68; j++)
printf("FaceID : %d, Point No : %d, x = %d, y = %d\n", i, j, (int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]);
}
}
}
ui.showCurrentPicLabel->SetShowContent(listFaceAttribute);
free(pResults);
pResults = NULL;
}
}
}
else
{
Sleep(10);//10ms
}
}
libfacedetection下载链接(包含win64,win32,arm版):https://download.csdn.net/download/m0_37684310/11119244
没有积分可留言邮箱,看到会及时回复。