From 96024c860270477fe9cf387ba855632a3ead08ee Mon Sep 17 00:00:00 2001 From: pansen <pansen626@sina.com> Date: 星期二, 18 十二月 2018 18:08:24 +0800 Subject: [PATCH] add Face tracking demo code --- QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.cpp | 95 +++++++++++++++ QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.h | 28 ++++ QiaoJiaSystem/testCodeMod/FaceDefine.h | 105 ++++++++++------ QiaoJiaSystem/testCodeMod/main.cpp | 85 ++++++++++++++ 4 files changed, 272 insertions(+), 41 deletions(-) diff --git a/QiaoJiaSystem/testCodeMod/FaceDefine.h b/QiaoJiaSystem/testCodeMod/FaceDefine.h index 58bd5a6..cf7431f 100644 --- a/QiaoJiaSystem/testCodeMod/FaceDefine.h +++ b/QiaoJiaSystem/testCodeMod/FaceDefine.h @@ -12,49 +12,74 @@ using std::vector; using std::string; -struct FaceFeatureResult { - vector<unsigned char> feature; - float score; -}; +namespace BasicFace { -struct FaceDetectResult { - FaceDetectResult() : attributes(256), trackingId(-1) {} + typedef vector<unsigned char> Feature; - int id; - int left; - int top; - int width; - int height; - float score; - float yaw; // 姘村钩杞锛岀湡瀹炲害閲忕殑宸﹁礋鍙虫, 鍗曚綅锛岃搴� - float pitch; // 淇话瑙掞紝鐪熷疄搴﹂噺鐨勪笂璐熶笅姝�, 鍗曚綅锛岃搴� - float roll; // 鏃嬭浆瑙掞紝鐪熷疄搴﹂噺鐨勫乏璐熷彸姝�, 鍗曚綅锛岃搴� - float angle; // sqrt(yaw*yaw/3+pitch*pitch/3+roll*roll/3) - vector<char> attributes; - float trackingId; -}; -struct DbSearchResult { - int index; - float confidence; - string dbId; -}; + struct InitParam { + int nDeviceID;//device id for GPU device.eg:0,1,2,3..... -struct FaceSearchResult { - int index; - int left; - int top; - int width; - int height; - float score; - float confidence; - string dbId; -}; + int nImageWidth;//image width of video + int nImageHeight;//image height of video + int nMaxFaceNum;//max face number for tracking + int nSampleSize;//down sample size for face detection + int nDetectionIntervalFrame;//interval frame number of face detection for face tracking -struct FaceImage { - int width; - int height; - int stride; - unsigned char *data; -}; + InitParam() { + nMaxFaceNum = 100; + nSampleSize = 640; + nDeviceID = 0; + nDetectionIntervalFrame = 5; + } + }; + + struct FaceFeatureResult { + Feature feature; + float score; + }; + + struct FaceDetectResult { + FaceDetectResult() : attributes(256), trackingId(-1) {} + + int id; + int left; + int top; + int width; + int height; + float score; + float yaw; // 姘村钩杞锛岀湡瀹炲害閲忕殑宸﹁礋鍙虫, 鍗曚綅锛岃搴� + float pitch; // 淇话瑙掞紝鐪熷疄搴﹂噺鐨勪笂璐熶笅姝�, 鍗曚綅锛岃搴� + float roll; // 鏃嬭浆瑙掞紝鐪熷疄搴﹂噺鐨勫乏璐熷彸姝�, 鍗曚綅锛岃搴� + float angle; // sqrt(yaw*yaw/3+pitch*pitch/3+roll*roll/3) + vector<char> attributes; + long trackingId; + }; + + struct DbSearchResult { + int index; + float confidence; + string dbId; + }; + + struct FaceSearchResult { + int index; + int left; + int top; + int width; + int height; + float score; + float confidence; + string dbId; + }; + + struct FaceImage { + int width; + int height; + int stride; + unsigned char *data; + }; + +} + #endif //TESTCODE_FACEDEFINE_H diff --git a/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.cpp b/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.cpp index ca5fb81..bd334b6 100644 --- a/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.cpp +++ b/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.cpp @@ -3,6 +3,8 @@ // #include "FaceTrackingWrapper.h" +#include "Debug.h" + FaceTrackingWrapper::FaceTrackingWrapper() { @@ -11,3 +13,96 @@ 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(BasicFace::FaceImage image) { + return vector<BasicFace::FaceDetectResult>(); +} + +std::vector<BasicFace::FaceDetectResult> FaceTrackingWrapper::trackingFace(int channel, 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(BasicFace::FaceImage image) { + return vector<BasicFace::FaceFeatureResult>(); +} + +/*** + * @todo + * @param feature1 + * @param feature2 + * @return + */ +float FaceTrackingWrapper::compareFeature(BasicFace::Feature &feature1, BasicFace::Feature &feature2) { + return 0; +} + + + diff --git a/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.h b/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.h index b1c5ff4..83e04f1 100644 --- a/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.h +++ b/QiaoJiaSystem/testCodeMod/FaceTrackingWrapper.h @@ -10,11 +10,18 @@ #include <string.h> #include <sys/time.h> #include <time.h> +#include <list> #include <opencv2/opencv.hpp> #include <FiStdDefEx.h> #include <THFaceTracking_i.h> + +#include "FaceDefine.h" + + +//typedef std::list<FaceTrackingInfo> ObjectList; +#define MAX_DETECT_FACE 50 class FaceTrackingWrapper { @@ -23,7 +30,26 @@ virtual ~FaceTrackingWrapper(); -// std::vector<FaceDetectResult> void detectFace(FaceImage image); + void setChannelParam(int channel, const BasicFace::InitParam &); + + bool initHandle(); + + std::vector<BasicFace::FaceDetectResult> detectFace(BasicFace::FaceImage image); + + std::vector<BasicFace::FaceDetectResult> trackingFace(int channel, BasicFace::FaceImage image); + + vector<BasicFace::FaceFeatureResult> extractFace(BasicFace::FaceImage image); + + static float compareFeature(BasicFace::Feature &feature1, BasicFace::Feature &feature2); + +private: + int nGPUDeviceID = 0; + + //sdk 鍒濆鍖栧弬鏁� + std::map<int, BasicFace::InitParam> m_mapParam; + + //淇濆瓨涓婃璺熻釜鐨勭洰鏍� +// std::map<int, ObjectList> m_objListCache; }; diff --git a/QiaoJiaSystem/testCodeMod/main.cpp b/QiaoJiaSystem/testCodeMod/main.cpp index 7bd3451..11f3fd1 100644 --- a/QiaoJiaSystem/testCodeMod/main.cpp +++ b/QiaoJiaSystem/testCodeMod/main.cpp @@ -3,10 +3,95 @@ // #include <Debug.h> +#include "FaceTrackingWrapper.h" + +using namespace cv; + +//get current system time +double msecond() { + struct timeval tv; + gettimeofday(&tv, 0); + return (tv.tv_sec * 1.0e3 + tv.tv_usec * 1.0e-3); +} int main(int argc, char **argv) { ENABLEGLOG("./log/"); + FaceTrackingWrapper faceTrackingWrapper; + + bool bOpen; + VideoCapture vc; +// rtsp stream address + bOpen = vc.open("rtsp://admin:a1234567@192.168.1.188:554/h264/ch1/main/av_stream"); + //camera +// if (1) { +// bool bSet1 = vc.set(CV_CAP_PROP_FRAME_WIDTH, w); +// bool bSet2 = vc.set(CV_CAP_PROP_FRAME_HEIGHT, h); +// bOpen = vc.open(devID); +// +// } +// //video file +// else { +// bOpen = vc.open("test.avi"); +// +// } + if (!bOpen) { + printf("Open video source faild."); + return 0; + } + + int nWidth = vc.get(CV_CAP_PROP_FRAME_WIDTH); + int nHeight = vc.get(CV_CAP_PROP_FRAME_HEIGHT); + + printf("FRAME_WIDTH=%d,FRAME_HEIGHT=%d\n", nWidth, nHeight); + + + BasicFace::InitParam initParam; + initParam.nDeviceID = 0; + initParam.nImageWidth = nWidth; + initParam.nImageHeight = nHeight; + initParam.nMaxFaceNum = 50; + initParam.nSampleSize = nWidth / 2; + initParam.nDetectionIntervalFrame = 12; + + faceTrackingWrapper.setChannelParam(0, initParam); + faceTrackingWrapper.setChannelParam(1, initParam); + faceTrackingWrapper.setChannelParam(2, initParam); + + faceTrackingWrapper.initHandle(); + Mat frame; + + while (1) { + + vc >> frame; + if (frame.empty()) { + waitKey(30); + continue; + } + + int nNum = 0; + THFT_FaceInfo *pFaceInfos = new THFT_FaceInfo[50]; + double t1, t2; + t1 = msecond(); +// nNum = THFT_FaceTracking(2, frame.data, pFaceInfos); + + BasicFace::FaceImage faceImage2{frame.cols, frame.rows, frame.step, frame.data}; + auto t_lists = faceTrackingWrapper.trackingFace(2, faceImage2); + t2 = msecond(); + delete[] pFaceInfos; + printf("face tracking time=%fms faceNun is %d\n", t2 - t1, (int) t_lists.size()); + + imshow("Face Tracking", frame); + waitKey(30); + } + destroyWindow("Face Tracking"); + + vc.release(); + THFT_Release(); + + getchar(); + return 0; + INFO("test"); -- Gitblit v1.8.0