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