// // Created by pans on 4/27/18. // #include #include "jsoncpp/json/json.h" #include #include #include "FaceFeatureSearchServerI.h" using namespace std; static std::string t_cNodeName = "FaceSearch"; void erlangCallBackFunc(std::string) { DBG("erlangCallBackFunc"); pthread_cond_signal(&(func_cond)); pthread_mutex_unlock(&(func_cond_mutex)); } FaceFeatureSearchServerI::FaceFeatureSearchServerI() : m_erlangDbTool(appConfig.getStringProperty("erlPath"), appConfig.getStringProperty("erlNode"), appConfig.getStringProperty("erlCookie"), t_cNodeName), m_retUpdatePthread(true), pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")), m_sqliteFaceEncap("LocalDataDB") { auto erlFatherNode = appConfig.getStringProperty("erlFatherNode"); if (m_erlangDbTool.initErlang() == 1) { m_erlangDbTool.startNodeDb(erlFatherNode); } m_erlangDbTool.test(&func_cond, &func_cond_mutex); loadFeatureData(this); } FaceFeatureSearchServerI::FaceFeatureSearchServerI(Ice::CommunicatorPtr &ich, string nodeName, string cookie) : m_erlangDbTool(nodeName, cookie, t_cNodeName), m_retUpdatePthread(true), pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")), m_sqliteFaceEncap("LocalDataDB") { // try { // std::string identity2 = ich->getProperties()->getProperty("user.FaceData"); // DBG(identity2); // base_FaceMemoryData = ich->stringToProxy(appPref.getStringData("user.FaceData")); // } catch (std::exception ex) { // ERR("base_FaceMemoryData connceticon fail" << ex.what()); // }; loadFeatureData(this); } FaceFeatureSearchServerI::~FaceFeatureSearchServerI() { t_live_ret = false; } //#todo 优化 ::FaceSearch::FaceResults FaceFeatureSearchServerI::faceSearchMax(const ::FaceSearch::Data &feature, const ::std::string &info_json, const ::Ice::Current &) { thread::id key = std::this_thread::get_id(); ClockTimer clockTimer("faceSearchMax"); ::FaceSearch::FaceResults results; FaceResults t_TableCompareResult; AlarmData featureData; featureData.num = 1; featureData.feature.resize(feature.size()); memcpy(featureData.feature.data(), feature.data(), feature.size()); for (auto &it : m_faceFCMAP) { auto &t_FaceFC = it.second; auto t_tableInfo = m_tableType[it.first]; bool ret = getRet(t_tableInfo.startTime, t_tableInfo.endTime); if (ret) { bool alarmRet = atoi(t_tableInfo.bwType.c_str()); //#todo 非同步库是否需要比较? t_FaceFC->compare(key, &featureData, 1); auto t_results = t_FaceFC->getTopResult(key); for (auto &t_item : t_results) { t_item.tableName = it.first; //#todo baojing zhuangtai ? t_item.alarmRet = ret; t_TableCompareResult.push_back(t_item); } } } // DBG("t_TableCompareResult size" << t_TableCompareResult.size()); for (auto itor = t_TableCompareResult.begin(); itor != t_TableCompareResult.end(); ++itor) { float new_confidence = itor->confidence; auto rtTR = results.rbegin(); if (!results.empty()) { auto temp = rtTR->confidence; while (new_confidence > temp) { ++rtTR; if (rtTR == (results.rend() + 1)) { rtTR--; break; } else { // DBG(" sc is "<< new_confidence << " > " << temp); } temp = rtTR->confidence; } } else { // INFO("topResult is null"); } auto itTR(rtTR.base()); ::FaceSearch::FaceResult t_faceCR; t_faceCR.id = itor->id; t_faceCR.uuid = itor->uuid; t_faceCR.tableName = itor->tableName; t_faceCR.confidence = itor->confidence; DBG("compare results tablename is " << t_faceCR.tableName << " id is " << t_faceCR.uuid << " sc is" << t_faceCR.confidence); results.insert(itTR, t_faceCR); } //#todo send message return results; } //#todo 优化 ::FaceSearch::FaceResults FaceFeatureSearchServerI::faceSearchTopN(const ::FaceSearch::Data &feature, const ::std::string &info_json, ::Ice::Int topN, ::Ice::Float score, const ::Ice::Current &) { ClockTimer clockTimer("faceSearchTopN " + to_string(score) + " :"); INFO("faceSearchTopN start"); thread::id key = std::this_thread::get_id(); ::FaceSearch::FaceResults results; FaceResults t_TableCompareResult; AlarmData featureData; featureData.num = topN; featureData.feature.resize(feature.size()); memcpy(featureData.feature.data(), feature.data(), feature.size()); Json::Reader reader; Json::Value value; if (reader.parse(info_json, value)) { //#todo m_rwLock.rdlock(); std::string feature_base64; feature_base64 = base64.Encode(feature.data(), feature.size()); value["FaceFeature"] = feature_base64; DBG("auto &it : m_faceFCMAP start " << m_faceFCMAP.size()); //#todo lock for (auto &it : m_faceFCMAP) { auto &t_FaceFC = it.second; auto t_tableInfo = m_tableType[it.first]; bool ret = getRet(t_tableInfo.startTime, t_tableInfo.endTime); if (ret) { string t_alarmRet = t_tableInfo.bwType; // bool alarmRet = atoi(t_tableInfo.bwType.c_str()); //#todo 非同步库是否需要比较? DBG("m_faceFCMAP compare start " << it.first); t_FaceFC->compare(key, &featureData, topN); DBG("m_faceFCMAP compare end " << it.first); auto t_results = t_FaceFC->getTopResult(key); for (auto &t_item : t_results) { t_item.tableName = it.first; t_item.alarmRet = t_alarmRet; t_TableCompareResult.push_back(t_item); // DBG("t_results item : uuid is " << t_item.uuid << " confidence " << t_item.confidence << it.first); } } else { INFO("m_faceFCMAP ret is false " << it.first); } } m_rwLock.unlock(); DBG("auto &it : m_faceFCMAP end"); DBG("t_TableCompareResult size" << t_TableCompareResult.size()); //sort_all_results for (auto itor = t_TableCompareResult.begin(); itor != t_TableCompareResult.end(); ++itor) { float new_confidence = itor->confidence; auto rtTR = results.rbegin(); if (!results.empty()) { auto temp = rtTR->confidence; while (new_confidence > temp) { ++rtTR; if (rtTR == (results.rend() + 1)) { rtTR--; break; } else { } temp = rtTR->confidence; } } else { ERR("topResult is null"); } auto itTR(rtTR.base()); ::FaceSearch::FaceResult t_faceCR; t_faceCR.id = itor->id; t_faceCR.uuid = itor->uuid; t_faceCR.tableName = itor->tableName; t_faceCR.confidence = itor->confidence; //#todo url idcard t_faceCR.imgUrl = itor->face_img_url; t_faceCR.idcard = itor->idCard; t_faceCR.alarmRet = itor->alarmRet; DBG("compare results tablename is " << t_faceCR.tableName << " id is " << t_faceCR.uuid << " pic n " << t_faceCR.idcard << " sc is" << t_faceCR.confidence); results.insert(itTR, t_faceCR); } bool retface = true; // cout << __FUNCTION__ << " -> " << __LINE__ << " -> " << results.size() << endl; //#todo send message if (results.size() > 0) { for (auto &item : results) { //#todo 得分比较,应该在compare中进行 if (item.confidence < score) { //#todo test auto str_uuid = value["Id"].asString(); value["personIsHub"] = "4"; value["likePer"] = 0.0; // DBG(value.toStyledString()); cout << __FUNCTION__ << " -> " << __LINE__ << " -> " << "value.toStyledString() " << value.toStyledString() << endl; retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(), str_uuid); break; } value["personId"] = item.uuid.size() > 0 ? item.uuid : "";//关联底库人员id,人脸id // string tmp_tableName = item.tableName; // if (tmp_tableName.find("lt_") == 0) { // tmp_tableName = tmp_tableName.insert(tmp_tableName.find("lt_") + 3, "::"); // value["BaseName"] = tmp_tableName;//关联底库表名 // } else { // value["BaseName"] = item.tableName.size() > 0 ? item.tableName : "";//关联底库表名 // } value["BaseName"] = item.tableName.size() > 0 ? item.tableName : "";//关联底库表名 value["likePer"] = item.confidence > 0 ? item.confidence : 0.0; value["personPicUrl"] = item.imgUrl.size() > 0 ? item.imgUrl : "";//diku tupian value["idcard"] = item.idcard.size() > 0 ? item.idcard : "";//diku tupian //如果 alarmRet 不为空把 他的值 放入 personIsHub,否则为4 value["personIsHub"] = item.alarmRet.size() > 0 ? item.alarmRet : "4"; auto str_uuid = value["Id"].asString(); // DBG(value.toStyledString()); cout << __FUNCTION__ << " -> " << __LINE__ << " -> " << "value.toStyledString() " << value.toStyledString() << "\n score " << score << endl; // DBG("score " << score); retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(), str_uuid); break; } } else { auto str_uuid = value["Id"].asString(); value["personIsHub"] = "4"; value["likePer"] = 0.0; DBG(value.toStyledString()); // cout << __FUNCTION__ << " -> " << __LINE__ << " -> " << "value.toStyledString() " // << value.toStyledString() << endl; retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", value.toStyledString(), str_uuid); } if (!retface) { ERR("insert error"); } else { cout << __FUNCTION__ << " -> " << __LINE__ << " -> " << "retface " << retface << endl; }; } else { ERR("json is error" << info_json); } // for (auto &item : t_tables) { // DBG(item); // } return results; } bool FaceFeatureSearchServerI::loadFeatureData(FaceFeatureSearchServerI *faceFea) { ErlangTool::map_TabDataCache dataBaseCache = faceFea->m_erlangDbTool.findAllDatabase(); if (dataBaseCache.size() < 0 && faceFea->m_retUpdatePthread) { faceFea->m_retUpdatePthread = false; std::thread thd(dataUpdate, faceFea); thd.detach(); } auto typeInfoCache = faceFea->m_erlangDbTool.findAllTypeInfo(); faceFea->m_tableType.clear(); string str_config = faceFea->m_erlangDbTool.getConfigJsonString(); Json::Value t_json; Json::FastWriter writer; Json::Reader reader; faceFea->m_rwLock.wrlock(); if (reader.parse(str_config, t_json)) { for (auto &item : dataBaseCache) { TableInfo tabInfo; tabInfo.tableName = item.first; tabInfo.startTime = item.second.startTime; tabInfo.endTime = item.second.endTime; // tabInfo.bwType = item.second.bwType = typeInfoCache.find(item.first)->second.bwType; tabInfo.bwType = item.second.bwType;//= typeInfoCache.find(item.first)->second.bwType; tabInfo.createBy = item.second.create_by; if ((tabInfo.tableName.find("lt_") == 0) && (tabInfo.createBy != appConfig.getStringProperty("erlNode"))) { continue; } string &tableName = item.second.tableName; faceFea->m_tableType[tableName] = tabInfo; appPref.setIntData(tableName, 0); if (faceFea->m_faceFCMAP.find(tableName) == faceFea->m_faceFCMAP.end()) { faceFea->m_faceFCMAP[tableName] = new FaceDBCompareServer(&(faceFea->m_erlangDbTool)); // usleep(1000); } t_json["\"tableName\""] = "\"" + tableName + "\""; std::string str_json = writer.write(t_json); str_json.substr(0, str_json.length() - 1); // sleep(1); usleep(1500 * 1000); faceFea->m_faceFCMAP[tableName]->initDB(str_json); DBG("initDB tableName " << tableName); } } else { ERR("json format error :: " << str_config); } //#todo get data from sqlite3 { //#查询人脸底库列表 auto res = faceFea->m_sqliteFaceEncap.getTableInfos(); for (auto &item : res) { if (item.tableType == "person") { std::cout << "tableName is " << item.tableName << std::endl; { std::string tableName = item.tableName; faceFea->m_tableType[tableName] = item; appPref.setIntData(tableName, 0); if (faceFea->m_faceFCMAP.find(tableName) == faceFea->m_faceFCMAP.end()) { faceFea->m_faceFCMAP[tableName] = new FaceDBCompareServer(&(faceFea->m_sqliteFaceEncap)); } Json::Value t_json2; t_json2.clear(); t_json2["\"syncTpye\""] = "local"; t_json2["tableName"] = tableName; std::string str_json = writer.write(t_json2); str_json.substr(0, str_json.length() - 1); faceFea->m_faceFCMAP[tableName]->initDB(str_json); DBG("initDB tableName " << tableName); } } } } faceFea->m_rwLock.unlock(); INFO("get time"); faceFea->m_inTime = getTimeLong(); if (faceFea->m_retUpdatePthread) { faceFea->m_retUpdatePthread = false; std::thread thd(dataUpdate, faceFea); // faceFea->m_erlangDbTool.test(faceFea, erlangCallBackFunc); INFO("start thread"); thd.detach(); } else { ERR("m_retUpdatePthread is false "); } return false; } void FaceFeatureSearchServerI::waitTables(FaceFeatureSearchServerI *faceFea, int loop) { DBG("waitTales"); while (t_live_ret) { faceFea->m_rwLock.rdlock(); if (faceFea->m_faceFCMAP.size() == 0) { ERR("table size is 0"); faceFea->m_rwLock.unlock(); return; } bool tmp = true; for (auto &t_face : faceFea->m_faceFCMAP) { auto t_ret = appPref.getIntData(t_face.first); tmp = t_ret & tmp; } if (tmp && faceFea->m_faceFCMAP.size() > 0) { INFO("waitTables ok"); faceFea->m_rwLock.unlock(); return; } else { ERR("tmp is " << tmp << " faceFea->m_faceFCMAP.size() is " << faceFea->m_faceFCMAP.size()); faceFea->m_rwLock.unlock(); usleep(1000); // if (loop != -1 && loop-- < 1) { // ERR("return " << loop); // return; // } } } return; } //void FaceFeatureSearchServerI::erlangCallBackFunc(std::string) { // DBG("erlangCallBackFunc"); // pthread_cond_signal(&(func_cond)); // pthread_mutex_unlock(&(func_cond_mutex)); //} void FaceFeatureSearchServerI::dataUpdate(FaceFeatureSearchServerI *faceFea) { long inTime = faceFea->m_inTime; // modify all db ready start update, <10s faceFea->waitTables(faceFea, 100); int loop = 0; long outTime; //update while (t_live_ret) { DBG(" wait lock?"); pthread_mutex_lock(&(func_cond_mutex)); DBG(" get lock?"); pthread_cond_wait(&(func_cond), &(func_cond_mutex)); try { // faceFea->m_rwLock.rdlock(); // if (faceFea->m_faceFCMAP.size() > 0) { // faceFea->m_rwLock.unlock(); // } else { // faceFea->m_rwLock.unlock(); // } DBG("update data sleep before "); int sleepTime = appConfig.getIntProperty("FaceSeachSleepTime"); sleepTime = sleepTime > 30 ? sleepTime : 30; DBG("sleepTime is " << sleepTime); sleep(30); inTime = outTime; outTime = 0; cout << " loop is " << loop++ << endl; faceFea->loadFeatureData(faceFea); faceFea->waitTables(faceFea, 100000); pthread_mutex_unlock(&func_cond_mutex); } catch (std::exception ex) { ERR(ex.what()); } } } bool FaceFeatureSearchServerI::initErlang(std::string nodeName, std::string cookie) { //#todo // m_erlangDbTool = ErlangTool::ErlangDbTool(nodeName, cookie); return false; }