// // Created by ps on 2/26/18. // #include #include #include #include #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 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 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); } }