add
houxiao
2017-04-21 a3e29fd900f721007c60284ec76092a6154d4e19
add

git-svn-id: http://192.168.1.226/svn/proxy@515 454eff88-639b-444f-9e54-f578c98de674
3个文件已删除
8个文件已添加
5个文件已修改
597 ■■■■■ 已修改文件
FaceServer/PB_0_0 (41x41).yuv 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/PB_0_1 (51x51).yuv 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/STFaceCache.cpp 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/STFaceCache.h 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/ev_server.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/face_daemon_proto.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/facelist-1001-0-2.pb 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/facelist-1001-0-4.pb 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/facelist-1001-0-5.pb 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/facelist-3.pb 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/main_face_daemon.cpp 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/make.sh 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/pseudo_stfacesdk.cpp 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/sample_face_search.cpp 376 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/sample_face_search.h 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/test_client.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FaceServer/PB_0_0 (41x41).yuv
Binary files differ
FaceServer/PB_0_1 (51x51).yuv
New file
@@ -0,0 +1,2 @@
Xr}€‚‚„ƒfUk††ƒ†‡…Š‹Œ‡†‰}pd[ZZUNIC=74.+)"Wnw~~~€i[r‰‡…†„}€„‚{wxzoc\^[VQHB;41.+,'Vksz~}~€€€n_mz}€„€{|~{~vputdUSUPNOHA92/.++,"Ugqw|~~~~u_TOUdr|{zywxrok[F:>@<=@B;40/.++*$T_nv{~~}}}}}~~uW8/$/Hetzxtri`K0!!)...0740/.-+++& T]irw~|||}}{{~yY<2":\quohYH7%#)*,-.../.-**)%  S\elszzzz}}y{„dMJJ<&)EaonbQ@5,%%,320.,,-.-,*''%  SYahovyyw}~†}h`ekyy[>;Umk_K>513>II>6.*++,-+*''% RT]dkrzyw~‚†rB'Doƒ—„aNXklYD71;OkvbK;/(**++*)*)#QRY^elsuw~~\+
"?Rlsvj`dok]H>AUr†‚gSB6()'())('$PQTX`goswxQ !,CH@239Mdx^A11?RVHB:3-,)%$)&"QPQU\bkpvrB7^Q205/!-V`5&2,! ##RONMTYbjurN#*?S\S.)C:-?HE("1*$&USJHNP[dotY<RqniaK2";@&")'3>C7 !91#$(  '&"\ZXWXYabiqm[YmjcppeaaiV1(/&(GO:)%59%&$.4761&cccceeheelh[Xhrlsw}we[P'4F2?aog[OB2)*0?BA>.*' edbcddccbcfYXfsmgk\GAJP:Y~Q4W]]c[K;53+,?GB<8/*(#a__aaaaa``a\V`jgivo\]h`Ns’_$6XZOLFA;9:17CG@:6/*)%_]]_____^^_[S_tpovsilpbSz‹a-=Z]RKB===B<=DFA:4-)(%!db`_```___`ZOSajuypotjQVƒ‡c7#?Yb[RHAEOPA=EF>62-('&#mllkjhgggggg_QD?FKYfhP:fŽ‚];'6Nac`]Y\eS=>FB731+('%#poppoooooppooswgUJIKH=O~“zZF2*0CRXVWPD<:DG<31.)''%#onnooopppqqrowvmghklb^cˆ“uWMH824<@EDFLRPE<62/,)((%%onnpppppqrrrspxk[XVWQPeАqOHJGAIQRZ`\WOB;531-*)))%&onnpppqqqrrqpsytnmhd^[iŒ†_IA=:AMOLJGEB?:6420,*))(&&onnpppqqqrrrrs||~zqdZjˆ€XA9/-8L\a]WSLE<741.+))((&&ooopppqqqrrssty|€xk[Vr‰|WB>512E_mmi`TH@93.-+*))(&&pooppqqqrrrsssw{|raV]y…rVJKF8.=[lppfXH@93.-+*))(&&pooppqqqrrrrrruz}xo]UbzyaNJQK7+4RjrpeWH@92.-+*))('&ppppqqqqrrrsssuz}{o_SWZSE99?A:+1Nhnk`TG?82.-+*))(&&ppppqqqqrrrssstx|zk[U\S=3.(/(+Hckg^RF>82..,*))(&&ppppqqqqqssssttvxtbUXovQ5*#&&$#+Ibhd[PF>82/.,+)(''(ppopqqqqrssstttwupaW^z„nJ3.+&##5NaeaWMD>81//-+*)'&'ssrqqqrrrsssttuwtm^Xgƒ‰~hJ6.++,:Pad`UKB<620/-+))'%%stuuutrrrssstuvwun][n„†ƒwbJ:69:BR`b^TJA;621/-+))'%$bbgkppqqrssstvvwun_`r}uj\MCBBGS]a[TJA;631/-+))'%#PRSTUVVY\^cehkjmqlgkv~z{rheXFCGLV[^XQJA;631/-+))'&$PPONMMKKLLMMNOOUbkkpw{|€zttgQJJLSVXSOJA;732/-+))&$"UTTSSSRRPONMKKJKWgqrsy~{swpdYPHHLORQMKD<521/-+*(&$"]\ZYXYXXUUWVSQQQWdqrnobNEDC@GGGEEHMNMLG=421/-+)(%#"kjhgecb`^\ZYYYXYZcoshZ=,++#'028@GGIKLF:310/-+)($!"llkkkkllkkkjhggdcdlp_C$%$")2<BDFHA7200/-+*'$"!lllllllllmlnnnnmlkkj\F5 (;ABBA;41///,+*&# lllllllllllkjjjlmjje[Wd`RL4&$1BC@><720/1.,**&" llkkkkkkllkmmmllnmqe_baaoyiR7/5?BB?<9620//,+*($ lllllllllllllllnqrbWY`]SSX\R>027<AB?;631//.,**&!llllllmllmmnmlmqlbF?Ra`O><?9,)04:?A=840.--,+*($ llllllnkkmmpqsolU=34K`aO7/,+-125:>?:62.,,+*)(%!llllllmllknqvp[F3/14D\jZD/-0797::><630,,,*)'&"lllllmmmnnoohS<01221<Vki]K=799>B@>931-+**)&#!llllmmnnrr^L;--/432/5NjutjXPJHGFE?;50,)(%#"!!
FaceServer/STFaceCache.cpp
New file
@@ -0,0 +1,68 @@
#include "STFaceCache.h"
#include <MaterialBuffer.h>
#include <logger.h>
#include <map>
#include <sys/types.h>
#include <dirent.h>
#include "sample_face_search.h"
struct STFaceContext
{
    int dbid;
    std::string dbfn;
    stface_handles handles;
};
typedef std::map<int, STFaceContext> stface_ctx_map_t; // <dbid, ctx>
STFaceCache::STFaceCache(const std::string& _stfacedbPath)
    : stfacedbPath(_stfacedbPath), stfaceModels(STFACESDK_BASE "/models"), _cacheContext(new stface_ctx_map_t)
{
    LOG_INFO << "st face db: " << stfacedbPath << LOG_ENDL;
    LOG_INFO << "st face sdk models: " << stfaceModels << LOG_ENDL;
}
STFaceCache::~STFaceCache()
{
    delete (stface_ctx_map_t*)_cacheContext;
    _cacheContext = nullptr;
}
bool STFaceCache::load_dbs()
{
    stface_ctx_map_t& cacheContext(*(stface_ctx_map_t*)_cacheContext);
    DIR* dp = opendir(stfacedbPath.c_str());
    if (dp != NULL)
    {
        struct dirent* ep;
        while(ep = readdir(dp))
        {
            //puts(ep->d_name);
            STFaceContext ctx;
            ctx.dbfn = ep->d_name;
            ctx.dbid = strtol(ctx.dbfn.c_str(), nullptr, 10);
        }
        closedir(dp);
    }
    else
    {
        LOG_ERROR << "Couldn't open the directory." << LOG_ENDL;
        return false;
    }
}
FDP_FaceDetectResult STFaceCache::detect(const STFaceImage& img)
{
    stface_ctx_map_t& cacheContext(*(stface_ctx_map_t*)_cacheContext);
    return FDP_FaceDetectResult(0, 0);
}
FDP_FaceDetectResult STFaceCache::save(const STFaceImage& img)
{
    stface_ctx_map_t& cacheContext(*(stface_ctx_map_t*)_cacheContext);
    return FDP_FaceDetectResult(0, 0);
}
FaceServer/STFaceCache.h
New file
@@ -0,0 +1,33 @@
#ifndef _ST_FACE_CACHE_H_
#define _ST_FACE_CACHE_H_
#include <string>
#include "face_daemon_proto.h"
struct STFaceImage
{
    int32_t db_id;
    int16_t mb_type; // MB_Frame::MBFType
    int16_t width;
    int16_t height;
    uint32_t size;
    const uint8_t* buff;
};
class STFaceCache
{
public:
    STFaceCache(const std::string& _stfacedbPath);
    ~STFaceCache();
    bool load_dbs();
    FDP_FaceDetectResult detect(const STFaceImage& img);
    FDP_FaceDetectResult save(const STFaceImage& img);
private:
    const std::string stfacedbPath;
    const std::string stfaceModels;
    void* _cacheContext;
};
#endif
FaceServer/ev_server.h
@@ -5,7 +5,9 @@
#include <stdint.h>
#include "ev_proto.h"
#ifndef SERVER_PORT
#define SERVER_PORT 5432
#endif
#define REUSEADDR_ON 1
#define CLIENT_BUFFER_MAX 100*1024 // 100KB
#define CLIENT_READ_TIMES_MAX 100
FaceServer/face_daemon_proto.h
@@ -25,7 +25,7 @@
struct FDP_Image
{
    int32_t school_id;
    int32_t db_id;
    int16_t mb_type; // MB_Frame::MBFType
    int16_t width;
    int16_t height;
@@ -38,6 +38,8 @@
    
