| | |
| | | #include <QtCore/QString> |
| | | #include <basic/util/app/AppUtil.h> |
| | | #include <basic/util/opencv/CvUtil.h> |
| | | #include <basic/util/app/AppPreference.hpp> |
| | | //diao用对应es数据封装的类 |
| | | //#include <basic/db/ES/es/ManagerEsDB.h> |
| | | #include <basic/db/Elasticsearch/EsDBTool.h> |
| | |
| | | #include <QtCore/QJsonObject> |
| | | #include <uuid/uuid.h> |
| | | #include <jsoncpp/json/json.h> |
| | | #include <basic/util/app/AppConfig.h> |
| | | |
| | | #define state "state" |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | FaceExtractElement::FaceExtractElement(std::string shareMemoryName) : |
| | | FaceExtractElement::FaceExtractElement(std::string shareMemoryName, const SdkRule &rule) : |
| | | TimerElement(1000), sharedMemory(nullptr), fdfsClient(nullptr), |
| | | //#todo appPref.setStringData |
| | | faceExtractRpcClient(appPref.getStringData("faceExte.proxy"), appPref.getStringData("faceExte.ip"), |
| | |
| | | // faceExtractRpcClient(/*appPref.getStringData("face.extract.proxy")*/ |
| | | // "faceExtractServer", "", 10008, "tcp"),//人脸特征提取 修改成点对点通讯 |
| | | faceSearchRpcClient(appPref.getStringData("faceSear.proxy"), appPref.getStringData("faceSear.ip"), |
| | | appPref.getIntData("faceSear.port"), "tcp") |
| | | appPref.getIntData("faceSear.port"), "tcp"), |
| | | // faceSearchRpcClient("faceCmServer", "", 10004, "tcp") |
| | | { |
| | | m_sdkRule(rule), |
| | | m_rpcClient("RtspAnalysServer", "127.0.0.1", appPref.getIntData("RpcVTIMPort"), "tcp") { |
| | | sharedMemory = new QSharedMemory(QString(shareMemoryName.c_str())); |
| | | if (!sharedMemory->create(4608 * 2592 * 4)) { |
| | | sharedMemory->attach(); |
| | |
| | | } |
| | | |
| | | void FaceExtractElement::timerFunc() { |
| | | // INFO("MYH Run Here"); |
| | | std::vector<FaceToExtract> faceExtractQueueTmp; |
| | | { |
| | | std::lock_guard<std::mutex> lg(imageQueueMutex); |
| | | if (faceExtractQueue.empty())return; |
| | | if (faceExtractQueue.empty()) { |
| | | ERR("faceExtractQueue.empty "); |
| | | return; |
| | | } |
| | | faceExtractQueueTmp.swap(faceExtractQueue); |
| | | faceExtractQueue.clear(); |
| | | } |
| | | try { |
| | | |
| | | string t_camIdex = getProperty("dev_id") + getProperty("ch_id"); |
| | | float t_com_sc = |
| | | appPref.getFloatData(t_camIdex + "face.cmp") == -1 ? 75 : appPref.getFloatData(t_camIdex + "face.cmp"); |
| | | float t_com_sc = m_sdkRule.nThreshold == 0 ? 75 : m_sdkRule.nThreshold; |
| | | |
| | | DBG(" TESTCODE getValue" << t_camIdex << " " << t_com_sc << " " << t_com_sc / 100); |
| | | |
| | | // DBG(" TESTCODE getValue" << t_camIdex << " " << t_com_sc << " " << t_com_sc / 100); |
| | | |
| | | t_com_sc = t_com_sc / 100; |
| | | |
| | |
| | | auto sharedImage = cv::Mat(image.rows, image.cols, CV_8UC3, sharedMemory->data()); |
| | | image.copyTo(sharedImage); |
| | | |
| | | |
| | | // 上传大图 |
| | | string strBigImgUrl; |
| | | if (fdfsClient != nullptr && fdfsClient->fastFds != nullptr) { |
| | | fdfsClient->rwLock.rdlock(); |
| | | std::vector<unsigned char> buffer; |
| | | CvUtil::cvMat2Buffer(image, buffer); |
| | | fdfsClient->fastFds->uploadFile(buffer, strBigImgUrl, "jpg"); |
| | | fdfsClient->rwLock.unlock(); |
| | | } else { |
| | | strBigImgUrl = ""; |
| | | ERR("fdfsClient is nullptr ???"); |
| | | } |
| | | |
| | | unsigned long size = faceExtractQueueTmp[i].facesPos.size(); |
| | | for (int j = 0; j < size; j++) { |
| | | auto feature = extractServer->faceExtract(image.cols, image.rows, faceExtractQueueTmp[i].facesPos[j], |
| | |
| | | // cv::imwrite(string1, image); |
| | | // } |
| | | if (feature.empty()) { |
| | | ERR("feature is empty"); |
| | | // INFO("No Face Find: " << getProperty("imgKey")); |
| | | continue; |
| | | } |
| | | features.clear(); |
| | | features.emplace_back(feature); |
| | | |
| | | std::string strImgUrl = "http://"; |
| | | if (fdfsClient != nullptr && fdfsClient->fastFds != nullptr) { |
| | | fdfsClient->rwLock.rdlock(); |
| | |
| | | CvUtil::cvMat2Buffer(faceExtractQueueTmp[i].faceImages[j], buffer); |
| | | std::string strImgUrlTmp = ""; |
| | | fdfsClient->fastFds->uploadFile(buffer, strImgUrlTmp, "jpg"); |
| | | strImgUrl.append(fdfsClient->fastFds->getIp() + "/" + strImgUrlTmp); |
| | | // strImgUrl.append(fdfsClient->fastFds->getIp() + "/" + strImgUrlTmp); |
| | | // DBG("strImgUrlTmp=" << strImgUrlTmp); |
| | | strImgUrl.clear(); |
| | | strImgUrl = strImgUrlTmp; |
| | | // strImgUrl.append("/").append(strImgUrlTmp); |
| | | fdfsClient->rwLock.unlock(); |
| | | } |
| | | |
| | | //拼接json |
| | | string str_uuid; |
| | | uuid_t t_uuid; |
| | | char str[36]; |
| | | uuid_generate(t_uuid); |
| | | uuid_unparse(t_uuid, str); |
| | | str_uuid = str; |
| | | |
| | | Json::Value t_json; |
| | | t_json["Id"] = str_uuid; //主键 |
| | | |
| | | //#在对比中添加特征值 |
| | | t_json["FaceFeature"] = "base64"; |
| | | t_json["personId"] = "wait todo";//关联底库人员id,人脸id |
| | | t_json["BaseName"] = "wait todo";//关联底库表名 |
| | | //#end |
| | | // t_json["likePer"] = faceExtractQueueTmp[i].scoredRects[j].score;//人员相似度 Score |
| | | t_json["likeDate"] = AppUtil::getTimeSecString();//"2018-01-01 01:01:01";//比较时间 |
| | | |
| | | t_json["picName"] = "wait todo"; |
| | | |
| | | |
| | | t_json["personPicUrl"] = "wait todo";//人员图片 store |
| | | t_json["picAddress"] = getProperty("str_addr");//抓拍地址 |
| | | t_json["picMaxUrl"] = "wait todo";//大图路径 |
| | | t_json["picLocalUrl"] = "wait todo";//本地路径 |
| | | t_json["picSmUrl"] = strImgUrl;//人员抓小图 |
| | | //#todo |
| | | t_json["picDate"] = faceExtractQueueTmp[i].scoredRects[j].properties["time"]; |
| | | // DBG("timeC ::::B" << t_json["picDate"].asString()); |
| | | // t_json["picDate"] = AppUtil::getTimeSecString(); |
| | | |
| | | t_json["content"] = "wait todo"; |
| | | t_json["viType"] = "1";//只有4种类型 1:personface 2:personbody 3:car 4:bicycle 5:none 未知类型 |
| | | t_json["personIsHub"] = "4";//1: 报警 2: 可疑 3: 安全 4: 未知 |
| | | |
| | | |
| | | //faceExtractElement.setProperty("dev_id", str_device_id); |
| | | //faceExtractElement.setProperty("cg_id", str_ch_id); |
| | | t_json["videoNum"] = getProperty("dev_id");//Video设备编号//getProperty("path");//Vide编号 外键 |
| | | t_json["videoReqNum"] = getProperty("dev_id");//Video设备编号 |
| | | t_json["ChannlId"] = getProperty("ch_id");//通道id |
| | | t_json["isDelete"] = "1";//默认1 ,0无效 1有效 |
| | | |
| | | //人脸属性 |
| | | t_json["Age"] = atoi( |
| | | faceExtractQueueTmp[i].scoredRects[j].properties["age"].c_str());//检测的年龄 应该为空 无检测结果 |
| | | |
| | | //#todo 优化 get vector<string> from json |
| | | t_json["Gender"] = faceExtractQueueTmp[i].scoredRects[j].properties["gender"];//检测的性别 为空 无检测结果 |
| | | switch (atoi(faceExtractQueueTmp[i].scoredRects[j].properties["gender"].c_str())) { |
| | | case 0: |
| | | t_json["Gender"] = "女"; |
| | | break; |
| | | case 1: |
| | | t_json["Gender"] = "男"; |
| | | break; |
| | | } |
| | | |
| | | t_json["BeautyLevel"] = faceExtractQueueTmp[i].scoredRects[j].properties["beauty"];//检测的美化水平 为空 无检测结果 |
| | | t_json["SimleLevel"] = faceExtractQueueTmp[i].scoredRects[j].properties["smile"];//检测的微笑水平 为空 无检测结果 |
| | | t_json["Race"] = "";//检测的种族 应该为空 无检测结果 |
| | | t_json["videoIp"] = getProperty("local_ip");//当前服务器IP地址 |
| | | |
| | | //#todo 优化 get vector<string> from json |
| | | switch (atoi(faceExtractQueueTmp[i].scoredRects[j].properties["race"].c_str())) { |
| | | case 1: |
| | | t_json["Race"] = "白人"; |
| | | break; |
| | | case 2: |
| | | t_json["Race"] = "黄人"; |
| | | break; |
| | | case 3: |
| | | t_json["Race"] = "黑人"; |
| | | break; |
| | | } |
| | | |
| | | // DBG(t_json.toStyledString()); |
| | | |
| | | t_json["indeviceid"] = appPref.getStringData("fxDevID"); |
| | | t_json["indevicename"] = appPref.getStringData("fxDevNAME"); |
| | | |
| | | auto faceSearchServer = faceSearchRpcClient.getServer(); |
| | | if (!faceSearchServer) { |
| | | ERR("faceSearchServer is null"); |
| | | EsDBTool pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")); |
| | | bool retface = false; |
| | | retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", t_json.toStyledString(), |
| | | str_uuid); |
| | | // if (retface) { |
| | | // INFO("facedb success"); |
| | | // } else { |
| | | // ERR("facedb fail"); |
| | | // } |
| | | } else { |
| | | INFO("send faceSearchTopN "); |
| | | auto faceSearchResults = faceSearchServer->faceSearchTopN(feature, t_json.toStyledString(), 2, |
| | | t_com_sc); |
| | | strImgUrl = ""; |
| | | ERR("fdfsClient is nullptr ???"); |
| | | } |
| | | InsertToESDB(faceExtractQueueTmp, t_com_sc, i, j, feature, strImgUrl, strBigImgUrl); |
| | | |
| | | } |
| | | } |
| | | } catch (std::exception &e) { |
| | |
| | | if (!features.empty())fireConnectors(); |
| | | } |
| | | |
| | | void FaceExtractElement::InsertToESDB(const vector<FaceToExtract> &faceExtractQueueTmp, float t_com_sc, int i, int j, |
| | | FaceDetect::Data &feature, string &strImgUrl, string &strBigImgUrl) { |
| | | //拼接json |
| | | string str_uuid; |
| | | uuid_t t_uuid; |
| | | char str[36]; |
| | | uuid_generate(t_uuid); |
| | | uuid_unparse(t_uuid, str); |
| | | str_uuid = str; |
| | | |
| | | Json::Value t_json; |
| | | t_json["Id"] = str_uuid; //主键 |
| | | |
| | | string feature_base64; |
| | | feature_base64 = base64.Encode(feature.data(), feature.size()); |
| | | |
| | | //#在对比中添加特征值 |
| | | t_json["FaceFeature"] = feature_base64; |
| | | t_json["personId"] = "";//关联底库人员id,人脸id |
| | | t_json["BaseName"] = "";//关联底库表名 |
| | | //#end |
| | | // t_json["likePer"] = faceExtractQueueTmp[i].scoredRects[j].score;//人员相似度 Score |
| | | t_json["likeDate"] = AppUtil::getTimeSecString();//"2018-01-01 01:01:01";//比较时间 |
| | | |
| | | t_json["picName"] = ""; |
| | | |
| | | |
| | | t_json["personPicUrl"] = "";//人员图片 store |
| | | t_json["picAddress"] = getProperty("str_addr");//抓拍地址 |
| | | DBG("picAddress=" << t_json["picAddress"]); |
| | | t_json["picMaxUrl"] = strBigImgUrl;//大图路径 |
| | | t_json["picLocalUrl"] = "";//本地路径 |
| | | t_json["picSmUrl"] = strImgUrl;//人员抓小图 |
| | | //#todo |
| | | t_json["picDate"] = faceExtractQueueTmp[i].scoredRects[j].properties["time"]; |
| | | DBG("picDate=" << t_json["picDate"].asString()); |
| | | // DBG("timeC ::::B" << t_json["picDate"m_bIsMask].asString()); |
| | | // t_json["picDate"] = AppUtil::getTimeSecString(); |
| | | |
| | | t_json["content"] = ""; |
| | | //t_json["viType"] = "2";//只有4种类型 1:personface 2:personbody 3:car 4:bicycle 5:none 未知类型 |
| | | t_json["sdkType"] = to_string( |
| | | m_sdkRule.nSdkType);//只有4种类型 1:personface 2:personbody 3:car 4:bicycle 5:none 未知类型 |
| | | t_json["personIsHub"] = "4";//1: 报警 2: 可疑 3: 安全 4: 未知 |
| | | |
| | | |
| | | t_json["cluster_id"] = appPref.getStringData("clusterID"); |
| | | t_json["ack_alarm"] = "0"; |
| | | |
| | | //faceExtractElement.setProperty("dev_id", str_device_id); |
| | | //faceExtractElement.setProperty("cg_id", str_ch_id); |
| | | t_json["videoNum"] = getProperty("dev_id");//Video设备编号//getProperty("path");//Vide编号 外键 |
| | | t_json["videoReqNum"] = getProperty("dev_id");//Video设备编号 |
| | | t_json["ChannlId"] = getProperty("ch_id");//通道id |
| | | t_json["isDelete"] = "1";//默认1 ,0无效 1有效 |
| | | |
| | | //人脸属性 |
| | | t_json["Age"] = atoi( |
| | | faceExtractQueueTmp[i].scoredRects[j].properties["age"].c_str());//检测的年龄 应该为空 无检测结果 |
| | | |
| | | //#todo 优化 get vector<string> from json |
| | | t_json["Gender"] = faceExtractQueueTmp[i].scoredRects[j].properties["gender"];//检测的性别 为空 无检测结果 |
| | | switch (atoi(faceExtractQueueTmp[i].scoredRects[j].properties["gender"].c_str())) { |
| | | case 0: |
| | | t_json["Gender"] = "女"; |
| | | break; |
| | | case 1: |
| | | t_json["Gender"] = "男"; |
| | | break; |
| | | } |
| | | |
| | | t_json["BeautyLevel"] = faceExtractQueueTmp[i].scoredRects[j].properties["beauty"];//检测的美化水平 为空 无检测结果 |
| | | t_json["SimleLevel"] = faceExtractQueueTmp[i].scoredRects[j].properties["smile"];//检测的微笑水平 为空 无检测结果 |
| | | t_json["Race"] = "";//检测的种族 应该为空 无检测结果 |
| | | t_json["videoIp"] = getProperty("local_ip");//当前服务器IP地址 |
| | | |
| | | t_json["cluster_id"] = appConfig.getStringProperty("clusterID");//集群id |
| | | t_json["ack_alarm"] = "0";//ack_alarm是否报警 |
| | | |
| | | //#todo 优化 get vector<string> from json |
| | | switch (atoi(faceExtractQueueTmp[i].scoredRects[j].properties["race"].c_str())) { |
| | | case 1: |
| | | t_json["Race"] = "白人"; |
| | | break; |
| | | case 2: |
| | | t_json["Race"] = "黄人"; |
| | | break; |
| | | case 3: |
| | | t_json["Race"] = "黑人"; |
| | | break; |
| | | } |
| | | |
| | | // DBG(t_json.toStyledString()); |
| | | |
| | | t_json["indeviceid"] = appPref.getStringData("fxDevID"); |
| | | t_json["indevicename"] = appPref.getStringData("fxDevNAME"); |
| | | |
| | | string strImageKey = faceExtractQueueTmp[i].scoredRects[j].properties["imgKey"]; |
| | | INFO("SaveImageKey To ES: " << strImageKey); |
| | | t_json["imgKey"] = strImageKey; |
| | | |
| | | try { |
| | | auto server = m_rpcClient.getServer(); |
| | | if (!server) { |
| | | ERR("server is null"); |
| | | //return; |
| | | } |
| | | INFO("Record Video " << strImageKey); |
| | | server->recordVideo(strImageKey); |
| | | } catch (exception &e) { |
| | | ERR("Record Video Err: " << strImageKey << " Message: " << e.what()); |
| | | //return; |
| | | } |
| | | auto faceSearchServer = faceSearchRpcClient.getServer(); |
| | | if (!faceSearchServer) { |
| | | ERR("faceSearchServer is null"); |
| | | EsDBTool pManagerEsDB(appPref.getStringData("ipAdd"), appPref.getIntData("ipPort")); |
| | | bool retface = false; |
| | | retface = pManagerEsDB.insertData("videopersons", "perVideoPicture", t_json.toStyledString(), |
| | | str_uuid); |
| | | // if (retface) { |
| | | // INFO("facedb success"); |
| | | // } else { |
| | | // ERR("facedb fail"); |
| | | // } |
| | | } else { |
| | | INFO("send faceSearchTopN "); |
| | | auto faceSearchResults = faceSearchServer->faceSearchTopN(feature, t_json.toStyledString(), 2, |
| | | t_com_sc); |
| | | } |
| | | } |
| | | |
| | | std::vector<::FaceDetect::Data> FaceExtractElement::getFeatures() const { |
| | | return features; |
| | | } |
| | | |
| | | |