VCarContainer/engine/SelectBestEngine/SelectBestEngine.cpp

242 lines
7.8 KiB
C++

#include "SelectBestEngine.h"
using namespace ai_matrix;
SelectBestEngine::SelectBestEngine() {}
SelectBestEngine::~SelectBestEngine() {}
APP_ERROR SelectBestEngine::Init()
{
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2";
this->baseConfig_ = Config::getins()->getBaseConfig();
this->minioConfig_ = Config::getins()->getMinioConfig();
this->vecDataSourceConfig_ = Config::getins()->getAllDataSourceConfig();
this->initParam();
LogInfo << "SelectBestEngine Init ok";
return APP_ERR_OK;
}
APP_ERROR SelectBestEngine::DeInit()
{
LogInfo << "SelectBestEngine DeInit ok";
return APP_ERR_OK;
}
/**
* 初始化参数信息
* inParam : N/A
* outParam: N/A
* return : N/A
*/
void SelectBestEngine::initParam()
{
this->strImagePath_ = "";
this->strDetectDate_ = "";
this->strDetectTime_ = "";
this->mapIndex_Containers_.clear();
this->iEndCount_ = 0;
}
void SelectBestEngine::sendWSServer(DetectResultData &detectResultData)
{
std::string strImage;
std::string data;
Json::Value jsonData;
for (int i = 0; i < detectResultData.vecImage.size(); ++i)
{
jsonData["bestImgSid" + std::to_string(i)] = detectResultData.vecImage[i];
strImage += detectResultData.vecImage[i];
if (i < detectResultData.vecImage.size() - 1)
{
strImage += ",";
}
}
std::string strContainerNo;
for (int i = 0; i < detectResultData.vecContainerNO.size(); ++i)
{
strContainerNo += detectResultData.vecContainerNO[i];
if (i < detectResultData.vecContainerNO.size() - 1)
{
strContainerNo += ",";
}
}
jsonData["containerNo"] = strContainerNo;
jsonData["images"] = strImage;
jsonData["status"] = "normal";
jsonData["id"] = "";
Json::StreamWriterBuilder jswBuilder;
std::string strSendData = Json::writeString(jswBuilder, jsonData);
outputQueMap_[strPort0_]->push(std::static_pointer_cast<std::string>(std::make_shared<std::string>(strSendData)));
}
void SelectBestEngine::sendMinioServer(DetectResultData &detectResultData)
{
std::shared_ptr<DetectResultData> pDetectResultData = std::make_shared<DetectResultData>();
*pDetectResultData = detectResultData;
outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pDetectResultData));
}
void SelectBestEngine::sendSaveCSV(DetectResultData &detectResultData)
{
std::shared_ptr<DetectResultData> pDetectResultData = std::make_shared<DetectResultData>();
*pDetectResultData = detectResultData;
outputQueMap_[strPort2_]->push(std::static_pointer_cast<void>(pDetectResultData));
}
/**
* 获取最优识别结果
*/
void SelectBestEngine::selectBest()
{
auto contains = [] (const std::vector<std::string>& vec, std::string value) -> bool {
return std::find(vec.begin(), vec.end(), value) != vec.end();
};
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;
};
DetectResultData detectResultData;
detectResultData.strDetectDate = this->strDetectDate_;
detectResultData.strDetectTime = this->strDetectTime_;
std::string strAlternativeResult;
bool bHaveTwoContainer = false;
for (auto & it_container : this->mapIndex_Containers_) {
bool bHaveVerify = false;
std::map<std::string, int> mapContainer_count;
for (auto &container: it_container.second) {
if (container.bIsChkFlag) {
bHaveVerify = true;
mapContainer_count[container.strNumResult]++;
}
if (container.bHaveTwoContainer) bHaveTwoContainer = true;
std::string strUploadName =
std::to_string(container.iFrameId) + "_" + std::to_string(container.iDataSource) + ".jpg";
detectResultData.vecImage.emplace_back(strUploadName);
}
if (bHaveVerify) {
std::string strBestContainer;
int count = 0;
// 取出现次数最高的 且与第一个箱子不一样的
for (auto &it_max: mapContainer_count) {
if (it_max.first.empty()) continue;
if (it_max.second >= count) {
count = it_max.second;
if (!contains(detectResultData.vecContainerNO, it_max.first)) {
strBestContainer = it_max.first;
break;
}
}
}
if (mapContainer_count.size() > 1)
{
for (auto &it_max : mapContainer_count)
{
if (it_max.first != strBestContainer && vCompare(it_max.first, strBestContainer) > 2)
{
strAlternativeResult = it_max.first;
}
}
}
detectResultData.vecContainerNO.emplace_back(strBestContainer);
} else {
if (detectResultData.vecContainerNO.size() == 1 && !strAlternativeResult.empty())
{
detectResultData.vecContainerNO.emplace_back(strAlternativeResult);
}
else
{
// 取识别字数最长的
std::string strBestContainer;
int iMaxSize = 0;
for (auto &it_max: mapContainer_count) {
if (it_max.first.size() > iMaxSize) {
iMaxSize = it_max.first.size();
strBestContainer = it_max.first;
}
}
detectResultData.vecContainerNO.emplace_back(strBestContainer);
}
}
}
if (bHaveTwoContainer && detectResultData.vecContainerNO.size() < 2)
{
detectResultData.vecContainerNO.emplace_back("?");
}
// 向其他引擎发送信息
this->sendWSServer(detectResultData);
this->sendMinioServer(detectResultData);
this->sendSaveCSV(detectResultData);
}
APP_ERROR SelectBestEngine::Process()
{
int iRet = APP_ERR_OK;
while (!isStop_)
{
//pop端口0
std::shared_ptr<void> pVoidData0 = nullptr;
iRet = inputQueMap_[strPort0_]->pop(pVoidData0);
if (nullptr == pVoidData0)
{
usleep(1000);
continue;
}
std::shared_ptr<VSelectBestData> pVSelectBestData = std::static_pointer_cast<VSelectBestData>(pVoidData0);
if (pVSelectBestData->bIsEnd)
{
if (this->strDetectDate_.empty())
{
this->strDetectDate_ = pVSelectBestData->strDetectDate;
this->strDetectTime_ = pVSelectBestData->strDetectTime;
}
this->iEndCount_++;
if (!(this->iEndCount_ % this->vecDataSourceConfig_.size()))
{
this->selectBest();
this->initParam();
}
continue;
}
this->iEndCount_ = 0;
if (this->strImagePath_.empty())
{
this->strDetectDate_ = pVSelectBestData->strDetectDate;
this->strDetectTime_ = pVSelectBestData->strDetectTime;
this->strImagePath_ = pVSelectBestData->strDetectDate + "/"
+ StringUtil::getins()->replace_all_distinct(pVSelectBestData->strDetectTime, ":", "-")
+ "/" + std::to_string(pVSelectBestData->iDataSource) + "/";
}
VSelectBestData selectBestData = *pVSelectBestData;
this->mapIndex_Containers_[selectBestData.iContainerIndex].emplace_back(selectBestData);
}
return APP_ERR_OK;
}