//
|
// Created by ps on 2/26/18.
|
//
|
|
#include <cstring>
|
#include <THFeature_i.h>
|
#include <basic/util/app/AppPreference.hpp>
|
#include <basic/util/ShareMemory/ShareMemoryTool.hpp>
|
#include "FaceDBCompareServer.h"
|
|
using namespace std;
|
|
FaceDBCompareServer::FaceDBCompareServer() : m_erlangDbTool(nullptr), m_sqliteFaceEncap(nullptr) {
|
|
}
|
|
FaceDBCompareServer::FaceDBCompareServer(ErlangTool::ErlangDbTool *erlangDbTool) : m_erlangDbTool(erlangDbTool),
|
m_sqliteFaceEncap(nullptr) {
|
|
}
|
|
FaceDBCompareServer::FaceDBCompareServer(SqliteFaceEncap *sqliteFaceEncap) : m_erlangDbTool(nullptr),
|
m_sqliteFaceEncap(sqliteFaceEncap) {
|
|
}
|
|
//FaceDBCompareServer::FaceDBCompareServer(Ice::CommunicatorHolder& ich) : minThreshold(10) {
|
//#ifdef TestCode
|
//
|
//#else
|
// try {
|
// base_alarm = ich->stringToProxy("ServerAlarm");
|
// }catch(std::exception ex){
|
// ERR("ServerAlarm connceticon fail" << ex.what());
|
// };
|
//#endif
|
//}
|
|
FaceDBCompareServer::~FaceDBCompareServer() {
|
|
}
|
|
FaceResults FaceDBCompareServer::getTopResult(std::thread::id key) {
|
if (m_dbRWLocks.find(key) == m_dbRWLocks.end()) {
|
m_dbRWLocks[key] = RWLock();
|
}
|
RWLock &t_rwl = m_dbRWLocks[key];
|
t_rwl.wrlock();
|
FaceResults t_result = topResult[key];
|
topResult.erase(key);
|
t_rwl.unlock();
|
return t_result;
|
}
|
|
//#todo map 1->2 modify 2->1
|
bool FaceDBCompareServer::compare(thread::id key, AlarmData *alarmData, int topN) {
|
if (m_dbRWLocks.find(key) == m_dbRWLocks.end()) {
|
m_dbRWLocks[key] = RWLock();
|
}
|
RWLock &t_rwl = m_dbRWLocks[key];
|
// ClockTimer clockTimer("compare ");
|
RWLock t_rwLock;
|
|
m_rwLock.rdlock();
|
mapFaceResults t_compareResults;
|
if (topN > 1) {
|
//topN
|
parallelFor(ParallelForThreardSize::CPU_Number, [&](string &key, FeatureData &data) {
|
//#todo
|
double sc = 0;
|
for (auto &t_fea : data.features) {
|
double t_sc = m_casiaFaceWapper.compareFeature(alarmData->feature, t_fea);
|
if (t_sc > sc)
|
sc = t_sc;
|
}
|
// FaceResult tface{data.face_id, data.uuid, alarmData->tableName, sc, false};
|
FaceResult tface{0, data.uuid, alarmData->tableName, sc, data.faceUrl, data.idcard, ""};
|
t_rwLock.wrlock();
|
//#todo
|
if (sc < t_compareResults.end()->second.confidence) {
|
t_rwLock.unlock();
|
return;
|
}
|
t_compareResults.insert(make_pair(tface.confidence, tface));
|
//#todo 10
|
if (t_compareResults.size() > topN) {
|
t_compareResults.erase((--t_compareResults.end()), t_compareResults.end());
|
}
|
t_rwLock.unlock();
|
});
|
} else {
|
//Max
|
float maxScore = 0;
|
parallelFor(ParallelForThreardSize::CPU_Number, [&](string &key, FeatureData &data) {
|
//#todo
|
double sc = 0;
|
for (auto &t_fea : data.features) {
|
double t_sc = m_casiaFaceWapper.compareFeature(alarmData->feature, t_fea);
|
if (t_sc > sc) sc = t_sc;
|
}
|
FaceResult tface{0, data.uuid, alarmData->tableName, sc, data.faceUrl, data.idcard, ""};
|
t_rwLock.wrlock();
|
if (sc < maxScore) {
|
t_rwLock.unlock();
|
return;
|
} else {
|
t_compareResults.clear();
|
t_compareResults.insert(make_pair(tface.confidence, tface));
|
maxScore = t_compareResults.begin()->second.confidence;
|
}
|
t_rwLock.unlock();
|
});
|
}
|
m_rwLock.unlock();
|
|
int maxSearchFaces = alarmData->num;
|
|
t_rwl.wrlock();
|
auto &t_topResult = topResult[key];
|
t_topResult.clear();
|
for (auto &item : t_compareResults) {
|
auto &it = item.second;
|
//#todo
|
// if (it.confidence <= 0.6) {
|
// continue;
|
// }
|
FaceResult t_CR{it.id, it.uuid, it.tableName, it.confidence, it.face_img_url, it.idCard, it.alarmRet};
|
//cout << __FUNCTION__ << " -> " << __LINE__ << " -> scroe" << it.confidence << endl;
|
t_topResult.push_back(t_CR);
|
}
|
while (topResult.size() > maxSearchFaces)
|
t_topResult.pop_back();
|
t_rwl.unlock();
|
return true;
|
}
|
|
bool FaceDBCompareServer::compare(std::thread::id key, AlarmData *alarmData) {
|
if (m_dbRWLocks.find(key) == m_dbRWLocks.end()) {
|
m_dbRWLocks[key] = RWLock();
|
}
|
RWLock &t_rwl = m_dbRWLocks[key];
|
// ClockTimer clockTimer("compare ");
|
t_rwl.wrlock();
|
RWLock t_rwLock;
|
mapFaceResults t_compareResults;
|
m_rwLock.rdlock();
|
parallelFor(ParallelForThreardSize::CPU_Number, [&](string &key, FeatureData &data) {
|
double sc = 0;
|
for (auto &t_fea : data.features) {
|
double t_sc = m_casiaFaceWapper.compareFeature(alarmData->feature, t_fea);
|
if (t_sc > sc)sc = t_sc;
|
}
|
FaceResult tface{data.face_id, data.uuid, alarmData->tableName, sc, data.faceUrl, data.idcard, ""};
|
// FaceResult tface{0, data.uuid, alarmData->tableName, sc, data.faceUrl,false};
|
t_rwLock.wrlock();
|
if (sc < alarmData->threshold) {
|
t_rwLock.unlock();
|
DBG("return");
|
return;
|
}
|
if (t_compareResults.size() > alarmData->num) {
|
t_compareResults.erase((--t_compareResults.end()), t_compareResults.end());
|
}
|
t_compareResults.insert(make_pair(tface.confidence, tface));
|
t_rwLock.unlock();
|
});
|
m_rwLock.unlock();
|
int maxSearchFaces = alarmData->num;
|
auto &t_topResult = topResult[key];
|
t_topResult.clear();
|
for (auto &item : t_compareResults) {
|
auto &it = item.second;
|
FaceResult t_CR{it.id, it.uuid, it.tableName, it.confidence, it.face_img_url, it.idCard, it.alarmRet};
|
// FaceResult t_CR{it.id, it.uuid, it.tableName, it.confidence, it.face_img_url, ""};
|
t_topResult.push_back(t_CR);
|
}
|
// while (t_topResult.size() > maxSearchFaces)
|
// t_topResult.pop_back();
|
return true;
|
}
|
|
void FaceDBCompareServer::loadDBData(std::string str_config) {
|
string log = "loadDBData " + str_config;
|
ClockTimer clk(log);
|
|
Json::Value t_json;
|
Json::FastWriter writer;
|
Json::Reader reader;
|
|
if (reader.parse(str_config, t_json)) {
|
|
m_rwLock.wrlock();
|
if (t_json["\"syncTpye\""].type() == Json::nullValue) {
|
auto str_tab = t_json["\"tableName\""].asString();
|
m_tableName = str_tab.substr(1, str_tab.length() - 2);//.append("_fea");
|
|
string tet = "./syncDBClient ";
|
string str_json = writer.write(t_json);
|
tet.append("\"" + str_json.substr(0, str_json.length() - 1) + "\" ");
|
INFO(tet);
|
system(tet.c_str());
|
dataMap.clear();
|
try {
|
// init
|
BISTL::BiMapFeaData biMapFeaData(m_tableName);
|
auto mymap = biMapFeaData.getMap();
|
auto size = mymap->size();
|
//#todo
|
for (auto it = mymap->begin(); it != mymap->end(); it++) {
|
string str_uuid(it->second.m_id.data());
|
string ft(it->second.m_feature.data());
|
string imgUrl(it->second.m_imgUrl.data());
|
string strIdCard(it->second.m_idcard.data());
|
string str2;
|
str2 = base64.Decode(ft.data(), ft.length());
|
std::vector<unsigned char> t_fea;
|
t_fea.resize(str2.size());
|
memcpy(t_fea.data(), str2.data(), str2.size());
|
auto &test = dataMap[str_uuid];
|
test.uuid = str_uuid;
|
test.features.push_back(t_fea);
|
test.faceUrl = imgUrl;
|
test.idcard = strIdCard;
|
}
|
} catch (const std::exception &e) {
|
printf("Exception:%s\n", e.what());
|
BISTL::shared_memory_object::remove(m_tableName.c_str());
|
}
|
BISTL::shared_memory_object::remove(m_tableName.c_str());
|
appPref.setIntData(m_tableName, 1);
|
DBG(m_tableName << " size is " << dataMap.size());
|
} else {
|
//#todo get sqlite3 data
|
m_tableName = t_json["tableName"].asCString();
|
auto t_res = m_sqliteFaceEncap->getFacesFromTable(m_tableName);
|
auto t_faceInfoCache = m_sqliteFaceEncap->getFaceInfoFromTable(m_tableName);
|
auto &res = *t_res;
|
//#todo
|
DBG(m_tableName << "clear before size is " << dataMap.size());
|
dataMap.clear();
|
DBG(m_tableName << "clear after size is " << dataMap.size());
|
for (auto &item : res) {
|
auto &t_sen = item.second;
|
std::vector<unsigned char> t_fea;
|
t_fea.resize(t_sen.faceFeature.size());
|
memcpy(t_fea.data(), t_sen.faceFeature.data(), t_sen.faceFeature.size());
|
auto &test = dataMap[t_sen.uuid];
|
test.uuid = t_sen.uuid;
|
test.features.push_back(t_fea);
|
test.faceUrl = t_sen.faceurl;
|
test.idcard = t_faceInfoCache[t_sen.uuid].idCard;
|
}
|
appPref.setIntData(m_tableName, 1);
|
DBG(m_tableName << " size is " << dataMap.size());
|
}
|
m_rwLock.unlock();
|
} else {
|
ERR("json format error :: " << str_config);
|
appPref.setIntData(str_config, 1);
|
}
|
|
}
|