    FDP_FaceDetectPB(int32_t _db_id) : db_id(_db_id)
    {}
    void hton();
};
struct FDP_FaceDetectResult
@@ -47,6 +49,8 @@
    
    FDP_FaceDetectResult(int32_t _db_id, int32_t _st_id) : db_id(_db_id), st_id(_st_id)
    {}
    void hton();
};
#pragma pack()
FaceServer/facelist-1001-0-2.pb
Binary files differ
FaceServer/facelist-1001-0-4.pb
Binary files differ
FaceServer/facelist-1001-0-5.pb
Binary files differ
FaceServer/facelist-3.pb
Binary files differ
FaceServer/main_face_daemon.cpp
@@ -4,7 +4,7 @@
#include "ev_server.h" 
#include "ev_proto.h"
#include "face_daemon_proto.h"
#include "STFaceCache.h"
#include <PbFaceList.pb.h>
#include <signal.h>
@@ -12,7 +12,10 @@
#include <sstream>
#include <iostream>
#define WRAPPER_TEXT(x) "\"" << x << "\""
Logger g_logger(std::cout);
STFaceCache g_STFaceCache("/opt/FaceServer/stfacedb");
evclient_proc_t evclient_proc;
@@ -25,12 +28,12 @@
{
    std::stringstream ss;
    ss << "{" << std::endl;
    ss << "\"ret\":" << 0 << "," << std::endl;
    ss << "\"count\":" << result.size() << "," << std::endl;
    ss << "\"ret\":" << WRAPPER_TEXT(0) << "," << std::endl;
    ss << "\"count\":" << WRAPPER_TEXT(result.size()) << "," << std::endl;
    ss << "\"result\":[";
    for(fdr_vec_t::const_iterator iter = result.begin(); iter != result.end(); ++iter)
    {
        ss << "[" << iter->db_id << "," << iter->st_id << "]";
        ss << "[" << WRAPPER_TEXT(iter->db_id) << "," << WRAPPER_TEXT(iter->st_id) << "]";
        if (iter != std::prev(result.end()))
            ss << ",";
    }
@@ -63,28 +66,38 @@
    LOGP(DEBUG, "pbFaceList: magic=%u, image_count=%u, src_width=%u, src_height=%u", 
        pbFaceList.magic(), pbFaceList.image_count(), pbFaceList.src_width(), pbFaceList.src_height());
    fdr_vec_t result;
    for(int i = 0; i < pbFaceList.image_count(); i++)
    {
        const PbFaceList_FaceListImage& pbFaceListImage = pbFaceList.images(i);
        LOGP(DEBUG, "\tpbFaceList %d: idx=%u, size=%u, type=%u, width=%u, height=%u, top_left_x=%u, top_left_y=%u", 
            i, pbFaceListImage.idx(), pbFaceListImage.size(), pbFaceListImage.type(), pbFaceListImage.width(), pbFaceListImage.height(), pbFaceListImage.top_left_x(), pbFaceListImage.top_left_y());
        char imgfn[100 * 1024];
        sprintf(imgfn, "PB_%d_%d.yuv", 0, i);
        FILE * pFile = fopen(imgfn, "wb");
        fwrite(*(pbFaceListImage.img().data()), sizeof(char), pbFaceListImage.size(), pFile);
        fclose(pFile);
        pFile = nullptr;
        //#test
        //char imgfn[100 * 1024];
        //sprintf(imgfn, "PB_%d_%d.yuv", 0, i);
        //
        //FILE * pFile = fopen(imgfn, "wb");
        const std::string* img(*pbFaceListImage.img().data());
        //fwrite(img->data(), sizeof(char), img->size(), pFile);
        //fclose(pFile);
        //pFile = nullptr;
        STFaceImage stimg;
        stimg.db_id = fdpFaceDetectPB->db_id;
        stimg.mb_type = pbFaceListImage.type();
        stimg.width = pbFaceListImage.width();
        stimg.height = pbFaceListImage.height();
        stimg.size = img->size();
        stimg.buff = (const uint8_t*)img->data();
        result.push_back(g_STFaceCache.detect(stimg));
    }
    fdr_vec_t result;
    //do detect(client)
    result.push_back(FDP_FaceDetectResult(-1,123));
    result.push_back(FDP_FaceDetectResult(2,456));
    result.push_back(FDP_FaceDetectResult(0,0));
    //#test
    //result.push_back(FDP_FaceDetectResult(-1,123));
    //result.push_back(FDP_FaceDetectResult(2,456));
    //result.push_back(FDP_FaceDetectResult(0,0));
    
    return send_SensetimeFaceDetectResultJson(client, result);
}
FaceServer/make.sh
@@ -8,8 +8,14 @@
PROTOBUF_INC="-I$PROTOBUF_BASE/include"
PROTOBUF_LIB="-L$PROTOBUF_BASE/lib -lprotobuf"
CPPFLAGS+="-g -c -std=c++11 -pthread -I$PIPELINE_BASE -I$VISITFACE_BASE $PROTOBUF_INC "
LDFLAGS+="-pthread -levent $PROTOBUF_LIB "
STFACESDK_BASE=/opt/st_face-6.3.1-verify_p1-linux-524d0c3
STFACESDK_INC="-I$STFACESDK_BASE/include"
STFACESDK_LIB="-L$STFACESDK_BASE/libs/linux-x86_64"
OPENCV_LIB=`pkg-config --libs-only-l opencv`
CPPFLAGS+="-g -c -std=c++11 -pthread -DSERVER_PORT=5432 -DSTFACESDK_BASE=\"$STFACESDK_BASE\" -I$PIPELINE_BASE -I$VISITFACE_BASE $PROTOBUF_INC $STFACESDK_INC "
LDFLAGS+="-pthread -levent $PROTOBUF_LIB $STFACESDK_LIB $OPENCV_LIB " # -lcvface_api
rm *.o
rm face_server
@@ -17,8 +23,10 @@
g++ $PIPELINE_BASE/Logger/src/logger.cc $CFLAGS $CPPFLAGS
g++ ev_server.cpp -DUSER_DEFINE_EVCLIENT_PROC $CFLAGS $CPPFLAGS
g++ main_face_daemon.cpp $CFLAGS $CPPFLAGS
g++ $VISITFACE_BASE/PbFaceList.pb.cc $CFLAGS $CPPFLAGS
g++ main_face_daemon.cpp $CFLAGS $CPPFLAGS
g++ sample_face_search.cpp $CFLAGS $CPPFLAGS
g++ STFaceCache.cpp $CFLAGS $CPPFLAGS
g++ test_client.cpp $CFLAGS $CPPFLAGS
@@ -27,6 +35,8 @@
  ev_server.o \
  PbFaceList.pb.o \
  main_face_daemon.o \
  sample_face_search.o \
  STFaceCache.o \
  $LDFLAGS -o face_server
