#include "myutils.h" namespace ai_matrix { const int TIME_DIFF = 28800; // 8 hour MyUtils *MyUtils::ins = nullptr; MyUtils::GarbageCollector MyUtils::gc; std::mutex MyUtils::mx; MyUtils *MyUtils::getins() { //双层锁,确保线程安全 if (ins == nullptr) { std::lock_guard guard(mx); //防止异常发生不能解锁 if (ins == nullptr) { ins = new MyUtils(); } } return ins; } float MyUtils::getMean(const std::vector &data) { int size = data.size(); if (size == 0) { return 0; } float sum = 0; for (int i = 0; i < size; i++) { sum += data[i]; } return sum / size; } float MyUtils::getMax(const std::vector &data) { int size = data.size(); if (size == 0) { return 0; } float max = 0; for (int i = 0; i < size; i++) { if (i == 0) { max = data[i]; } else if (data[i] > max) { max = data[i]; } } return max; } float MyUtils::getMin(const std::vector &data) { int size = data.size(); if (size == 0) { return 0; } float min = 0; for (int i = 0; i < size; i++) { if (i == 0) { min = data[i]; } else if (data[i] < min) { min = data[i]; } } return min; } float MyUtils::getMedian(const std::vector &data) { if (data.size() < 2) { return 0; } std::vector data_tmp; int n = data.size(); for (int i = 0; i < n; i++) { data_tmp.push_back(data[i]); } std::sort(data_tmp.begin(), data_tmp.end(), std::less()); if (n % 2 == 0) { return (data_tmp[n / 2] + data_tmp[n / 2 - 1]) / 2; } else { return data_tmp[(n - 1) / 2]; } } std::string MyUtils::get_timestamp_file() { time_t timep = time(NULL); struct tm *p = localtime(&timep); struct timeval tv; gettimeofday(&tv, NULL); int msec = tv.tv_usec / 1000; char tmp[30] = {0}; sprintf(tmp, "%04d-%02d-%02d-%02d-%02d-%02d-%03d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, msec); return std::string(tmp); } std::string MyUtils::get_date() { time_t timep = time(NULL); struct tm *p = localtime(&timep); struct timeval tv; gettimeofday(&tv, NULL); int msec = tv.tv_usec / 1000; char tmp[12] = { 0 }; sprintf(tmp, "%04d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); return std::string(tmp); } std::string MyUtils::get_time() { time_t timep = time(NULL); struct tm *p = localtime(&timep); struct timeval tv; gettimeofday(&tv, NULL); int msec = tv.tv_usec / 1000; char tmp[10] = { 0 }; sprintf(tmp, "%02d-%02d-%02d", p->tm_hour, p->tm_min, p->tm_sec); return std::string(tmp); } std::string MyUtils::get_timestamp_log() { time_t timep = time(NULL); struct tm *p = localtime(&timep); struct timeval tv; gettimeofday(&tv, NULL); int msec = tv.tv_usec / 1000; char tmp[30] = {0}; sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d.%03d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, msec); return std::string(tmp); } std::string MyUtils::create_dir_name(std::string root, std::string name) { std::string dir_path = root + "/" + name; if (access(dir_path.c_str(), F_OK) != 0) { if (mkdir(dir_path.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return ""; } } return dir_path; } std::string MyUtils::create_dir_date(std::string root) { time_t timep = time(NULL); struct tm *p = localtime(&timep); char tmp_date[20] = {0}; sprintf(tmp_date, "%04d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); std::string dir_path; dir_path = root + "/" + std::string(tmp_date); //创建日期目录 if (access(dir_path.c_str(), F_OK) != 0) { if (mkdir(dir_path.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return ""; } } return dir_path; } std::string MyUtils::create_dir_date_name_time(std::string root, std::string name) { time_t timep = time(NULL); struct tm *p = localtime(&timep); char tmp_date[20] = {0}; sprintf(tmp_date, "%04d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); char tmp_time[20] = {0}; sprintf(tmp_time, "%02d-%02d-%02d", p->tm_hour, p->tm_min, p->tm_sec); std::string dir_path; dir_path = root + "/" + std::string(tmp_date); //创建日期目录 if (access(dir_path.c_str(), F_OK) != 0) { if (mkdir(dir_path.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return ""; } } dir_path = dir_path + "/" + name + "_" + std::string(tmp_time); //创建点云目录 if (access(dir_path.c_str(), F_OK) != 0) { if (mkdir(dir_path.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return ""; } } return dir_path; } std::string MyUtils::create_file_path(std::string root, std::string name, std::string suffix) { time_t timep = time(NULL); struct tm *p = localtime(&timep); char tmp_date[20] = {0}; sprintf(tmp_date, "%04d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); char tmp_time[20] = {0}; sprintf(tmp_time, "%02d-%02d-%02d", p->tm_hour, p->tm_min, p->tm_sec); std::string file_path; file_path = root + "/" + std::string(tmp_date); //创建日期目录 if (access(file_path.c_str(), F_OK) != 0) { if (mkdir(file_path.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return ""; } } file_path = file_path + "/" + name + "_" + std::string(tmp_time) + suffix; //创建文件 return file_path; } //字符串分割函数 std::vector MyUtils::split(std::string str, std::string pattern) { std::string::size_type pos; std::vector result; str += pattern; //扩展字符串以方便操作 int size = str.size(); for (int i = 0; i < size; i++) { pos = str.find(pattern, i); if (pos < size) { std::string s = str.substr(i, pos - i); result.push_back(s); i = pos + pattern.size() - 1; } } return result; } std::string MyUtils::getStringFromFloat(float f) { std::ostringstream buffer; buffer << f; return buffer.str(); } std::string MyUtils::getStringFromBool(bool b) { std::ostringstream buffer; buffer << b; return buffer.str(); } /** * 拷贝文件 * @param filePath 源文件位置 * @param savePath 将要拷贝的新位置 * @return */ bool MyUtils::copyFile(std::string filePath, std::string savePath) { FILE *fp, *sp; fp = fopen(filePath.c_str(), "rb"); sp = fopen(savePath.c_str(), "w+b"); if (!fp || !sp) { LogError << "open fial filePath:" << filePath << " or savePath:" << savePath; return false; } void *buffer; while (!feof(fp)) { fread(&buffer, 1, 1, fp); fwrite(&buffer, 1, 1, sp); } fclose(fp); fclose(sp); return true; } std::string& MyUtils::replace_all_distinct(std::string &str, const std::string &old_value, const std::string &new_value) { for (std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()) { if ((pos = str.find(old_value, pos)) != std::string::npos) str.replace(pos, old_value.length(), new_value); else break; } return str; } /** * 获取北京当前日期 * inParam : N/A * outParam: N/A * return : 日期 */ std::string MyUtils::GetDate() { struct timeval time = {0, 0}; gettimeofday(&time, nullptr); time_t timep = time.tv_sec + TIME_DIFF; struct tm *p = gmtime(&timep); char szTmp[12] = {0}; sprintf(szTmp, "%04d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); return std::string(szTmp); } /** * 获取北京当前时间 * inParam : N/A * outParam: N/A * return : 时间 */ std::string MyUtils::GetTime() { struct timeval time = {0, 0}; gettimeofday(&time, nullptr); time_t timep = time.tv_sec + TIME_DIFF; struct tm *p = gmtime(&timep); char szTmp[10] = {0}; sprintf(szTmp, "%02d-%02d-%02d", p->tm_hour, p->tm_min, p->tm_sec); return std::string(szTmp); } //时间戳转化为时间 毫秒级 std::string MyUtils::Stamp2Time(long long timestamp, bool has_msec) { int ms = timestamp % 1000;//取毫秒 time_t tick = (time_t)(timestamp/1000);//转换时间 struct tm tm; char s[40]; tm = *localtime(&tick); strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", &tm); std::string str(s); if (has_msec) { str = str+ "." + std::to_string(ms); } return str; } /** * 获取当前时间距1970年的毫秒数 * inParam : N/A * outParam: N/A * return : 时间戳 */ uint64_t MyUtils::GetCurrentTimeMillis() { struct timeval tv; gettimeofday(&tv, NULL); //printf("tv_sec:%ld, tv_usec:%ld\n", tv.tv_sec, tv.tv_usec); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } /** * 获取指定时间距1970年的毫秒数 (入参格式:YYYY-MM-DD hh-mm-ss) * inParam : std::string &strDateTime 日期时间 * outParam: N/A * return : 时间戳 */ uint64_t MyUtils::GetParamTimeMilliSeconds(std::string &strDateTime) { LogDebug << "strDateTime:" << strDateTime; if (strDateTime.length() != 19) { return 0; } int iYear = atoi(strDateTime.substr(0, 4).c_str()); int iMon = atoi(strDateTime.substr(5, 2).c_str()); int iDay = atoi(strDateTime.substr(8, 2).c_str()); int iHour = atoi(strDateTime.substr(11, 2).c_str()); int iMin = atoi(strDateTime.substr(14, 2).c_str()); int iSec = atoi(strDateTime.substr(17, 2).c_str()); struct tm stm; memset(&stm, 0, sizeof(stm)); stm.tm_year = iYear - 1900; stm.tm_mon = iMon - 1; stm.tm_mday = iDay; stm.tm_hour = iHour; stm.tm_min = iMin; stm.tm_sec = iSec; uint64_t i64Ret = (uint64_t)mktime(&stm) * 1000; LogDebug << iYear << " " << iMon << " " << iDay << " " << iHour << " " << iMin << " " << iSec << " " << i64Ret; return i64Ret; } /** * Anchor行分割 * inParam : std::string &strLine Anchor一行内容 * : const std::set &setDelimiters 分割符集合 * outParam: N/A * return : 分割数据 */ std::vector MyUtils::SplitAnchor(std::string &strLine, const std::set &setDelimiters) { std::vector result; if (strLine.empty()) { return result; } char const *pch = strLine.c_str(); char const *start = pch; for (; *pch; ++pch) { if (setDelimiters.find(*pch) != setDelimiters.end()) { if (start != pch) { std::string tmp(start, pch); result.push_back(atof(tmp.c_str())); //浮点数 } start = pch + 1; } } result.push_back(atof(start)); //最后一个内容 return result; } /** * 创建文件夹路径 * inParam : std::string strDirPath :文件夹路径 * outParam: N/A * return : true/false */ bool MyUtils::CreateDirPath(std::string strDirPath) { if (strDirPath.back() != '/') { strDirPath += "/"; } if (access(strDirPath.c_str(), F_OK) == 0) { return true; } std::string::size_type pos = strDirPath.find('/'); while (pos != std::string::npos) { std::string strCur = strDirPath.substr(0, pos); if (!strCur.empty() && access(strCur.c_str(), F_OK) != 0) { if (mkdir(strCur.c_str(), 0755) != 0) //如果父目录不存在,会创建失败 { perror("mkdir fail"); return false; } if (chmod(strCur.c_str(), 0777) != 0) { perror("chmod fail"); } } pos = strDirPath.find('/', pos + 1); } return true; } #ifdef ASCEND /** * 拷贝Device数据到Host * inParam : void *pDeviceBuffer device内存地址 : uint32_t iBufferSize device内存大小 * outParam: std::shared_ptr *pHostData host内存地址 (size同入参) * return : N/A */ bool MyUtils::MemcpyDeviceToHost(std::shared_ptr *pHostData, const void *pDeviceBuffer, uint32_t iBufferSize) { if (pDeviceBuffer == nullptr || iBufferSize == 0) { LogError << "MemcpyDeviceToHost fail pDeviceBuffer is null or iBufferSize is 0"; return false; } void *pHostBuffer = nullptr; int iRet = aclrtMallocHost(&pHostBuffer, iBufferSize); if (iRet != APP_ERR_OK) { LogError << "MemcpyDeviceToHost aclrtMallocHost fail, iBufferSize:" << iBufferSize << " iRet:" << iRet; return false; } pHostData->reset(pHostBuffer, aclrtFreeHost); iRet = aclrtMemcpy(pHostData->get(), iBufferSize, pDeviceBuffer, iBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); if (iRet != APP_ERR_OK) { LogError << "MemcpyDeviceToHost aclrtMemcpy fail, iBufferSize:" << iBufferSize << " iRet:" << iRet; return false; } return true; } /** * 拷贝Host数据到Device * inParam : void *pHostBuffer host内存地址 : uint32_t iBufferSize host内存大小 : bool bDvppFlag 是否使用dvpp方式申请device内存(默认true) * outParam: std::shared_ptr *pDeviceData device内存地址 (size同入参) * return : N/A */ bool MyUtils::MemcpyHostToDevice(std::shared_ptr *pDeviceData, const void *pHostBuffer, uint32_t iBufferSize, bool bDvppFlag/*=true*/) { if (pHostBuffer == nullptr || iBufferSize == 0) { LogError << "MemcpyHostToDevice fail pHostBuffer is null or iBufferSize is 0"; return false; } int iRet = APP_ERR_OK; void *pDeviceBuffer = nullptr; if (bDvppFlag) { int iRet = acldvppMalloc(&pDeviceBuffer, iBufferSize); if (iRet != APP_ERR_OK) { LogError << "MemcpyHostToDevice acldvppMalloc fail, iBufferSize:" << iBufferSize << " iRet:" << iRet; return false; } pDeviceData->reset(pDeviceBuffer, acldvppFree); } else { int iRet = aclrtMalloc(&pDeviceBuffer, iBufferSize, ACL_MEM_MALLOC_HUGE_FIRST); if (iRet != APP_ERR_OK) { LogError << "MemcpyHostToDevice aclrtMalloc fail, iBufferSize:" << iBufferSize << " iRet:" << iRet; return false; } pDeviceData->reset(pDeviceBuffer, aclrtFree); } iRet = aclrtMemcpy(pDeviceData->get(), iBufferSize, pHostBuffer, iBufferSize, ACL_MEMCPY_HOST_TO_DEVICE); if (iRet != APP_ERR_OK) { LogError << "MemcpyHostToDevice aclrtMemcpy fail, iBufferSize:" << iBufferSize << " iRet:" << iRet; return false; } return true; } #endif /** * 获取指定毫秒数的对应的北京日期时间 * inParam : uint64_t i64MilliSeconds * outParam: N/A * return : 日期时间 */ std::string MyUtils::GetDateTimeByMilliSeconds(uint64_t i64MilliSeconds, bool bFormatFlag/*=false*/) { time_t timep = i64MilliSeconds / 1000 + TIME_DIFF; struct tm *p = gmtime(&timep); char szTmp[32] = {0}; if (bFormatFlag) { sprintf(szTmp, "%04d-%02d-%02d %02d:%02d:%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); } else { sprintf(szTmp, "%04d-%02d-%02d %02d-%02d-%02d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); } return std::string(szTmp); } /** * 校验是否识别该目标 * inParam : std::string &strOneTarget * outParam: N/A * return : true/false */ bool MyUtils::ChkIsHaveTarget(const std::string &strOneTarget) { std::map mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig(); bool bFindTarget = false; for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++) { if (iter->second.strTarget.find(strOneTarget) != std::string::npos) { bFindTarget = true; break; } } return bFindTarget; } /** * 读取json格式文件内容 * inParam : std::string &strFilePath :文件路径 * outParam: Json::Value &jvFileInfo :json格式内容 * return : true/false */ bool MyUtils::ReadJsonInfo(Json::Value &jvFileInfo, std::string &strFilePath, int iRetry /*=3*/) { std::ifstream ifs(strFilePath.c_str()); int i = 0; while (!ifs.is_open() && i < iRetry) { i++; usleep(10 * 1000); ifs.open(strFilePath.c_str()); } if (!ifs.is_open()) { // LogWarn << "txt:" << strFilePath << " open fail"; return false; } std::string strContent; getline(ifs, strContent); ifs.close(); Json::CharReaderBuilder jsrBuilder; std::shared_ptr reader(jsrBuilder.newCharReader()); JSONCPP_STRING errs; if (!reader->parse(strContent.data(), strContent.data() + strContent.size(), &jvFileInfo, &errs)) { LogWarn << "json parse fail content:" << strContent; return false; } return true; } /** * json格式内容写入文件 * inParam : Json::Value &jvFileInfo :json格式内容 : std::string &strFilePath :文件路径 * outParam: N/A * return : true/false */ bool MyUtils::WriteJsonInfo(Json::Value &jvFileInfo, std::string &strFilePath) { Json::StreamWriterBuilder jswBuilder; jswBuilder["indentation"] = ""; std::string strFrameInfo = Json::writeString(jswBuilder, jvFileInfo); std::ofstream ofs(strFilePath.c_str()); if (!ofs.is_open()) { LogWarn << "txt:" << strFilePath << " open fail"; return false; } ofs.write(strFrameInfo.c_str(), strFrameInfo.length()); ofs.close(); return true; } /** * 获取第1步得分最高框 * inParam : std::vector &vecResult 推理符合结果 * outParam: std::vector &vecResult 每个类别得分最高结果 * return : N/A */ void MyUtils::GetMaxScoreResult(std::vector &vecResult) { if (vecResult.size() < 2) { return; } std::map> mapResult; for (size_t i = 0; i < vecResult.size(); i++) { stDetection stDTemp = vecResult.at(i); if (stDTemp.class_id == 0) { mapResult[HEAD].emplace_back(stDTemp); } else if (stDTemp.class_id == 1) { mapResult[PRO].emplace_back(stDTemp); } else if ((stDTemp.class_id >= 2 && stDTemp.class_id <= 6) || stDTemp.class_id == 8 || stDTemp.class_id == 15) { mapResult[NUM].emplace_back(stDTemp); } else if (stDTemp.class_id >= 9 && stDTemp.class_id <= 17 && stDTemp.class_id != 15) { mapResult[TRAINSPACE].emplace_back(stDTemp); } else if (stDTemp.class_id == 18) { mapResult[SPACE].emplace_back(stDTemp); } } //清空之前的结果 vecResult.clear(); // 每个类别中,获取得分最高的框 for (auto iter = mapResult.begin(); iter != mapResult.end(); iter++) { int iMaxPos = -1; for (size_t i = 0; i < iter->second.size(); i++) { if (iMaxPos == -1) { iMaxPos = i; } else if (iter->second.at(i).class_conf > iter->second.at(iMaxPos).class_conf) { iMaxPos = i; } } if (iMaxPos >= 0) { vecResult.emplace_back(iter->second.at(iMaxPos)); } } } /** * 获取第二步缩放比例 * inParam : Step1Location &step1Location 第一步大框 : int iModelWidth 模型宽 : int iModelHeight 模型高 * outParam: N/A * return : 缩放比例 */ float MyUtils::GetStep2ResizeRatio(Step1Location &step1Location, int iModelWidth, int iModelHeight) { uint32_t iCropgWidth = step1Location.fRBX - step1Location.fLTX; uint32_t iCropHeight = step1Location.fRBY - step1Location.fLTY; float fRatioW = static_cast(iCropgWidth) / iModelWidth; float fRatioH = static_cast(iCropHeight) / iModelHeight; return (fRatioW > fRatioH) ? fRatioW : fRatioH; } /** * 第二步坐标还原 * inParam : SingleData &singleData : float fResizeRatio 比例 : std::shared_ptr pProcessData 待处理数据 : Step1Location &step1Location 第一步大框在原图坐标 * outParam: SingleData &singleData * return : N/A */ void MyUtils::Step2ResetLocation(SingleData &singleData, float fResizeRatio, std::shared_ptr pProcessData, Step1Location &step1Location) { uint32_t iOrigWidth = pProcessData->iWidth; uint32_t iOrigHeight = pProcessData->iHeight; singleData.fLTX = singleData.fLTX * fResizeRatio + step1Location.fLTX; singleData.fLTY = singleData.fLTY * fResizeRatio + step1Location.fLTY; singleData.fRBX = singleData.fRBX * fResizeRatio + step1Location.fLTX; singleData.fRBY = singleData.fRBY * fResizeRatio + step1Location.fLTY; singleData.fLTX = (singleData.fLTX < iOrigWidth) ? singleData.fLTX : iOrigWidth; singleData.fLTY = (singleData.fLTY < iOrigHeight) ? singleData.fLTY : iOrigHeight; singleData.fRBX = (singleData.fRBX < iOrigWidth) ? singleData.fRBX : iOrigWidth; singleData.fRBY = (singleData.fRBY < iOrigHeight) ? singleData.fRBY : iOrigHeight; } }