//
|
// Created by ps on 18-12-18.
|
//
|
|
#include "FaceTrackingWrapper.h"
|
#include "Debug.h"
|
|
#include <FaceDetectServer/rpc/FaceServer.h>
|
#include <opencv2/opencv.hpp>
|
|
static FaceTrackingWrapper g_faceTrackingWrapper;
|
static std::map<std::string, int> g_channelCache;
|
|
static ::FaceDetect::Faces faceTrackingFunc(int channel, cv::Mat &image) {
|
FaceDetect::Faces faces;
|
int channel = 0;
|
BasicFace::FaceImage faceImage{image.cols, image.rows, image.step, image.data};
|
|
THFT_FaceInfo facePos[MAX_DETECT_FACE];
|
int faceNum = THFT_FaceTracking(channel, image.data, facePos);
|
|
if (faceNum > 0) {
|
for (int i = 0; i < faceNum; i++) {
|
FaceDetect::FacePos face;
|
auto &pos = facesPos[i];
|
memcpy(&face, &pos, sizeof(pos) - sizeof(pos.pFacialData) - sizeof(pos.nFaceID));
|
face.pFacialData.resize(sizeof(pos.pFacialData));
|
memcpy(face.pFacialData.data(), pos.pFacialData, sizeof(pos.pFacialData));
|
face.pfaceId = pos.nFaceID;
|
// DBG(face.fAngle.confidence);
|
faces.push_back(face);
|
}
|
} else {
|
DBG("Face num is 0");
|
}
|
|
}
|
|
|
FaceTrackingWrapper::FaceTrackingWrapper() {
|
|
}
|
|
FaceTrackingWrapper::~FaceTrackingWrapper() {
|
|
}
|
|
void FaceTrackingWrapper::setChannelParam(int channel, const BasicFace::InitParam &initParam) {
|
m_mapParam.insert(std::make_pair(channel, initParam));
|
}
|
|
bool FaceTrackingWrapper::initHandle() {
|
// todo add gpu support
|
int size = m_mapParam.size();
|
THFT_Param *param = new THFT_Param[size];
|
|
for (auto &item :m_mapParam) {
|
int pos = item.first;
|
auto t_param = item.second;
|
param[pos].nDeviceID = t_param.nDeviceID;
|
param[pos].nImageWidth = t_param.nImageWidth;
|
param[pos].nImageHeight = t_param.nImageHeight;
|
param[pos].nMaxFaceNum = t_param.nMaxFaceNum;
|
param[pos].nSampleSize = t_param.nSampleSize;
|
param[pos].nDetectionIntervalFrame = t_param.nDetectionIntervalFrame;
|
}
|
int nNum = -1;
|
nNum = THFT_Create(size, param);
|
delete[] param;
|
return (nNum > 0);
|
}
|
|
/***
|
* @todo
|
*
|
* @param image
|
* @return
|
*/
|
std::vector<BasicFace::FaceDetectResult> FaceTrackingWrapper::detectFace(const BasicFace::FaceImage &image) {
|
return vector<BasicFace::FaceDetectResult>();
|
}
|
|
std::vector<BasicFace::FaceDetectResult>
|
FaceTrackingWrapper::trackingFace(int channel, const BasicFace::FaceImage &image) {
|
vector<BasicFace::FaceDetectResult> results;
|
// ClockTimer ct("CasiaFaceWapper::detectFace");
|
if (channel == -1) {
|
ERR("invalid face channel, face detect faild");
|
return results;
|
}
|
THFT_FaceInfo facePos[MAX_DETECT_FACE];
|
int faceNum = THFT_FaceTracking(channel, image.data, facePos);
|
//int faceNum = THFI_DetectFace(channel, image.data, 24, image.width, image.height, facePos, MAX_DETECT_FACE);
|
if (faceNum < 0) {
|
ERR("THFI_DetectFace return " << faceNum);
|
} else {
|
results.resize(faceNum);
|
for (int i = 0; i < faceNum; i++) {
|
BasicFace::FaceDetectResult &result = results[i];
|
THFT_FaceInfo &face = facePos[i];
|
result.angle = sqrt(face.fAngle.pitch * face.fAngle.pitch / 3 +
|
face.fAngle.roll * face.fAngle.roll / 3 +
|
face.fAngle.yaw * face.fAngle.yaw / 3);
|
result.yaw = face.fAngle.yaw;
|
result.pitch = face.fAngle.pitch;
|
result.roll = face.fAngle.roll;
|
result.left = face.rcFace.left;
|
result.top = face.rcFace.top;
|
result.width = face.rcFace.right - face.rcFace.left;
|
result.height = face.rcFace.bottom - face.rcFace.top;
|
// result.score = face.nQuality / 100.0f;
|
result.score = face.fAngle.confidence;
|
result.trackingId = face.nFaceID;
|
}
|
}
|
return results;
|
}
|
|
/***
|
* @todo
|
*
|
* @param image
|
* @return
|
*/
|
vector<BasicFace::FaceFeatureResult> FaceTrackingWrapper::extractFace(const BasicFace::FaceImage &image) {
|
return vector<BasicFace::FaceFeatureResult>();
|
}
|
|
/***
|
* @todo
|
* @param feature1
|
* @param feature2
|
* @return
|
*/
|
float FaceTrackingWrapper::compareFeature(BasicFace::Feature &feature1, BasicFace::Feature &feature2) {
|
return 0;
|
}
|