#
@@ -35,4 +45,4 @@
  $LDFLAGS -o test_client
#
#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/protobuf/inst/lib
#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/protobuf/inst/lib:/opt/st_face-6.3.1-verify_p1-linux-524d0c3/libs/linux-x86_64
FaceServer/pseudo_stfacesdk.cpp
FaceServer/sample_face_search.cpp
New file
@@ -0,0 +1,376 @@
#include "sample_face_search.h"
#include <logger.h>
#include <vector>
#include <stdio.h>
#include <cv_face.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
//static cv_handle_t handle_verify = nullptr;
//static cv_handle_t handle_db = nullptr;
//static cv_handle_t handle_detect = nullptr;
#define _MAX_PATH 260
cv_feature_t *stface_extract_feature(stface_handles& handles, const char *image_path) {
    Mat bgr_image = imread(image_path);  // CV_PIX_FMT_BGR888
    if (!bgr_image.data) {
        return nullptr;
    }
    cv_feature_t *p_feature = nullptr;
    cv_face_t *p_face = nullptr;
    int face_count = 0;
    cv_result_t st_result = CV_OK;
    st_result = cv_face_detect(handles.handle_detect, bgr_image.data, CV_PIX_FMT_BGR888,
                bgr_image.cols, bgr_image.rows, bgr_image.step,
                CV_FACE_UP, &p_face, &face_count);
    if (face_count >= 1) {
        st_result = cv_verify_get_feature(handles.handle_verify,
                        (unsigned char *)bgr_image.data, CV_PIX_FMT_BGR888,
                        bgr_image.cols, bgr_image.rows, bgr_image.step,
                        p_face, &p_feature, nullptr);
        if (st_result != CV_OK) {
            LOGP(INFO, "cv_verify_get_feature failed, error code %d\n", st_result);
        }
    } else {
        LOGP(INFO, "can't find face in %s", image_path);
    }
    // release the memory of face
    cv_face_release_detector_result(p_face, face_count);
    return p_feature;
}
int stface_db_add(stface_handles& handles, const char *image_path) {
    cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
    if (!p_feature) {
        return -1;
    }
    int idx;
    cv_result_t cv_result = cv_verify_add_face(handles.handle_db, p_feature, &idx);
    if (cv_result != CV_OK) {
        LOGP(INFO, "cv_verify_add_face failed, error code %d\n", cv_result);
    }
    cv_verify_release_feature(p_feature);
    return idx;
}
bool stface_db_del(stface_handles& handles, int idx) {
    if (idx < 0) {
        LOGP(INFO, "invalid idx!\n");
        return false;
    }
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_delete_face(handles.handle_db, idx);
    if (cv_result != CV_OK) {
        LOGP(INFO, "cv_verify_delete_face failed, error code %d\n", cv_result);
    }
    else {
        LOGP(INFO, "delete succeed\n");
    }
}
bool stface_db_save(stface_handles& handles, char *db_path) {
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_save_db(handles.handle_db, db_path);
    if (cv_result != CV_OK) {
        LOGP(INFO, "cv_verify_save_db failed, error code %d\n", cv_result);
        return false;
    }
    else {
        LOGP(INFO, "save done!\n");
    }
    return true;
}
bool stface_db_load(stface_handles& handles, char *db_path) {
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_load_db(handles.handle_db, db_path);
    if (cv_result != CV_OK) {
        LOGP(INFO, "cv_verify_load_db failed, error code %d\n", cv_result);
        return false;
    }
    else {
        LOGP(INFO, "load done!\n");
    }
    return true;
}
bool stface_db_gen(stface_handles& handles, char *image_list, char *output_db_path) {
    bool bresult = true;
    FILE *fp_path = fopen(image_list, "r");
    if(!fp_path) {
        LOGP(INFO, "failed to load %s\n", image_list);
        return false;
    }
    std::vector<cv_feature_t *> list_feature;
    list_feature.clear();
    for (;;) {
        char image_path[1024];
        int num = fscanf(fp_path, "%s", image_path);
        if (num != 1) {
            bresult = false;
            break;
        }
        LOGP(INFO, "extracting %s\n", image_path);
        // get the face feature
        cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
        if (!p_feature) {
            LOGP(INFO, "failed to extract image: %s\n", image_path);
            continue;
        }
        list_feature.push_back(p_feature);
    }
    fclose(fp_path);
    cv_verify_destroy_db(handles.handle_db);
    cv_result_t cv_result = CV_OK;
    cv_verify_create_db(&handles.handle_db);
    cv_result = cv_verify_build_db(handles.handle_db, &list_feature[0], list_feature.size());
    if (cv_result != CV_OK) {
        LOGP(INFO, "cv_verify_build_db failed, error code %d\n", cv_result);
        bresult = false;
    }
    cv_verify_save_db(handles.handle_db, output_db_path);
    for (int i = 0; i < list_feature.size(); i++) {
        cv_verify_release_feature(list_feature[i]);
    }
    cout << "db gen done!" << endl;
    return bresult;
}
bool stface_search_db(stface_handles& handles, char *image_path) {
    FILE *fp_path = fopen(image_path, "r");
    if (fp_path == nullptr) {
        LOGP(INFO, "invalid path !\n");
        return false;
    }
    fclose(fp_path);
    cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
    if (p_feature == nullptr) {
        LOGP(INFO, "extract failed !\n");
        return false;
    }
    int top_k = 10;
    int *top_idxs = new int[top_k];
    float *top_scores = new float[top_k];
    unsigned int result_length = 0;
    cv_result_t cv_result = cv_verify_search_face(handles.handle_verify, handles.handle_db,
        p_feature, top_k,
        top_idxs, top_scores, &result_length);
    if (cv_result == CV_OK) {
        for (unsigned int t = 0; t < result_length; t++) {
            // const cv_feature_t item = result[t].item;
            LOGP(INFO, "%d\t", top_idxs[t]);
            LOGP(INFO, "%0.2f\n", top_scores[t]);
        }
    }
    else {
        LOGP(INFO, "cv_verify_search_face failed, error code %d\n", cv_result);
    }
    if (top_idxs) {
        delete[]top_idxs;
    }
    if (top_scores) {
        delete[]top_scores;
    }
    cv_verify_release_feature(p_feature);
    return true;
}
bool stface_search_list(stface_handles& handles, char *image_path, char *list_path) {
    cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
    if (p_feature == nullptr) {
        LOGP(INFO, "failed to extract image: %s\n", image_path);
        return false;
    }
    FILE *fp_path = fopen(list_path, "r");
    if(!fp_path) {
        LOGP(INFO, "failed to load %s\n", list_path);
        return false;
    }
    std::vector<cv_feature_t *> list_feature;
    list_feature.clear();
    for (;;) {
        char image_path[_MAX_PATH];
        int num = fscanf(fp_path, "%s", image_path);
        if (num != 1) {
            break;
        }
        LOGP(INFO, "extracting %s\n", image_path);
        // get the face feature
        cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
        if (!p_feature) {
            LOGP(INFO, "failed to extract image: %s\n", image_path);
            continue;
        }
        list_feature.push_back(p_feature);
    }
    fclose(fp_path);
    const int top_k = 10;
    int top_idxs[top_k];
    float top_scores[top_k];
    unsigned int result_length = 0;
    cv_result_t cv_result = cv_verify_search_face_from_list(handles.handle_verify,
                &list_feature[0], list_feature.size(),
                p_feature, top_k,
                top_idxs, top_scores, &result_length);
    if (cv_result == CV_OK) {
        for (unsigned int t = 0; t < result_length; t++) {
            LOGP(INFO, "%d\t", top_idxs[t]);
            LOGP(INFO, "%0.2f\n", top_scores[t]);
        }
    } else {
        LOGP(INFO, "search face failed");
    }
    cv_verify_release_feature(p_feature);
    for (int i = 0; i < list_feature.size(); i++) {
        cv_verify_release_feature(list_feature[i]);
    }
    LOGP(INFO, "list search done!\n");
    return true;
}
void stface_get_help() {
    LOGP(INFO, "Usage: help | Get cmd list\n");
    LOGP(INFO, "Usage: search p_image_colorpath | Search image in db\n");
    LOGP(INFO, "Usage: add p_image_colorpath | Add image in db, return idx in db, if idx < 0 means failed\n");
    LOGP(INFO, "Usage: del idx | Delete image in db\n");
    LOGP(INFO, "Usage: save db_file | Save current db in db_file\n");
    LOGP(INFO, "Usage: load db_file | Load db in db_file\n");
    LOGP(INFO, "Usage: gen p_image_colorlist db_file | Gen images in p_image_colorlist and save in db_file\n");
    LOGP(INFO, "Usage: exit | Exit the program\n");
}
int stface_main(stface_handles& handles, int argc, char *argv[]) {
    cv_result_t cv_result = cv_face_create_detector(&handles.handle_detect, nullptr, CV_DETECT_ENABLE_ALIGN_21);
    if (cv_result != CV_OK){
        LOGP(INFO, "create detect handle failed, error code %d\n", cv_result);
    }
    cv_result = cv_verify_create_handle(&handles.handle_verify, "../../../models/verify.model");
    if (cv_result != CV_OK){
        LOGP(INFO, "create verify handle failed, error code %d\n", cv_result);
    }
    cv_result = cv_verify_create_db(&handles.handle_db);
    if (cv_result != CV_OK){
        LOGP(INFO, "create db handle failed, error code %d\n", cv_result);
    }
    if (handles.handle_detect != nullptr && handles.handle_verify != nullptr && handles.handle_db != nullptr) {
        // stface_db_gen("list.txt","out.db");
        LOGP(INFO, "Database is empty at the beginning\n");
        LOGP(INFO, "Please input 'help' to get the cmd list\n");
        char input_code[256];
        char image_path[_MAX_PATH];
        char db_path[_MAX_PATH];
        char command[256];
        input_code[0] = 0;
        while (1) {
            LOGP(INFO, ">>");
            if (!fgets(input_code, 256, stdin)) {
                LOGP(INFO, "read nothing\n");
                continue;
            }
            int input_length = strlen(input_code);
            if (input_length > 0 && input_code[input_length - 1] == '\n') {
                input_code[--input_length] = 0;
            }
            if (input_length == 0) {
                continue;
            }
            std::string str_input_code(input_code);
            if (strcmp(str_input_code.c_str(), "help") == 0) {
                stface_get_help();
            }
            else if (strcmp(str_input_code.substr(0, 3).c_str(), "add") == 0) {
                int input_number = sscanf(input_code, "%s%s", command, image_path);
                if (input_number != 2) {
                    LOGP(INFO, "invalid! Usage: add p_image_colorpath\n");
                    continue;
                }
                int idx = stface_db_add(handles, image_path);
                cout << "idx = " << idx << endl;
            }
            else if (strcmp(str_input_code.substr(0, 3).c_str(), "del") == 0) {
                int idx = -1;
                int input_number = sscanf(input_code, "%s%d", image_path, &idx);
                if (input_number != 2) {
                    LOGP(INFO, "invalid! Usage: del idx(unsigned int\n");
                    continue;
                }
                stface_db_del(handles, idx);
            }
            else if (strcmp(str_input_code.substr(0, 4).c_str(), "save") == 0) {
                int input_number = sscanf(input_code, "%s%s", command, image_path);
                if (input_number != 2) {
                    LOGP(INFO, "invalid! Usage: save db_file\n");
                    continue;
                }
                stface_db_save(handles, image_path);
            }
            else if (strcmp(str_input_code.substr(0, 4).c_str(), "load") == 0) {
                int input_number = sscanf(input_code, "%s%s", command, image_path);
                if (input_number != 2) {
                    LOGP(INFO, "invalid! Usage: load db_file\n");
                    continue;
                }
                stface_db_load(handles, image_path);
            }
            else if (strcmp(str_input_code.c_str(), "exit") == 0) {
                break;
            }
            else if (strcmp(str_input_code.substr(0, 3).c_str(), "gen") == 0) {
                int input_number = sscanf(input_code, "%s%s%s", command, image_path, db_path);
                if (input_number != 3) {
                    LOGP(INFO, "invalid! Usage: gen p_image_colorlist_file db_file\n");
                    continue;
                }
                stface_db_gen(handles, image_path, db_path);
            }
            else if (strcmp(str_input_code.substr(0, 6).c_str(), "search") == 0) {
                int input_number = sscanf(input_code, "%s%s", command, image_path);
                if (input_number != 2) {
                    LOGP(INFO, "invalid! Usage: search p_image_colorpath\n");
                    continue;
                }
                stface_search_db(handles, image_path);
            }
            else if (strcmp(str_input_code.substr(0, 10).c_str(), "listsearch") == 0) {
                char search_path[_MAX_PATH];
                int input_number = sscanf(input_code, "%s%s%s", command, search_path,
                    image_path);
                if (input_number != 3) {
                    LOGP(INFO, "invalid! Usage: listsearch p_image_colorsrcpath p_image_colorlistpath\n");
                    continue;
                }
                stface_search_list(handles, search_path, image_path);
            }
            else {
                LOGP(INFO, "invalid cmd, please input 'help' to get the cmd list\n");
            }
        }
    }
    cv_face_destroy_detector(handles.handle_detect);
    cv_verify_destroy_db(handles.handle_db);
    cv_verify_destroy_handle(handles.handle_verify);
    return 0;
}
FaceServer/sample_face_search.h
New file
@@ -0,0 +1,37 @@
#ifndef _SAMPLE_FACE_SEARCH_H_
#define _SAMPLE_FACE_SEARCH_H_
typedef void* cv_handle_t;
struct cv_feature_t;
struct stface_handles
{
    cv_handle_t handle_verify;
    cv_handle_t handle_db;
    cv_handle_t handle_detect;
    stface_handles() : handle_verify(nullptr), handle_db(nullptr), handle_detect(nullptr)
    {}
};
cv_feature_t *stface_extract_feature(stface_handles& handles, const char *image_path);
int stface_db_add(stface_handles& handles, const char *image_path);
bool stface_db_del(stface_handles& handles, int idx);
bool stface_db_save(stface_handles& handles, char *db_path);
bool stface_db_load(stface_handles& handles, char *db_path);
bool stface_db_gen(stface_handles& handles, char *image_list, char *output_db_path);
bool stface_search_db(stface_handles& handles, char *image_path);
bool stface_search_list(stface_handles& handles, char *image_path, char *list_path);
void stface_get_help();
int stface_main(int argc, char *argv[]);
#endif
FaceServer/test_client.cpp
@@ -35,7 +35,7 @@
void make_msg(char* mesg, int& length)
{
    FILE* pFile = fopen("facelist-1001-0-2.pb", "rb");
    FILE* pFile = fopen("facelist-1001-0-5.pb", "rb");
    length = fread(mesg, 1, length, pFile);
    fclose(pFile);
}