From c1cb59eba902bcfb72230562a05625687484126b Mon Sep 17 00:00:00 2001 From: "Mr.V" Date: Mon, 25 Nov 2024 19:01:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=8B=E7=9A=84=E5=9B=BE=E5=83=8F=E6=A0=87=E6=B3=A8?= =?UTF-8?q?=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DeleteExpiredFolderEngine.cpp | 2 +- .../ContainerDivideEngine.cpp | 2 +- .../SaveDebugImageEngine.cpp | 22 ++++++++++++++----- .../SaveMoveImageEngine.cpp | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/engine/DeleteExpiredFolderEngine/DeleteExpiredFolderEngine.cpp b/engine/DeleteExpiredFolderEngine/DeleteExpiredFolderEngine.cpp index 95a61d2..af160a8 100644 --- a/engine/DeleteExpiredFolderEngine/DeleteExpiredFolderEngine.cpp +++ b/engine/DeleteExpiredFolderEngine/DeleteExpiredFolderEngine.cpp @@ -1 +1 @@ -#include "DeleteExpiredFolderEngine.h" using namespace ai_matrix; DeleteExpiredFolderEngine::DeleteExpiredFolderEngine() {} DeleteExpiredFolderEngine::~DeleteExpiredFolderEngine() {} APP_ERROR DeleteExpiredFolderEngine::Init() { this->baseConfig_ = Config::getins()->getBaseConfig(); LogInfo << "DeleteExpiredFolderEngine Init ok"; return APP_ERR_OK; } APP_ERROR DeleteExpiredFolderEngine::DeInit() { LogInfo << "DeleteExpiredFolderEngine DeInit ok"; return APP_ERR_OK; } APP_ERROR DeleteExpiredFolderEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { std::string strTrainDate_temp = TimeUtil::getins()->getDate(); deletePreviousFolder(this->baseConfig_.strDebugResultPath, strTrainDate_temp, this->baseConfig_.iResultSaveDays); deletePreviousFolder(this->baseConfig_.strResultPath, strTrainDate_temp, this->baseConfig_.iResultSaveDays + 10); usleep(1000*1000*10); //每10秒执行一次 } return APP_ERR_OK; } void DeleteExpiredFolderEngine::deletePreviousFolder(std::string path, const std::string &date, int n_days) { // 1 computer date std::string previous_date = getDateBeforeNDays(date, n_days); if (!previous_date.empty()) LogDebug << "Date before " << n_days << " days from " << date << " is: " << previous_date; // 2 std::vector subfolders; getSubfolderNames(path, subfolders); // for (const auto &it : subfolders) // std::cout << it.year << "." << it.month << "." << it.day << std::endl; // 3 delete if (path.back() != '/') path += "/"; Date reference_date = strToDate(previous_date); // 给定的参考日期 deleteEarlierDatesFolder(path, subfolders, reference_date); } // 获取某月有多少天 int DeleteExpiredFolderEngine::daysInMonth(int year, int month) { int max_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { max_days[2] = 29; // 闰年2月有29天 } return max_days[month]; } // 解析字符串为日期结构体 Date DeleteExpiredFolderEngine::strToDate(const std::string &date_str) { std::istringstream iss(date_str); int year, month, day; char dash; if (!(iss >> year >> dash && dash == '-' && iss >> month >> dash && dash == '-' && iss >> day)) { LogError << ("Invalid date format") << ":" << date_str; } return {year, month, day}; } // 减去指定天数 void DeleteExpiredFolderEngine::subtractDays(Date &date, int n_days) { while (n_days > 0) { date.day--; n_days--; if (date.day == 0) { if (--date.month == 0) { --date.year; date.month = 12; } int max_days = daysInMonth(date.year, date.month); date.day = max_days; } } } // 格式化日期结构体为字符串 std::string DeleteExpiredFolderEngine::dateToStr(const Date &date) { std::ostringstream oss; oss << date.year << "-" << std::setfill('0') << std::setw(2) << date.month << "-" << std::setw(2) << date.day; return oss.str(); } // 主要功能函数,接收一个日期字符串和一个整数n,返回n天前的日期字符串 std::string DeleteExpiredFolderEngine::getDateBeforeNDays(const std::string &input_date, int n_days) { try { Date date = strToDate(input_date); subtractDays(date, n_days); return dateToStr(date); } catch (const std::exception &e) { LogError << "Error: " << e.what(); return ""; } } void DeleteExpiredFolderEngine::getSubfolderNames(std::string &directory, std::vector &folder_names) { if (directory.back() != '/') directory += "/"; DIR *dir; struct dirent *ent; if ((dir = opendir(directory.c_str())) != nullptr) { while ((ent = readdir(dir)) != nullptr) { // 排除"."和".." if (ent->d_type == DT_DIR && ent->d_name[0] != '.' && ent->d_name != "best") { folder_names.push_back(strToDate(ent->d_name)); } } closedir(dir); } else { LogError << "Unable to open directory: " << directory; } } void DeleteExpiredFolderEngine::deleteFolder(const std::string directory) { std::string command = "rm -rf " + directory; int result = system(command.c_str()); if (result != 0) std::cout << "Failed to remove directory recursively: " << directory << std::endl; else std::cout << "delete folder successfully : " << directory << std::endl; } // 删除向量中小于指定日期的所有元素 void DeleteExpiredFolderEngine::deleteEarlierDatesFolder(std::string &path, std::vector &subfolders, const Date &reference_date) { if (path.back() != '/') path += "/"; for (const Date &cur : subfolders) { // bool flag = false; if (cur.year < reference_date.year) { deleteFolder(path + dateToStr(cur)); } else if (cur.year == reference_date.year && cur.month < reference_date.month) { deleteFolder(path + dateToStr(cur)); } else if (cur.year == reference_date.year && cur.month == reference_date.month && cur.day < reference_date.day) { deleteFolder(path + dateToStr(cur)); } } } \ No newline at end of file +#include "DeleteExpiredFolderEngine.h" using namespace ai_matrix; DeleteExpiredFolderEngine::DeleteExpiredFolderEngine() {} DeleteExpiredFolderEngine::~DeleteExpiredFolderEngine() {} APP_ERROR DeleteExpiredFolderEngine::Init() { this->baseConfig_ = Config::getins()->getBaseConfig(); LogInfo << "DeleteExpiredFolderEngine Init ok"; return APP_ERR_OK; } APP_ERROR DeleteExpiredFolderEngine::DeInit() { LogInfo << "DeleteExpiredFolderEngine DeInit ok"; return APP_ERR_OK; } APP_ERROR DeleteExpiredFolderEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { std::string strTrainDate_temp = TimeUtil::getins()->getDate(); deletePreviousFolder(this->baseConfig_.strDebugResultPath, strTrainDate_temp, this->baseConfig_.iResultSaveDays); deletePreviousFolder(this->baseConfig_.strResultPath, strTrainDate_temp, this->baseConfig_.iResultSaveDays + 10); usleep(1000*1000*3600*24); //每天执行一次 } return APP_ERR_OK; } void DeleteExpiredFolderEngine::deletePreviousFolder(std::string path, const std::string &date, int n_days) { // 1 computer date std::string previous_date = getDateBeforeNDays(date, n_days); // if (!previous_date.empty()) // LogDebug << "Date before " << n_days << " days from " << date << " is: " << previous_date; // 2 std::vector subfolders; getSubfolderNames(path, subfolders); // for (const auto &it : subfolders) // std::cout << it.year << "." << it.month << "." << it.day << std::endl; // 3 delete if (path.back() != '/') path += "/"; Date reference_date = strToDate(previous_date); // 给定的参考日期 deleteEarlierDatesFolder(path, subfolders, reference_date); } // 获取某月有多少天 int DeleteExpiredFolderEngine::daysInMonth(int year, int month) { int max_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) { max_days[2] = 29; // 闰年2月有29天 } return max_days[month]; } // 解析字符串为日期结构体 Date DeleteExpiredFolderEngine::strToDate(const std::string &date_str) { std::istringstream iss(date_str); int year, month, day; char dash; if (!(iss >> year >> dash && dash == '-' && iss >> month >> dash && dash == '-' && iss >> day)) { LogError << ("Invalid date format") << ":" << date_str; } return {year, month, day}; } // 减去指定天数 void DeleteExpiredFolderEngine::subtractDays(Date &date, int n_days) { while (n_days > 0) { date.day--; n_days--; if (date.day == 0) { if (--date.month == 0) { --date.year; date.month = 12; } int max_days = daysInMonth(date.year, date.month); date.day = max_days; } } } // 格式化日期结构体为字符串 std::string DeleteExpiredFolderEngine::dateToStr(const Date &date) { std::ostringstream oss; oss << date.year << "-" << std::setfill('0') << std::setw(2) << date.month << "-" << std::setw(2) << date.day; return oss.str(); } // 主要功能函数,接收一个日期字符串和一个整数n,返回n天前的日期字符串 std::string DeleteExpiredFolderEngine::getDateBeforeNDays(const std::string &input_date, int n_days) { try { Date date = strToDate(input_date); subtractDays(date, n_days); return dateToStr(date); } catch (const std::exception &e) { LogError << "Error: " << e.what(); return ""; } } void DeleteExpiredFolderEngine::getSubfolderNames(std::string &directory, std::vector &folder_names) { if (directory.back() != '/') directory += "/"; DIR *dir; struct dirent *ent; if ((dir = opendir(directory.c_str())) != nullptr) { while ((ent = readdir(dir)) != nullptr) { // 排除"."和".." if (ent->d_type == DT_DIR && ent->d_name[0] != '.' && ent->d_name != "best") { folder_names.push_back(strToDate(ent->d_name)); } } closedir(dir); } else { LogError << "Unable to open directory: " << directory; } } void DeleteExpiredFolderEngine::deleteFolder(const std::string directory) { std::string command = "rm -rf " + directory; int result = system(command.c_str()); if (result != 0) LogWarn << "Failed to remove directory recursively: " << directory; else LogInfo << "delete folder successfully : " << directory; } // 删除向量中小于指定日期的所有元素 void DeleteExpiredFolderEngine::deleteEarlierDatesFolder(std::string &path, std::vector &subfolders, const Date &reference_date) { if (path.back() != '/') path += "/"; for (const Date &cur : subfolders) { // bool flag = false; if (cur.year < reference_date.year) { deleteFolder(path + dateToStr(cur)); } else if (cur.year == reference_date.year && cur.month < reference_date.month) { deleteFolder(path + dateToStr(cur)); } else if (cur.year == reference_date.year && cur.month == reference_date.month && cur.day < reference_date.day) { deleteFolder(path + dateToStr(cur)); } } } \ No newline at end of file diff --git a/engine/DetectDivideEngine/ContainerDivideEngine.cpp b/engine/DetectDivideEngine/ContainerDivideEngine.cpp index afa27f1..4194676 100644 --- a/engine/DetectDivideEngine/ContainerDivideEngine.cpp +++ b/engine/DetectDivideEngine/ContainerDivideEngine.cpp @@ -1 +1 @@ -#include "ContainerDivideEngine.h" #include using namespace ai_matrix; ContainerDivideEngine::ContainerDivideEngine() {} ContainerDivideEngine::~ContainerDivideEngine() {} APP_ERROR ContainerDivideEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; std::vector vecDataSourceConfig = Config::getins()->getAllDataSourceConfig(); if (vecDataSourceConfig.size() <= this->engineId_) { LogWarn << " -- " << engineName_ << "_" << engineId_ << " dataSource no set, Engine DeInit"; return APP_ERR_OK; } this->dataSourceConfig_ = vecDataSourceConfig.at(engineId_); this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->initParam(); LogInfo << "DetectDivideEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerDivideEngine::DeInit() { LogInfo << "DetectDivideEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::initParam() { this->iContainerIndex = 0; this->vecContainerFail_.clear(); } void ContainerDivideEngine::sendBestData(const VSelectBestData& selectBestData) { // 直接发送第一个箱子的箱号 std::shared_ptr pVSelectBestData = std::make_shared(); *pVSelectBestData = selectBestData; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); LogInfo << " 数据源:" << selectBestData.iDataSource << " 帧:" << selectBestData.iFrameId << " 节:" << selectBestData.iContainerIndex << " 发送识别结果 " << selectBestData.strNumResult; this->stdContainerResult_ = selectBestData.strNumResult; this->iContainerIndex++; } void ContainerDivideEngine::makeResult(const std::shared_ptr& pVStep2OutputData, VSelectBestData & selectBestData) const { selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = pVStep2OutputData->iFrameId; selectBestData.strNumResult = pVStep2OutputData->step2ResultData.transInfo.strTmpResult; selectBestData.bIsChkFlag = pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag; selectBestData.fSumScore = pVStep2OutputData->step2ResultData.fSubScoreSum; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = pVStep2OutputData->vecCornerResultData.size() > 2; } /** * 处理车厢间隔 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::divideInfo(std::shared_ptr pVStep2OutputData) { auto vCompare = [](std::string a, std::string b) { if (a.size() != b.size()) return 999; int count = 0; for (int i = 0; i < a.size(); ++i) { if (a[i] != b[i]) { ++count; } } return count; }; if (!this->pVStep2OutputDataPre_) return; Step2ResultData step2ResultData_pre = this->pVStep2OutputDataPre_->step2ResultData; Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; float fCenterX = (step2ResultData.fRBX + step2ResultData.fLTX)/2; float fCenterY = (step2ResultData.fRBY + step2ResultData.fLTY)/2; float fCenterX_Pre = (step2ResultData_pre.fRBX + step2ResultData_pre.fLTX)/2; float fCenterY_Pre = (step2ResultData_pre.fRBY + step2ResultData_pre.fLTY)/2; if (this->iContainerIndex > 1) return; LogDebug << "-- 数据源:" << pVStep2OutputData->iDataSource << " 帧:" << pVStep2OutputData->iFrameId << " 实际Y:" << std::abs(fCenterY - fCenterY_Pre) << " 实际X:" << std::abs(fCenterX - fCenterX_Pre); if ((pVStep2OutputData->iDataSource == 0 && std::abs(fCenterY - fCenterY_Pre) > this->identifyConfig_.iTop_Y_SplitSpanPx) || (pVStep2OutputData->iDataSource != 0 && std::abs(fCenterX - fCenterX_Pre) > this->identifyConfig_.iSide_X_SplitSpanPx)) { if (step2ResultData.transInfo.bIsChkFlag) { if (stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { if (stdContainerResult_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } sendBestData(this->vecContainerFail_[iIndex]); } // 记录第二箱子 this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } } else { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } if (this->vecContainerFail_.size() > 0 && this->iContainerIndex < 1) { sendBestData(this->vecContainerFail_[iIndex]); } // 把之前的清理掉再存新箱子的 (有风险,有可能切分错) this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } else {// 不满足像素差 if (!this->stdContainerResult_.empty()) { if (step2ResultData.transInfo.bIsChkFlag) { if (this->stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { // if (vCompare(this->stdContainerResult_, step2ResultData.transInfo.strTmpResult) > 2) // { this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); // } } } } else { if (step2ResultData.transInfo.bIsChkFlag) { this->stdContainerResult_ = step2ResultData.transInfo.strTmpResult; this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } } } APP_ERROR ContainerDivideEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pVStep2OutputData = std::static_pointer_cast(pVoidData0); if (pVStep2OutputData->bIsEnd) { std::shared_ptr pVSelectBestData = std::make_shared(); pVSelectBestData->bIsEnd = true; pVSelectBestData->iDataSource = pVStep2OutputData->iDataSource; pVSelectBestData->strDetectDate = pVStep2OutputData->strDetectDate; pVSelectBestData->strDetectTime = pVStep2OutputData->strDetectTime; if (this->iContainerIndex < 2 && this->vecContainerFail_.size() > 0) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } this->vecContainerFail_[iIndex].bIsEnd = true; sendBestData(this->vecContainerFail_[iIndex]); this->initParam(); continue; } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } std::string strFilePath ; strFilePath = this->baseConfig_.strDebugResultPath + "/" + pVStep2OutputData->strDetectDate + "/" + StringUtil::getins()->replace_all_distinct(pVStep2OutputData->strDetectTime, ":", "-") + "/" + std::to_string(pVStep2OutputData->iFrameId) + "_" + std::to_string(pVStep2OutputData->iDataSource) + ".json"; // 先读取文本内容,追加新的信息后再写入 Json::Value jvFrameInfo; if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strFilePath)) { LogError << "read fail:" << strFilePath; } // jvFrameInfo["isEnd"] = (pVStep2OutputData->bIsEnd || jvFrameInfo["isEnd"].asBool()); // 识别结果存储 float fCenter = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = pVStep2OutputData->step2ResultData.iClassId; jvInfo["score"] = pVStep2OutputData->step2ResultData.fScore; jvInfo["ltx"] = pVStep2OutputData->step2ResultData.fLTX; jvInfo["lty"] = pVStep2OutputData->step2ResultData.fLTY; jvInfo["rbx"] = pVStep2OutputData->step2ResultData.fRBX; jvInfo["rby"] = pVStep2OutputData->step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); for (auto &step2ResultData : pVStep2OutputData->vecCornerResultData) { float fCenter = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = step2ResultData.iClassId; jvInfo["score"] = step2ResultData.fScore; jvInfo["ltx"] = step2ResultData.fLTX; jvInfo["lty"] = step2ResultData.fLTY; jvInfo["rbx"] = step2ResultData.fRBX; jvInfo["rby"] = step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); } FileUtil::getins()->writeJsonInfo(jvFrameInfo, strFilePath); if (pVStep2OutputData->step2ResultData.fScore == 0.0f) continue; LogDebug << "数据源:" << pVStep2OutputData->iDataSource << " 帧:" << pVStep2OutputData->iFrameId << " - "<< pVStep2OutputData->step2ResultData.transInfo.strTmpResult; this->divideInfo(pVStep2OutputData); this->pVStep2OutputDataPre_ = pVStep2OutputData; } return APP_ERR_OK; } \ No newline at end of file +#include "ContainerDivideEngine.h" #include using namespace ai_matrix; ContainerDivideEngine::ContainerDivideEngine() {} ContainerDivideEngine::~ContainerDivideEngine() {} APP_ERROR ContainerDivideEngine::Init() { strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0"; strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1"; std::vector vecDataSourceConfig = Config::getins()->getAllDataSourceConfig(); if (vecDataSourceConfig.size() <= this->engineId_) { LogWarn << " -- " << engineName_ << "_" << engineId_ << " dataSource no set, Engine DeInit"; return APP_ERR_OK; } this->dataSourceConfig_ = vecDataSourceConfig.at(engineId_); this->baseConfig_ = Config::getins()->getBaseConfig(); this->identifyConfig_ = Config::getins()->getIdentifyConfig(); this->initParam(); LogInfo << "DetectDivideEngine Init ok"; return APP_ERR_OK; } APP_ERROR ContainerDivideEngine::DeInit() { LogInfo << "DetectDivideEngine DeInit ok"; return APP_ERR_OK; } /** * 初始化参数信息 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::initParam() { this->iContainerIndex = 0; this->vecContainerFail_.clear(); } void ContainerDivideEngine::sendBestData(const VSelectBestData& selectBestData) { // 直接发送第一个箱子的箱号 std::shared_ptr pVSelectBestData = std::make_shared(); *pVSelectBestData = selectBestData; outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); LogInfo << " 数据源:" << selectBestData.iDataSource << " 帧:" << selectBestData.iFrameId << " 节:" << selectBestData.iContainerIndex << " 发送识别结果 " << selectBestData.strNumResult; this->stdContainerResult_ = selectBestData.strNumResult; this->iContainerIndex++; } void ContainerDivideEngine::makeResult(const std::shared_ptr& pVStep2OutputData, VSelectBestData & selectBestData) const { selectBestData.strDetectDate = pVStep2OutputData->strDetectDate; selectBestData.strDetectTime = pVStep2OutputData->strDetectTime; selectBestData.iDataSource = pVStep2OutputData->iDataSource; selectBestData.iFrameId = pVStep2OutputData->iFrameId; selectBestData.strNumResult = pVStep2OutputData->step2ResultData.transInfo.strTmpResult; selectBestData.bIsChkFlag = pVStep2OutputData->step2ResultData.transInfo.bIsChkFlag; selectBestData.fSumScore = pVStep2OutputData->step2ResultData.fSubScoreSum; selectBestData.iContainerIndex = this->iContainerIndex; selectBestData.bHaveTwoContainer = pVStep2OutputData->vecCornerResultData.size() > 2; } /** * 处理车厢间隔 * inParam : N/A * outParam: N/A * return : N/A */ void ContainerDivideEngine::divideInfo(std::shared_ptr pVStep2OutputData) { auto vCompare = [](std::string a, std::string b) { if (a.size() != b.size()) return 999; int count = 0; for (int i = 0; i < a.size(); ++i) { if (a[i] != b[i]) { ++count; } } return count; }; if (!this->pVStep2OutputDataPre_) return; Step2ResultData step2ResultData_pre = this->pVStep2OutputDataPre_->step2ResultData; Step2ResultData step2ResultData = pVStep2OutputData->step2ResultData; float fCenterX = (step2ResultData.fRBX + step2ResultData.fLTX)/2; float fCenterY = (step2ResultData.fRBY + step2ResultData.fLTY)/2; float fCenterX_Pre = (step2ResultData_pre.fRBX + step2ResultData_pre.fLTX)/2; float fCenterY_Pre = (step2ResultData_pre.fRBY + step2ResultData_pre.fLTY)/2; if (this->iContainerIndex > 1) return; LogDebug << "-- 数据源:" << pVStep2OutputData->iDataSource << " 帧:" << pVStep2OutputData->iFrameId << " Y差值:" << std::abs(fCenterY - fCenterY_Pre) << " X差值:" << std::abs(fCenterX - fCenterX_Pre); if ((pVStep2OutputData->iDataSource == 0 && std::abs(fCenterY - fCenterY_Pre) > this->identifyConfig_.iTop_Y_SplitSpanPx) || (pVStep2OutputData->iDataSource != 0 && std::abs(fCenterX - fCenterX_Pre) > this->identifyConfig_.iSide_X_SplitSpanPx)) { if (step2ResultData.transInfo.bIsChkFlag) { if (stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { if (stdContainerResult_.empty()) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } sendBestData(this->vecContainerFail_[iIndex]); } // 记录第二箱子 this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } } else { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } if (this->vecContainerFail_.size() > 0 && this->iContainerIndex < 1) { sendBestData(this->vecContainerFail_[iIndex]); } // 把之前的清理掉再存新箱子的 (有风险,有可能切分错) this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } else {// 不满足像素差 if (!this->stdContainerResult_.empty()) { if (step2ResultData.transInfo.bIsChkFlag) { if (this->stdContainerResult_ != step2ResultData.transInfo.strTmpResult) { // if (vCompare(this->stdContainerResult_, step2ResultData.transInfo.strTmpResult) > 2) // { this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); // } } } } else { if (step2ResultData.transInfo.bIsChkFlag) { this->stdContainerResult_ = step2ResultData.transInfo.strTmpResult; this->vecContainerFail_.clear(); VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->sendBestData(selectBestData); } else { VSelectBestData selectBestData; this->makeResult(pVStep2OutputData, selectBestData); this->vecContainerFail_.emplace_back(selectBestData); } } } } APP_ERROR ContainerDivideEngine::Process() { int iRet = APP_ERR_OK; while (!isStop_) { //pop端口0 std::shared_ptr pVoidData0 = nullptr; iRet = inputQueMap_[strPort0_]->pop(pVoidData0); if (nullptr == pVoidData0) { usleep(1000); continue; } std::shared_ptr pVStep2OutputData = std::static_pointer_cast(pVoidData0); if (pVStep2OutputData->bIsEnd) { std::shared_ptr pVSelectBestData = std::make_shared(); pVSelectBestData->bIsEnd = true; pVSelectBestData->iDataSource = pVStep2OutputData->iDataSource; pVSelectBestData->strDetectDate = pVStep2OutputData->strDetectDate; pVSelectBestData->strDetectTime = pVStep2OutputData->strDetectTime; if (this->iContainerIndex < 2 && this->vecContainerFail_.size() > 0) { // 筛选不满足校验的部分 取最长的发送 int iSize = 0, iIndex = 0; std::string strContainer_tmp; for (int i = 0; i < this->vecContainerFail_.size(); i++) { this->vecContainerFail_[i]; if (iSize < this->vecContainerFail_[i].strNumResult.size()) { iSize = this->vecContainerFail_[i].strNumResult.size(); iIndex = i; strContainer_tmp = this->vecContainerFail_[i].strNumResult; } } this->vecContainerFail_[iIndex].bIsEnd = true; sendBestData(this->vecContainerFail_[iIndex]); this->initParam(); continue; } outputQueMap_[strPort0_]->push(std::static_pointer_cast(pVSelectBestData), true); this->initParam(); continue; } std::string strFilePath ; strFilePath = this->baseConfig_.strDebugResultPath + "/" + pVStep2OutputData->strDetectDate + "/" + StringUtil::getins()->replace_all_distinct(pVStep2OutputData->strDetectTime, ":", "-") + "/" + std::to_string(pVStep2OutputData->iFrameId) + "_" + std::to_string(pVStep2OutputData->iDataSource) + ".json"; // 先读取文本内容,追加新的信息后再写入 Json::Value jvFrameInfo; if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strFilePath)) { LogError << "read fail:" << strFilePath; } // jvFrameInfo["isEnd"] = (pVStep2OutputData->bIsEnd || jvFrameInfo["isEnd"].asBool()); // 识别结果存储 float fCenter = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = pVStep2OutputData->step2ResultData.iClassId; jvInfo["score"] = pVStep2OutputData->step2ResultData.fScore; jvInfo["ltx"] = pVStep2OutputData->step2ResultData.fLTX; jvInfo["lty"] = pVStep2OutputData->step2ResultData.fLTY; jvInfo["rbx"] = pVStep2OutputData->step2ResultData.fRBX; jvInfo["rby"] = pVStep2OutputData->step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); for (auto &step2ResultData : pVStep2OutputData->vecCornerResultData) { float fCenter = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX) / 2; // this->mapContainerCenterInfo_.insert(std::make_pair(pVStep2OutputData->iFrameId, fCenter)); Json::Value jvInfo; jvInfo["classid"] = step2ResultData.iClassId; jvInfo["score"] = step2ResultData.fScore; jvInfo["ltx"] = step2ResultData.fLTX; jvInfo["lty"] = step2ResultData.fLTY; jvInfo["rbx"] = step2ResultData.fRBX; jvInfo["rby"] = step2ResultData.fRBY; jvFrameInfo["step1"].append(jvInfo); } FileUtil::getins()->writeJsonInfo(jvFrameInfo, strFilePath); if (pVStep2OutputData->step2ResultData.fScore == 0.0f) continue; LogDebug << "数据源:" << pVStep2OutputData->iDataSource << " 帧:" << pVStep2OutputData->iFrameId << " - "<< pVStep2OutputData->step2ResultData.transInfo.strTmpResult; this->divideInfo(pVStep2OutputData); this->pVStep2OutputDataPre_ = pVStep2OutputData; } return APP_ERR_OK; } \ No newline at end of file diff --git a/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp b/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp index 70c8ac8..46494ca 100644 --- a/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp +++ b/engine/SaveDebugImageEngine/SaveDebugImageEngine.cpp @@ -65,7 +65,6 @@ APP_ERROR SaveDebugImageEngine::Process() + "_" + std::to_string(pVStep2OutputData->iDataSource) + ".jpg"; - LogInfo << "strJsonPath:" << strJsonPath << " strImagePath:" << strImagePath; Json::Value jvFrameInfo; if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strJsonPath)) { @@ -74,6 +73,12 @@ APP_ERROR SaveDebugImageEngine::Process() cv::Mat image = cv::imread(strImagePath); + if (image.empty()) + { + LogWarn << "图像未找到:" << strImagePath; + continue; + } + std::stringstream ss; std::vector vecTitle; vecTitle.emplace_back("FrameID:" + to_string(pVStep2OutputData->iFrameId)); @@ -81,12 +86,12 @@ APP_ERROR SaveDebugImageEngine::Process() int base_line = 0; cv::Point text_org(15, 45); // 文本起始点 - for (int i = 0; i < vecTitle.size(); ++i) + for (const auto & i : vecTitle) { - cv::Size text_size = cv::getTextSize(vecTitle.at(i), cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); + cv::Size text_size = cv::getTextSize(i, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); cv::Point baseline_loc(text_org); baseline_loc.y += base_line + text_size.height; - cv::putText(image, vecTitle.at(i), baseline_loc, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 255), 2); + cv::putText(image, i, baseline_loc, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 255), 2); // 手动调整x位置,为下一个单词留出空间 text_org.x += text_size.width + 10; text_org.x = text_org.x > IMAGE_WIDTH ? 15 : text_org.x; @@ -106,13 +111,14 @@ APP_ERROR SaveDebugImageEngine::Process() cv::Point(centerX, pVStep2OutputData->step2ResultData.fLTY-30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fRBY+30), cvScalar, 1); - cv::Point linePoint(pVStep2OutputData->step2ResultData.fLTX + 10, pVStep2OutputData->step2ResultData.fRBY + 10); + cv::Size text_size = cv::getTextSize(pVStep2OutputData->step2ResultData.transInfo.strTmpResult, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0); + cv::Point linePoint(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fRBY + text_size.height + 5); cv::putText(image, pVStep2OutputData->step2ResultData.transInfo.strTmpResult, linePoint, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 180), 2); - for (auto &step2ResultData : pVStep2OutputData->vecCornerResultData) + for (const auto &step2ResultData : pVStep2OutputData->vecCornerResultData) { cvScalar = {0, 255, 255, 255}; float centerX_corner = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX)/2; @@ -129,6 +135,10 @@ APP_ERROR SaveDebugImageEngine::Process() { LogError << "图片存储失败:" << strImagePath; } +// else +// { +// LogInfo << "图片存储成功:" << strImagePath; +// } } return APP_ERR_OK; } \ No newline at end of file diff --git a/engine/SaveMoveImageEngine/SaveMoveImageEngine.cpp b/engine/SaveMoveImageEngine/SaveMoveImageEngine.cpp index 09659d2..34f91d8 100644 --- a/engine/SaveMoveImageEngine/SaveMoveImageEngine.cpp +++ b/engine/SaveMoveImageEngine/SaveMoveImageEngine.cpp @@ -66,6 +66,7 @@ APP_ERROR SaveMoveImageEngine::Process() // pToStep1Data->strImageName = pSaveImgData->strFileName; // // outputQueMap_[strPort0_]->push(std::static_pointer_cast(pToStep1Data), true); +// LogInfo << "存储:" << strImgFilePath; } else {