generated from zhangwei/Train_Identify
新增解码异常时解码器自动重置
This commit is contained in:
parent
3dabfe2bf6
commit
6778b5a0e9
|
|
@ -1,7 +1,6 @@
|
|||
/build/
|
||||
/app/
|
||||
*.tgz
|
||||
*.tar
|
||||
*.log
|
||||
*.o
|
||||
*.out
|
||||
build/
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
.idea/
|
||||
.vscode/
|
||||
app/train
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
# cmake_policy(SET CMP0074 NEW)
|
||||
# cmake_policy(SET CMP0146 NEW)
|
||||
|
||||
message("NVIDIA NX PLATFORM")
|
||||
set(PROJECT_NAME train)
|
||||
|
|
@ -85,6 +85,7 @@ include_directories(
|
|||
${PROJECT_SOURCE_DIR}/ai_matrix/myqueue
|
||||
${PROJECT_SOURCE_DIR}/ai_matrix/myshell
|
||||
${PROJECT_SOURCE_DIR}/ai_matrix/myutils
|
||||
${PROJECT_SOURCE_DIR}/ai_matrix/Http
|
||||
|
||||
#nvidia ascend common cann include
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_base/Base/BlockingQueue
|
||||
|
|
@ -106,11 +107,12 @@ include_directories(
|
|||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/MergerEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SaveEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SelectBestEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TrainAnaEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TransEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TrainAnaEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataDealEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SocketEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DeleteExpiredFolderEngine
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/ApiEngine
|
||||
|
||||
#common tools rtsp_server include
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_tools/common_tools/rtsp_server/3rdpart/md5
|
||||
|
|
@ -179,17 +181,18 @@ file(GLOB_RECURSE COMMON_SRCS_LISTS
|
|||
#common engine src
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataSourceEngine/*.cpp
|
||||
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/ControlEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataUploadEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/FilterEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/MergerEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SaveEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SelectBestEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TrainAnaEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TransEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TrainAnaEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataDealEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SocketEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DeleteExpiredFolderEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/ApiEngine/*.cpp
|
||||
|
||||
#common tools rtsp_server src
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_tools/common_tools/rtsp_server/net/*.cpp
|
||||
|
|
@ -198,18 +201,6 @@ file(GLOB_RECURSE COMMON_SRCS_LISTS
|
|||
|
||||
file(GLOB_RECURSE SRCS_LISTS
|
||||
#nvidia engine src
|
||||
#nvidia engine include
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/ControlEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataSourceEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataUploadEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/FilterEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/MergerEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SaveEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/SelectBestEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TrainAnaEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/TransEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/common_engine/DataDealEngine/*.cpp
|
||||
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/nvidia_engine/ChkDateStepOneEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/nvidia_engine/ChkDateStepTwoEngine/*.cpp
|
||||
${PROJECT_SOURCE_DIR}/nvidia_ascend_engine/nvidia_engine/MyYaml/*.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
FROM dustynv/jetson-inference:r32.6.1
|
||||
|
||||
#拷贝业务程序
|
||||
COPY --chown=1000:1000 app /app
|
||||
#WORKDIR /app/bin
|
||||
WORKDIR /app
|
||||
|
||||
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/lib
|
||||
|
||||
#CMD echo "$APP_NAME version $APP_VERSION"
|
||||
|
||||
ENTRYPOINT ["./train"]
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
#include "Config.h"
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
Config *Config::pInstance_ = nullptr;
|
||||
Config::GarbageCollector Config::gc_;
|
||||
std::mutex Config::mx_;
|
||||
|
||||
Config *Config::GetIns()
|
||||
{
|
||||
//双层锁,确保线程安全
|
||||
if (pInstance_ == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mx_); //防止异常发生不能解锁
|
||||
if (pInstance_ == nullptr)
|
||||
{
|
||||
pInstance_ = new Config();
|
||||
}
|
||||
}
|
||||
return pInstance_;
|
||||
}
|
||||
|
||||
int Config::readYaml(std::string &strPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
strConfigYamlPath_ = strPath;
|
||||
config_ = YAML::LoadFile(strPath);
|
||||
|
||||
//退出程序
|
||||
if (config_.IsNull())
|
||||
{
|
||||
printf("config.yaml no find");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 控制参数
|
||||
this->baseConfig_.strTrackName = config_["base"]["track_name"].as<std::string>();
|
||||
this->baseConfig_.bTestModel = config_["base"]["test_model"].as<bool>();
|
||||
this->baseConfig_.iApiPort = config_["base"]["api_port"].as<int>();
|
||||
this->baseConfig_.bUpResult = config_["base"]["up_result"].as<bool>();
|
||||
this->baseConfig_.strLogPath = config_["base"]["log_path"].as<std::string>();
|
||||
this->baseConfig_.strResultPath = config_["base"]["result_path"].as<std::string>();
|
||||
this->baseConfig_.iResultSaveDays = config_["base"]["result_save_days"].as<int>();
|
||||
|
||||
// 日志参数
|
||||
this->logConfig_.strOutLevel = config_["log"]["out_level"].as<std::string>();
|
||||
this->logConfig_.strSaveLevel = config_["log"]["save_level"].as<std::string>();
|
||||
|
||||
// 数据源参数
|
||||
this->dataSourceConfig_.strUrl = config_["data_source"]["url"].as<std::string>();
|
||||
this->dataSourceConfig_.iSkipInterval = config_["data_source"]["skip_interval"].as<int>();
|
||||
this->dataSourceConfig_.iDirection = config_["data_source"]["direction"].as<int>();
|
||||
this->dataSourceConfig_.iLeftFirst = config_["data_source"]["left_first"].as<int>();
|
||||
this->dataSourceConfig_.iRightFirst = config_["data_source"]["right_first"].as<int>();
|
||||
|
||||
// 识别参数
|
||||
this->identifyConfig_.strRunModel = config_["identify"]["run_mode"].as<std::string>();
|
||||
this->identifyConfig_.bNeedMoveDetectFlag = config_["identify"]["need_move_detect_flag"].as<bool>();
|
||||
this->identifyConfig_.strIdentifyDirection = config_["identify"]["identify_direction"].as<std::string>();
|
||||
this->identifyConfig_.iPartitionFrameSpan = config_["identify"]["partition_frame_span"].as<int>();
|
||||
this->identifyConfig_.iSplitFrameSpanPx = config_["identify"]["split_frame_span_px"].as<int>();
|
||||
this->identifyConfig_.iChkstopPx = config_["identify"]["chkstop_px"].as<int>();
|
||||
this->identifyConfig_.iChkstopCount = config_["identify"]["chkstop_count"].as<int>();
|
||||
this->identifyConfig_.iNumFrameHeight = config_["identify"]["num_frame_height"].as<int>();
|
||||
this->identifyConfig_.iProFrameHeight = config_["identify"]["pro_frame_height"].as<int>();
|
||||
this->identifyConfig_.iSpaceFrameWidth = config_["identify"]["space_frame_width"].as<int>();
|
||||
this->identifyConfig_.bTrainHeardDetect = config_["identify"]["train_heard_detect"].as<bool>();
|
||||
|
||||
// websocket server 服务端参数
|
||||
this->wSocketConfig_.bIsUse = config_["wsocket_server"]["is_use"].as<bool>();
|
||||
this->wSocketConfig_.iPort = config_["wsocket_server"]["port"].as<int>();
|
||||
this->wSocketConfig_.iMaxQueueLen = config_["wsocket_server"]["max_queue_len"].as<int>();
|
||||
|
||||
// http服务器参数
|
||||
this->httpServerConfig_.bIsUse = config_["http_server"]["is_use"].as<bool>();
|
||||
this->httpServerConfig_.strIp = config_["http_server"]["http_ip"].as<std::string>();
|
||||
this->httpServerConfig_.iPort = config_["http_server"]["http_port"].as<int>();
|
||||
this->httpServerConfig_.strTokenUrl = config_["http_server"]["token_path"].as<std::string>();
|
||||
this->httpServerConfig_.strUpResultUrl = config_["http_server"]["up_result_path"].as<std::string>();
|
||||
this->httpServerConfig_.strUserName = config_["http_server"]["username"].as<std::string>();
|
||||
this->httpServerConfig_.strPassword = config_["http_server"]["password"].as<std::string>();
|
||||
|
||||
}
|
||||
catch (...) //捕获所有异常
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Config::writeYaml()
|
||||
{
|
||||
try
|
||||
{
|
||||
std::ofstream of(strConfigYamlPath_);
|
||||
of << config_;
|
||||
of.close();
|
||||
}
|
||||
catch (...) //捕获所有异常
|
||||
{
|
||||
printf("yaml文件不存在\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string Config::getStringValue(const char *pszKey, const YAML::Node *pConfig/*=nullptr*/) const
|
||||
{
|
||||
if(nullptr == pConfig)
|
||||
{
|
||||
pConfig = &config_;
|
||||
}
|
||||
if (!(*pConfig)[pszKey].IsDefined())
|
||||
{
|
||||
printf("key:[%s] not exist!\n", pszKey);
|
||||
}
|
||||
return (*pConfig)[pszKey].as<std::string>();
|
||||
}
|
||||
|
||||
int Config::getIntValue(const char *pszKey, const YAML::Node *pConfig/*=nullptr*/) const
|
||||
{
|
||||
if (nullptr == pConfig)
|
||||
{
|
||||
pConfig = &config_;
|
||||
}
|
||||
if (!(*pConfig)[pszKey].IsDefined())
|
||||
{
|
||||
printf("key:[%s] not exist!\n", pszKey);
|
||||
}
|
||||
return (*pConfig)[pszKey].as<int>();
|
||||
}
|
||||
|
||||
bool Config::getBoolValue(const char *pszKey, const YAML::Node *pConfig/*=nullptr*/) const
|
||||
{
|
||||
if (nullptr == pConfig)
|
||||
{
|
||||
pConfig = &config_;
|
||||
}
|
||||
if (!(*pConfig)[pszKey].IsDefined())
|
||||
{
|
||||
printf("key:[%s] not exist!\n", pszKey);
|
||||
}
|
||||
return (*pConfig)[pszKey].as<bool>();
|
||||
}
|
||||
|
||||
float Config::getFloatValue(const char *pszKey, const YAML::Node *pConfig/*=nullptr*/) const
|
||||
{
|
||||
if (nullptr == pConfig)
|
||||
{
|
||||
pConfig = &config_;
|
||||
}
|
||||
if (!(*pConfig)[pszKey].IsDefined())
|
||||
{
|
||||
printf("key:[%s] not exist!\n", pszKey);
|
||||
}
|
||||
return (*pConfig)[pszKey].as<float>();
|
||||
}
|
||||
|
||||
std::string Config::getPathValue(const char *pszKey, const YAML::Node *pConfig /*=nullptr*/) const
|
||||
{
|
||||
if (nullptr == pConfig)
|
||||
{
|
||||
pConfig = &config_;
|
||||
}
|
||||
if (!(*pConfig)[pszKey].IsDefined())
|
||||
{
|
||||
printf("key:[%s] not exist!\n", pszKey);
|
||||
}
|
||||
std::string strTmp = (*pConfig)[pszKey].as<std::string>();
|
||||
if (strTmp.back() != '/')
|
||||
{
|
||||
strTmp += "/";
|
||||
}
|
||||
return strTmp;
|
||||
}
|
||||
|
||||
RunConfig Config::getRunConfig() const
|
||||
{
|
||||
return this->runConfig_;
|
||||
}
|
||||
|
||||
void Config::setRunConfig(const ai_matrix::RunConfig runConfig)
|
||||
{
|
||||
this->runConfig_ = runConfig;
|
||||
}
|
||||
|
||||
BaseConfig Config::getBaseConfig() const
|
||||
{
|
||||
return this->baseConfig_;
|
||||
}
|
||||
|
||||
void Config::setBaseConfig(const BaseConfig baseConfig)
|
||||
{
|
||||
this->baseConfig_ = baseConfig;
|
||||
}
|
||||
|
||||
LogConfig Config::getLogConfig() const
|
||||
{
|
||||
return this->logConfig_;
|
||||
}
|
||||
|
||||
void Config::setLogConfig(const LogConfig logConfig)
|
||||
{
|
||||
this->logConfig_ = logConfig;
|
||||
}
|
||||
|
||||
DataSourceConfig Config::getDataSourceConfig() const
|
||||
{
|
||||
return this->dataSourceConfig_;
|
||||
}
|
||||
|
||||
void Config::setDataSourceConfig(const ai_matrix::DataSourceConfig dataSourceConfig)
|
||||
{
|
||||
this->dataSourceConfig_ = dataSourceConfig;
|
||||
}
|
||||
|
||||
IdentifyConfig Config::getIdentifyConfig() const
|
||||
{
|
||||
return this->identifyConfig_;
|
||||
}
|
||||
|
||||
void Config::setIdentifyConfig(const ai_matrix::IdentifyConfig identifyConfig)
|
||||
{
|
||||
this->identifyConfig_ = identifyConfig;
|
||||
}
|
||||
|
||||
WSocketConfig Config::getWSocketConfig() const
|
||||
{
|
||||
return this->wSocketConfig_;
|
||||
}
|
||||
|
||||
void Config::setWSocketConfig(const ai_matrix::WSocketConfig wSocketConfig)
|
||||
{
|
||||
this->wSocketConfig_ = wSocketConfig;
|
||||
}
|
||||
|
||||
HttpServerConfig Config::getHttpServerConfig() const
|
||||
{
|
||||
return this->httpServerConfig_;
|
||||
}
|
||||
|
||||
void Config::setHttpServerConfig(const HttpServerConfig httpServerConfig) {
|
||||
this->httpServerConfig_ = httpServerConfig;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
#ifndef MYYAML_H_
|
||||
#define MYYAML_H_
|
||||
|
||||
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include "yaml-cpp/yaml.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
|
||||
struct RunConfig
|
||||
{
|
||||
// 识别状态
|
||||
bool bRun;
|
||||
|
||||
};
|
||||
|
||||
// 基础控制参数
|
||||
struct BaseConfig
|
||||
{
|
||||
// 股道名称
|
||||
std::string strTrackName;
|
||||
// 测试模式
|
||||
bool bTestModel;
|
||||
// Api 监听端口
|
||||
int iApiPort;
|
||||
// 是否上传识别结果
|
||||
bool bUpResult;
|
||||
// 日志文件目录
|
||||
std::string strLogPath;
|
||||
// 识别结果目录
|
||||
std::string strResultPath;
|
||||
// 调试结果目录
|
||||
std::string strDebugResultPath;
|
||||
// 日志存储天数
|
||||
int iResultSaveDays;
|
||||
// 过期文件夹天数
|
||||
int iDayForResultExpire;
|
||||
};
|
||||
|
||||
// 日志参数
|
||||
struct LogConfig {
|
||||
// 输出日志级别[DEBUG, INFO, WARN, ERROR, FATAL]
|
||||
std::string strOutLevel;
|
||||
// 保存日志级别[DEBUG, INFO, WARN, ERROR, FATAL]
|
||||
std::string strSaveLevel;
|
||||
};
|
||||
|
||||
// 数据源参数
|
||||
struct DataSourceConfig {
|
||||
// 数据源地址
|
||||
std::string strUrl;
|
||||
// 跳帧数
|
||||
int iSkipInterval;
|
||||
// 行驶方向 0-自动识别 1-向左 2-向右 (与“首位信息”成对存在,形成例如向左就编号在前,向右就属性在前的对应)
|
||||
int iDirection;
|
||||
// 0-向左编号在前 1-向左属性在前 (向右行驶的情况:2-向右编号在前 3-向右属性在前)
|
||||
int iLeftFirst;
|
||||
// (向左行驶的情况:0-向左编号在前 1-向左属性在前) 2-向右编号在前 3-向右属性在前
|
||||
int iRightFirst;
|
||||
};
|
||||
|
||||
// 识别参数
|
||||
struct IdentifyConfig {
|
||||
// 运行方式
|
||||
std::string strRunModel;
|
||||
// 是否开启动态检测
|
||||
bool bNeedMoveDetectFlag;
|
||||
// 识别方向 [LEFT,RIGHT,ALL]
|
||||
std::string strIdentifyDirection;
|
||||
// 大框帧跨度(比一个大框从出现到消失的跨度稍大一点, 跟跳帧有关系)
|
||||
int iPartitionFrameSpan;
|
||||
// 大框帧跨度的位置像素差异
|
||||
int iSplitFrameSpanPx;
|
||||
// 每帧大框位置差异最小值 (持续小于此值,则可能停车)
|
||||
int iChkstopPx;
|
||||
// 持续X次续位置差异小于gc_chkstop_px,则判断为停车。
|
||||
int iChkstopCount;
|
||||
// 过滤最小大框高度(不需要的话就写个很小的值)
|
||||
int iNumFrameHeight;
|
||||
int iProFrameHeight;
|
||||
// 过滤最大框宽度(不需要的话就写个很大的值)
|
||||
int iSpaceFrameWidth;
|
||||
// 是否识别车头
|
||||
bool bTrainHeardDetect;
|
||||
};
|
||||
|
||||
// websocket_server 的服务端参数
|
||||
struct WSocketConfig {
|
||||
// 是否启用
|
||||
bool bIsUse;
|
||||
// 端口
|
||||
int iPort;
|
||||
// 最大链接队列
|
||||
int iMaxQueueLen;
|
||||
};
|
||||
|
||||
// web服务器参数
|
||||
struct HttpServerConfig
|
||||
{
|
||||
// 使用状态
|
||||
bool bIsUse;
|
||||
// 获取接口授权地址
|
||||
std::string strIp;
|
||||
// 通讯端口
|
||||
int iPort;
|
||||
// 获取接口授权地址
|
||||
std::string strTokenUrl;
|
||||
// 识别结果上传地址
|
||||
std::string strUpResultUrl;
|
||||
// 接口用户名
|
||||
std::string strUserName;
|
||||
// 接口密码
|
||||
std::string strPassword;
|
||||
};
|
||||
|
||||
class Config final
|
||||
{
|
||||
public:
|
||||
static Config *GetIns();
|
||||
|
||||
// 读yaml文件
|
||||
int readYaml(std::string &strPath);
|
||||
// 写yaml文件
|
||||
int writeYaml();
|
||||
std::string getStringValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
|
||||
int getIntValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
|
||||
bool getBoolValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
|
||||
float getFloatValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
|
||||
std::string getPathValue(const char *pszKey, const YAML::Node *pConfig =nullptr) const;
|
||||
|
||||
|
||||
RunConfig getRunConfig() const;
|
||||
void setRunConfig(const RunConfig runConfig);
|
||||
|
||||
// 获取控制参数
|
||||
BaseConfig getBaseConfig() const;
|
||||
void setBaseConfig(const BaseConfig baseConfig);
|
||||
// 获取日志参数
|
||||
LogConfig getLogConfig() const;
|
||||
void setLogConfig(const LogConfig logConfig);
|
||||
// 获取数据源参数
|
||||
DataSourceConfig getDataSourceConfig() const;
|
||||
void setDataSourceConfig(const DataSourceConfig dataSourceConfig);
|
||||
// 获取识别参数
|
||||
IdentifyConfig getIdentifyConfig() const;
|
||||
void setIdentifyConfig(const IdentifyConfig identifyConfig);
|
||||
// 获取websocket server 参数
|
||||
WSocketConfig getWSocketConfig() const;
|
||||
void setWSocketConfig(const WSocketConfig wSocketConfig);
|
||||
// 获取web服务器参数
|
||||
HttpServerConfig getHttpServerConfig() const;
|
||||
void setHttpServerConfig(const HttpServerConfig httpServerConfig);
|
||||
|
||||
YAML::Node config_;
|
||||
|
||||
private:
|
||||
Config() = default;
|
||||
Config(const Config &) = delete;
|
||||
Config(Config &&) = delete;
|
||||
Config &operator=(const Config &) = delete;
|
||||
Config &operator=(Config &&) = delete;
|
||||
~Config() = default;
|
||||
|
||||
static Config *pInstance_;
|
||||
static std::mutex mx_; //锁,保证线程安全
|
||||
std::string strConfigYamlPath_;
|
||||
|
||||
// (全局)运行实时变量
|
||||
RunConfig runConfig_;
|
||||
|
||||
// 控制参数
|
||||
BaseConfig baseConfig_;
|
||||
|
||||
// 日志参数
|
||||
LogConfig logConfig_;
|
||||
|
||||
// 数据源参数
|
||||
DataSourceConfig dataSourceConfig_;
|
||||
|
||||
// 识别参数
|
||||
IdentifyConfig identifyConfig_;
|
||||
|
||||
// websocket server 服务端参数
|
||||
WSocketConfig wSocketConfig_;
|
||||
|
||||
// web服务器参数
|
||||
HttpServerConfig httpServerConfig_;
|
||||
|
||||
//定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露
|
||||
class GarbageCollector
|
||||
{
|
||||
public:
|
||||
~GarbageCollector()
|
||||
{
|
||||
if (Config::pInstance_)
|
||||
{
|
||||
delete Config::pInstance_;
|
||||
Config::pInstance_ = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
static GarbageCollector gc_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,190 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#include "FileUtil.h"
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
FileUtil *FileUtil::ins = nullptr;
|
||||
FileUtil::GarbageCollector FileUtil::gc;
|
||||
std::mutex FileUtil::mx;
|
||||
|
||||
FileUtil *FileUtil::getins()
|
||||
{
|
||||
//双层锁,确保线程安全
|
||||
if (ins == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mx); //防止异常发生不能解锁
|
||||
if (ins == nullptr)
|
||||
{
|
||||
ins = new FileUtil();
|
||||
}
|
||||
}
|
||||
return ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件夹路径
|
||||
* inParam : std::string strDirPath :文件夹路径
|
||||
* outParam: N/A
|
||||
* return : true/false
|
||||
*/
|
||||
bool FileUtil::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;
|
||||
}
|
||||
|
||||
std::string FileUtil::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 FileUtil::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 FileUtil::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 FileUtil::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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
* @param filePath 源文件位置
|
||||
* @param savePath 将要拷贝的新位置
|
||||
* @return
|
||||
*/
|
||||
bool FileUtil::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) {
|
||||
return false;
|
||||
}
|
||||
void *buffer;
|
||||
while (!feof(fp)) {
|
||||
fread(&buffer, 1, 1, fp);
|
||||
fwrite(&buffer, 1, 1, sp);
|
||||
}
|
||||
fclose(fp);
|
||||
fclose(sp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#ifndef TRAIN_RFID_LINUX_FILEUTIL_H
|
||||
#define TRAIN_RFID_LINUX_FILEUTIL_H
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
class FileUtil final
|
||||
{
|
||||
public:
|
||||
static FileUtil *getins();
|
||||
|
||||
//创建文件夹
|
||||
std::string create_dir_name(std::string root, std::string name);
|
||||
std::string create_dir_date_name_time(std::string root, std::string name);
|
||||
std::string create_dir_date(std::string root);
|
||||
//创建文件路径
|
||||
std::string create_file_path(std::string root, std::string name, std::string suffix);
|
||||
//创建文件夹路径
|
||||
bool CreateDirPath(std::string strDirPath);
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
* @param filePath 源文件位置
|
||||
* @param savePath 将要拷贝的新位置
|
||||
* @return
|
||||
*/
|
||||
bool copyFile(std::string filePath, std::string savePath);
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
FileUtil() = default;
|
||||
FileUtil(const FileUtil &) = delete;
|
||||
FileUtil(FileUtil &&) = delete;
|
||||
FileUtil &operator=(const FileUtil &) = delete;
|
||||
FileUtil &operator=(FileUtil &&) = delete;
|
||||
~FileUtil() = default;
|
||||
|
||||
//定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露
|
||||
class GarbageCollector
|
||||
{
|
||||
public:
|
||||
~GarbageCollector()
|
||||
{
|
||||
if (FileUtil::ins)
|
||||
{
|
||||
delete FileUtil::ins;
|
||||
FileUtil::ins = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static GarbageCollector gc;
|
||||
static FileUtil *ins;
|
||||
static std::mutex mx; //锁,保证线程安全
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //TRAIN_RFID_LINUX_FILEUTIL_H
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
StringUtil *StringUtil::ins = nullptr;
|
||||
StringUtil::GarbageCollector StringUtil::gc;
|
||||
std::mutex StringUtil::mx;
|
||||
|
||||
StringUtil *StringUtil::getins()
|
||||
{
|
||||
//双层锁,确保线程安全
|
||||
if (ins == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mx); //防止异常发生不能解锁
|
||||
if (ins == nullptr)
|
||||
{
|
||||
ins = new StringUtil();
|
||||
}
|
||||
}
|
||||
return ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串分割函数
|
||||
* @param str 目标字符串
|
||||
* @param pattern 切割字符
|
||||
* @return vector<std::string>
|
||||
*/
|
||||
std::vector<std::string> StringUtil::split(std::string str, std::string pattern)
|
||||
{
|
||||
std::string::size_type pos;
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉字符串前后空格
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
std::string StringUtil::trim(const std::string& str) {
|
||||
std::string temp = str;
|
||||
temp.erase(0, temp.find_first_not_of(" \t\n\r\f\v")); // 去除开头的空格
|
||||
temp.erase(temp.find_last_not_of(" \t\n\r\f\v") + 1); // 去除末尾的空格
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换字符串中所有指定字符
|
||||
* @param str 目标字符串
|
||||
* @param old_value 原值
|
||||
* @param new_value 新值
|
||||
* @return 新结果
|
||||
*/
|
||||
std::string& StringUtil::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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anchor行分割
|
||||
* inParam : std::string &strLine Anchor一行内容
|
||||
* : const std::set<char> &setDelimiters 分割符集合
|
||||
* outParam: N/A
|
||||
* return : 分割数据
|
||||
*/
|
||||
std::vector<float> StringUtil::SplitAnchor(std::string &strLine, const std::set<char> &setDelimiters)
|
||||
{
|
||||
std::vector<float> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* float 转 string
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
std::string StringUtil::getStringFromFloat(float f)
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
buffer << f;
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* bool 转 string
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
std::string StringUtil::getStringFromBool(bool b)
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
buffer << b;
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* string 转 int
|
||||
* (会过滤字符串前后的空格)
|
||||
* @param s
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
int StringUtil::string2int(const std::string s, bool &b) {
|
||||
try {
|
||||
b = true;
|
||||
return std::stoi(this->trim(s));
|
||||
} catch (...) {
|
||||
b = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串中是否存在 字母和数字 之外的字符
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
bool StringUtil::containsNonAlphaNum(const std::string &str) {
|
||||
for (char c : str) {
|
||||
if (!std::isalnum(c) && !std::isspace(c)) { // 如果不是字母或数字
|
||||
return true; // 返回true,表示存在非字母数字字符
|
||||
}
|
||||
}
|
||||
return false; // 遍历完成未发现非字母数字字符,返回false
|
||||
}
|
||||
|
||||
bool StringUtil::is_digits(const std::string &str) {
|
||||
return all_of(str.begin(), str.end(), ::isdigit);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#ifndef TRAIN_RFID_LINUX_STRINGUTIL_H
|
||||
#define TRAIN_RFID_LINUX_STRINGUTIL_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
class StringUtil final
|
||||
{
|
||||
public:
|
||||
static StringUtil *getins();
|
||||
|
||||
// 字符串分割函数
|
||||
std::vector<std::string> split(std::string str, std::string pattern);
|
||||
// 去掉字符串前后的空格
|
||||
std::string trim(const std::string& str);
|
||||
|
||||
// 替换string中所有指定字符串
|
||||
std::string& replace_all_distinct(std::string &str, const std::string &old_value, const std::string &new_value);
|
||||
//
|
||||
std::vector<float> SplitAnchor(std::string &strLine, const std::set<char> &setDelimiters);
|
||||
|
||||
// float 转 string
|
||||
std::string getStringFromFloat(float f);
|
||||
// bool 转 string
|
||||
std::string getStringFromBool(bool b);
|
||||
// string 转 int
|
||||
int string2int(const std::string s, bool &b);
|
||||
|
||||
// 判断字符串中是否含有 字母和数字 之外的字符
|
||||
bool containsNonAlphaNum(const std::string &str);
|
||||
// 判断字符串中是否仅含有数字
|
||||
// 检查函数
|
||||
bool is_digits(const std::string& str);
|
||||
|
||||
private:
|
||||
StringUtil() = default;
|
||||
StringUtil(const StringUtil &) = delete;
|
||||
StringUtil(StringUtil &&) = delete;
|
||||
StringUtil &operator=(const StringUtil &) = delete;
|
||||
StringUtil &operator=(StringUtil &&) = delete;
|
||||
~StringUtil() = default;
|
||||
|
||||
//定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露
|
||||
class GarbageCollector
|
||||
{
|
||||
public:
|
||||
~GarbageCollector()
|
||||
{
|
||||
if (StringUtil::ins)
|
||||
{
|
||||
delete StringUtil::ins;
|
||||
StringUtil::ins = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static GarbageCollector gc;
|
||||
static StringUtil *ins;
|
||||
static std::mutex mx; //锁,保证线程安全
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //TRAIN_RFID_LINUX_STRINGUTIL_H
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
#include <cstring>
|
||||
#include "TimeUtil.h"
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
const int TIME_DIFF = 28800; // 8 hour
|
||||
TimeUtil *TimeUtil::ins = nullptr;
|
||||
TimeUtil::GarbageCollector TimeUtil::gc;
|
||||
std::mutex TimeUtil::mx;
|
||||
|
||||
TimeUtil *TimeUtil::getins()
|
||||
{
|
||||
//双层锁,确保线程安全
|
||||
if (ins == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mx); //防止异常发生不能解锁
|
||||
if (ins == nullptr)
|
||||
{
|
||||
ins = new TimeUtil();
|
||||
}
|
||||
}
|
||||
return ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用于文件命名的时间戳
|
||||
* @return
|
||||
*/
|
||||
std::string TimeUtil::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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用用于日志记录的时间
|
||||
* @return yyyy-MM-dd hh:mm:ss.us
|
||||
*/
|
||||
std::string TimeUtil::getDateTime_usec()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取北京当前日期
|
||||
* @return : 日期 yyyy-mm-dd
|
||||
*/
|
||||
std::string TimeUtil::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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取北京当前时间
|
||||
* @return : 时间 hh:mm:ss
|
||||
*/
|
||||
std::string TimeUtil::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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前 日期+时间
|
||||
* @return yyyy-MM-dd hh:mm:ss
|
||||
*/
|
||||
std::string TimeUtil::getDateTime()
|
||||
{
|
||||
struct timeval time = {0, 0};
|
||||
gettimeofday(&time, nullptr);
|
||||
time_t timep = time.tv_sec + TIME_DIFF;
|
||||
|
||||
struct tm *p = gmtime(&timep);
|
||||
int msec = time.tv_usec / 1000;
|
||||
|
||||
char szTmp[32] = {0};
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用于文件名的时间
|
||||
* @return hh-mm-ss
|
||||
*/
|
||||
std::string TimeUtil::getTime_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[10] = { 0 };
|
||||
sprintf(tmp, "%02d-%02d-%02d", p->tm_hour, p->tm_min, p->tm_sec);
|
||||
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* inParam : N/A
|
||||
* outParam: N/A
|
||||
* return : 时间戳
|
||||
*/
|
||||
/**
|
||||
* 获取当前时间距1970年的秒数(可选毫秒数)
|
||||
* @param usec 是否取毫秒数
|
||||
* @return
|
||||
*/
|
||||
uint64_t TimeUtil::getCurrentTimeMillis(bool usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
if (usec)
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
else
|
||||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定时间距1970年的秒数 (入参格式:YYYY-MM-DD hh-mm-ss)
|
||||
* inParam : std::string &strDateTime 日期时间
|
||||
* outParam: N/A
|
||||
* return : 时间戳
|
||||
*/
|
||||
uint64_t TimeUtil::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;
|
||||
return i64Ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定毫秒数的对应的北京日期时间
|
||||
* inParam : uint64_t i64MilliSeconds
|
||||
* outParam: N/A
|
||||
* return : 日期时间
|
||||
*/
|
||||
std::string TimeUtil::getDateTimeByMilliSeconds(uint64_t i64MilliSeconds)
|
||||
{
|
||||
time_t timep = i64MilliSeconds / 1000 + TIME_DIFF;
|
||||
struct tm *p = gmtime(&timep);
|
||||
|
||||
char szTmp[32] = {0};
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef TimeUtil_H_
|
||||
#define TimeUtil_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
class TimeUtil final
|
||||
{
|
||||
public:
|
||||
static TimeUtil *getins();
|
||||
|
||||
//获取时间戳
|
||||
std::string get_timestamp_file();
|
||||
std::string getDateTime_usec();
|
||||
//获取日期
|
||||
// std::string get_date();
|
||||
//获取北京当前日期
|
||||
std::string getDate();
|
||||
//获取北京当前时间
|
||||
std::string getTime();
|
||||
// 获取当前 日期 时间
|
||||
std::string getDateTime();
|
||||
//获取用于文件名的时间
|
||||
std::string getTime_file();
|
||||
//获取当前时间距1970年的毫秒数
|
||||
uint64_t getCurrentTimeMillis(bool usec = false);
|
||||
//获取指定时间距1970年的毫秒数 (入参格式:YYYY-MM-DD hh-mm-ss)
|
||||
uint64_t getParamTimeMilliSeconds(std::string &strDateTime);
|
||||
//获取指定毫秒数的对应的日期时间
|
||||
std::string getDateTimeByMilliSeconds(uint64_t i64MilliSeconds);
|
||||
|
||||
|
||||
private:
|
||||
TimeUtil() = default;
|
||||
TimeUtil(const TimeUtil &) = delete;
|
||||
TimeUtil(TimeUtil &&) = delete;
|
||||
TimeUtil &operator=(const TimeUtil &) = delete;
|
||||
TimeUtil &operator=(TimeUtil &&) = delete;
|
||||
~TimeUtil() = default;
|
||||
|
||||
//定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露
|
||||
class GarbageCollector
|
||||
{
|
||||
public:
|
||||
~GarbageCollector()
|
||||
{
|
||||
if (TimeUtil::ins)
|
||||
{
|
||||
delete TimeUtil::ins;
|
||||
TimeUtil::ins = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static GarbageCollector gc;
|
||||
static TimeUtil *ins;
|
||||
static std::mutex mx; //锁,保证线程安全
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
Utils *Utils::ins = nullptr;
|
||||
Utils::GarbageCollector Utils::gc;
|
||||
std::mutex Utils::mx;
|
||||
|
||||
Utils *Utils::getins()
|
||||
{
|
||||
//双层锁,确保线程安全
|
||||
if (ins == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mx); //防止异常发生不能解锁
|
||||
if (ins == nullptr)
|
||||
{
|
||||
ins = new Utils();
|
||||
}
|
||||
}
|
||||
return ins;
|
||||
}
|
||||
|
||||
float Utils::getMean(const std::vector<float> &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 Utils::getMax(const std::vector<float> &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 Utils::getMin(const std::vector<float> &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 Utils::getMedian(const std::vector<float> &data)
|
||||
{
|
||||
if (data.size() < 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<float> 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<float>());
|
||||
|
||||
if (n % 2 == 0)
|
||||
{
|
||||
return (data_tmp[n / 2] + data_tmp[n / 2 - 1]) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data_tmp[(n - 1) / 2];
|
||||
}
|
||||
}
|
||||
|
||||
bool Utils::contains_vec(const std::vector<std::string> &vec, std::string x) {
|
||||
return count(vec.begin(), vec.end(), x) > 0;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 读取json格式文件内容
|
||||
// * inParam : std::string &strFilePath :文件路径
|
||||
// * outParam: Json::Value &jvFileInfo :json格式内容
|
||||
// * return : true/false
|
||||
// */
|
||||
// bool Utils::ReadJsonInfo(Json::Value &jvFileInfo, std::string &strFilePath)
|
||||
// {
|
||||
// std::ifstream ifs(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<Json::CharReader> 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 Utils::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;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// Created by matrixai on 4/2/24.
|
||||
//
|
||||
|
||||
#ifndef TRAIN_RFID_LINUX_UTILS_H
|
||||
#define TRAIN_RFID_LINUX_UTILS_H
|
||||
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
namespace ai_matrix
|
||||
{
|
||||
class Utils final
|
||||
{
|
||||
public:
|
||||
static Utils *getins();
|
||||
|
||||
//计算均值
|
||||
float getMean(const std::vector<float> &data);
|
||||
//计算最大值
|
||||
float getMax(const std::vector<float> &data);
|
||||
//计算最小值
|
||||
float getMin(const std::vector<float> &data);
|
||||
//计算中位数
|
||||
float getMedian(const std::vector<float> &data);
|
||||
|
||||
bool contains_vec(const std::vector<std::string> &vec, std::string x);
|
||||
|
||||
// //读取json格式文件内容
|
||||
// bool ReadJsonInfo(Json::Value &jvFileInfo, std::string &strFilePath);
|
||||
// //json格式内容写入文件
|
||||
// bool WriteJsonInfo(Json::Value &jvFileInfo, std::string &strFilePath);
|
||||
|
||||
private:
|
||||
Utils() = default;
|
||||
Utils(const Utils &) = delete;
|
||||
Utils(Utils &&) = delete;
|
||||
Utils &operator=(const Utils &) = delete;
|
||||
Utils &operator=(Utils &&) = delete;
|
||||
~Utils() = default;
|
||||
|
||||
//定义一个嵌套类,负责释放内存,操作系统自动完成,不用担心内存泄露
|
||||
class GarbageCollector
|
||||
{
|
||||
public:
|
||||
~GarbageCollector()
|
||||
{
|
||||
if (Utils::ins)
|
||||
{
|
||||
delete Utils::ins;
|
||||
Utils::ins = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static GarbageCollector gc;
|
||||
static Utils *ins;
|
||||
static std::mutex mx; //锁,保证线程安全
|
||||
};
|
||||
}
|
||||
|
||||
#endif //TRAIN_RFID_LINUX_UTILS_H
|
||||
|
|
@ -104,11 +104,10 @@ namespace ai_matrix
|
|||
|
||||
//检查是否有重复engine
|
||||
std::string engine_unique = engine_name + "_" + std::to_string(engine_id);
|
||||
// printf(engine_unique.c_str());
|
||||
printf(engine_unique.c_str());
|
||||
auto iter = engine_map_.find(engine_unique);
|
||||
if (iter != engine_map_.end())
|
||||
{
|
||||
LogWarn << "重复engine :" << engine_unique;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ namespace ai_matrix
|
|||
std::string get_date();
|
||||
//获取时间
|
||||
std::string get_time();
|
||||
|
||||
//时间戳转化为时间 毫秒级
|
||||
std::string Stamp2Time(long long timestamp, bool has_msec = false);
|
||||
|
||||
|
|
|
|||
15
config.yaml
15
config.yaml
|
|
@ -1,18 +1,11 @@
|
|||
#acl参数
|
||||
stop_delay_count: 64
|
||||
stop_by_vari: 0
|
||||
gc_acl_path: ./config/acl.json
|
||||
gc_init_deviceid: "ALL" #例: 0; 0,1; 2,3; ALL
|
||||
|
||||
method_setting: ./modeltest/model
|
||||
gc_init_deviceid: "ALL" #例: 0; 0,1; 2,3; ALL
|
||||
|
||||
#识别数据来源参数配置
|
||||
gc_data_source: "camera" #[camera, images]
|
||||
camera:
|
||||
camera_0:
|
||||
#url: "rtsp://admin:sgt12345@10.27.119.13:554/h264/ch1/main/av_stream"
|
||||
# url: "./videos/km70.mp4"
|
||||
url: "./vedio/buertai2.mp4"
|
||||
url: "./videos/06-29_96.mp4"
|
||||
skipInterval: 3
|
||||
target: "NUM"
|
||||
use: true
|
||||
|
|
@ -119,6 +112,8 @@ gc_http_open: 0
|
|||
# gc_http_url: "http://192.168.2.211:20004/api/train-carriage/identification/video-save"
|
||||
# gc_gettoken_url: "http://192.168.2.211:20004/api/blade-auth/oauth/token"
|
||||
# gc_image_srv: "http://192.168.2.211:9010/"
|
||||
username: ""
|
||||
password: ""
|
||||
gc_http_url: "http://192.168.2.121:8081"
|
||||
gc_gettoken_url: "http://192.168.0.121:20004/api/blade-auth/oauth/token"
|
||||
gc_image_srv: "http://192.168.0.121:9010/"
|
||||
|
|
@ -159,7 +154,7 @@ gc_mysql_passwd: "123456"
|
|||
gc_mysql_db: "test1"
|
||||
gc_mysql_port: "http://192.168.2.115:9000"
|
||||
|
||||
gc_push_direction: 1 #(1:识别向左行驶的列车,2:识别向右行驶的列车,0:识别双方向。 注:如果方向不对,服务器会正常识别只是不推送给web)
|
||||
gc_push_direction: 2 #(1:识别向左行驶的列车,2:识别向右行驶的列车,0:识别双方向。 注:如果方向不对,服务器会正常识别只是不推送给web)
|
||||
|
||||
gc_space_minrbx_imgpercent: 0 #间隔框最低点不应小于画面某个高度值(该值为画面百分比) [主要为屏蔽远股道间隔框,若不需要屏蔽则配置为0]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,165 @@
|
|||
init_deviceid: "ALL" #例: 0; 0,1; 2,3; ALL
|
||||
|
||||
# 基础控制参数
|
||||
base:
|
||||
# 股道名称
|
||||
track_name: "1"
|
||||
# 测试模式
|
||||
test_model: false
|
||||
# Api 监听端口
|
||||
api_port: 7070
|
||||
# 是否上传识别结果
|
||||
up_result: false
|
||||
# 是否启用socket-server
|
||||
use_socket_server: false
|
||||
# 日志文件目录
|
||||
log_path: "./logs"
|
||||
# 识别结果目录
|
||||
result_path: "./result"
|
||||
# 调试结果目录
|
||||
debug_result_path: "./debug_result"
|
||||
# 最优识别目录
|
||||
best_result_path: "./best_result"
|
||||
# 结果存储天数
|
||||
result_save_days: 2
|
||||
|
||||
# 日志参数
|
||||
log:
|
||||
# 输出日志级别[DEBUG, INFO, WARN, ERROR, FATAL]
|
||||
out_level: "DEBUG"
|
||||
# 保存日志级别
|
||||
save_level: "DEBUG"
|
||||
|
||||
#识别数据来源参数配置
|
||||
data_source:
|
||||
#url: "rtsp://admin:sgt12345@10.27.119.13:554/h264/ch1/main/av_stream"
|
||||
url: "./vedio/buertai2.mp4"
|
||||
# 跳帧数
|
||||
skip_interval: 3
|
||||
# 识别目标
|
||||
target: "NUM"
|
||||
# 行驶方向 0-自动识别 1-向左 2-向右 (与“首位信息”成对存在,形成例如向左就编号在前,向右就属性在前的对应)
|
||||
direction: 0
|
||||
# 0-向左编号在前 1-向左属性在前 (向右行驶的情况:2-向右编号在前 3-向右属性在前)
|
||||
left_first: 0
|
||||
# (向左行驶的情况:0-向左编号在前 1-向左属性在前) 2-向右编号在前 3-向右属性在前
|
||||
right_first: 3
|
||||
# (ltx,lty,rbx,rby)
|
||||
identify_areas: "120, 0, 1800, 1080"
|
||||
# 大框的最小高度(为屏蔽远股道识别到的信息)
|
||||
classid_minheight: "1:90, 2:120, 3:120, 9:240, 10:240, 18:120"
|
||||
|
||||
# 识别参数
|
||||
identify:
|
||||
# 硬件解码
|
||||
hardware_decode: true
|
||||
# 运行方式
|
||||
run_mode: "always" #[always; command]
|
||||
# 是否开启动态检测
|
||||
need_move_detect_flag: true
|
||||
# 识别方向 [LEFT,RIGHT,ALL]
|
||||
identify_direction: "LEFT"
|
||||
# 大框帧跨度(比一个大框从出现到消失的跨度稍大一点, 跟跳帧有关系)
|
||||
partition_frame_span: 20
|
||||
# 大框帧跨度的位置像素差异
|
||||
split_frame_span_px: 200
|
||||
# 每帧大框位置差异最小值 (持续小于此值,则可能停车)
|
||||
chkstop_px: 15
|
||||
# 持续X次续位置差异小于chkstop_px,则判断为停车。
|
||||
chkstop_count: 10
|
||||
# 过滤最小大框高度(不需要的话就写个很小的值)
|
||||
num_frame_height: 150
|
||||
pro_frame_height: 120
|
||||
# 过滤最大框宽度(不需要的话就写个很大的值)
|
||||
space_frame_width: 500
|
||||
# 是否识别车头
|
||||
train_heard_detect: true
|
||||
# 选优 0-频率优先 1-长度优先
|
||||
select_best_mode: 0
|
||||
# 保存图片质量(1~100 越高越清晰)
|
||||
save_pic_quality: 50
|
||||
|
||||
#是否实时推流-用于直播
|
||||
#gc_push_actual_flag: false
|
||||
|
||||
# 模型参数
|
||||
model:
|
||||
# 来车检测
|
||||
MoveEngine:
|
||||
path: "./model/step0/step0.engine"
|
||||
model_info_path: "./model/step0/move_modelinfo.txt"
|
||||
score_threshold: 0.9
|
||||
nms_threshold: 0.3
|
||||
# 关键区域识别
|
||||
TrainStepOneEngine:
|
||||
path: "./model/step1/step1.engine"
|
||||
model_info_path: "./model/step1/train_step1_modelinfo.txt"
|
||||
score_threshold: 0.6
|
||||
nms_threshold: 0.3
|
||||
# 字符识别
|
||||
TrainStepTwoEngine:
|
||||
path: "./model/step2/step2.engine"
|
||||
model_info_path: "./model/step2/train_step2_modelinfo.txt"
|
||||
score_threshold: 0.7
|
||||
nms_threshold: 0.3
|
||||
# 定检期关键区域识别
|
||||
ChkDateStepOneEngine:
|
||||
path: "./model/chkDate_step1/step1.engine"
|
||||
model_info_path: "./model/chkDate_step1/chkdate_step1_modelinfo.txt"
|
||||
score_threshold: 0.6
|
||||
nms_threshold: 0.3
|
||||
# 定检期字符识别
|
||||
ChkDateStepTwoEngine:
|
||||
path: "./model/chkDate_step2/step2.engine"
|
||||
model_info_path: "./model/chkDate_step2/chkdate_step2_modelinfo.txt"
|
||||
score_threshold: 0.7
|
||||
nms_threshold: 0.3
|
||||
# 集装箱关键区域识别
|
||||
StepOneContainerEngine:
|
||||
path: "./model/container_step1/con1.engine"
|
||||
model_info_path: "./model/container_step1/container_step1_modelinfo.txt"
|
||||
score_threshold: 0.6
|
||||
nms_threshold: 0.3
|
||||
# 集装箱字符识别
|
||||
StepTwoContainerEngine:
|
||||
path: "./model/container_step2/con2.engine"
|
||||
model_info_path: "./model/container_step2/container_step2_modelinfo.txt"
|
||||
score_threshold: 0.7
|
||||
nms_threshold: 0.3
|
||||
|
||||
# http 接口
|
||||
http_client:
|
||||
# 服务器IP
|
||||
http_ip: 192.168.2.108
|
||||
# 通讯端口
|
||||
http_port: 20004
|
||||
# 获取接口授权地址
|
||||
token_path: "/api/blade-auth/oauth/token"
|
||||
# 识别结果上传地址
|
||||
up_result_path: "/api/train-carriage/identification/rfid-save"
|
||||
# 设备状态上传地址
|
||||
device_status_url: "/api/blade-train/deviceInfo/save"
|
||||
# 接口用户名
|
||||
username: "guest_01"
|
||||
# 接口密码
|
||||
password: "d55b0f642e817eea24725d2f2a31dd08"
|
||||
# 上传图片的地址
|
||||
image_srv: "http://192.168.0.121:9010/"
|
||||
|
||||
# websocket_server 的服务端参数
|
||||
wsocket_server:
|
||||
port: 7071
|
||||
max_queue_len: 10
|
||||
|
||||
#sftp用户名、密码、地址
|
||||
ftp:
|
||||
type: "ftp" #可选 ftp 或 sftp
|
||||
ip: "192.168.2.138"
|
||||
port: 21 # ftp默认21 sftp默认22
|
||||
username: "nvidia"
|
||||
password: "nvidia"
|
||||
image_path: ""
|
||||
quit_time: 10 #无上传任务延迟XXX秒断开FTP连接
|
||||
|
||||
gc_space_minrbx_imgpercent: 0 #间隔框最低点不应小于画面某个高度值(该值为画面百分比) [主要为屏蔽远股道间隔框,若不需要屏蔽则配置为0]
|
||||
|
||||
|
|
@ -896,6 +896,7 @@ typedef struct
|
|||
int iBigClassId = -1; //大框id (给第二步用 1-属性 23456-编号)
|
||||
uint32_t iFrameId = 0; //帧号
|
||||
float fCenterX; //第一步识别目标中心点X坐标
|
||||
float fTargetWidth; // 第一步识别目标X坐标宽度
|
||||
} CalculateInfo;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
#include "ApiEngine.h"
|
||||
|
||||
using namespace ai_matrix;
|
||||
|
||||
ApiEngine::ApiEngine() {}
|
||||
|
||||
ApiEngine::~ApiEngine() {}
|
||||
|
||||
APP_ERROR ApiEngine::Init()
|
||||
{
|
||||
strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
|
||||
strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
|
||||
|
||||
LogInfo << "engineId_:" << engineId_ << " ApiEngine Init ok";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR ApiEngine::DeInit()
|
||||
{
|
||||
LogInfo << "ApiEngine engineId_:" << engineId_ << " DeInit ok";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR ApiEngine::Process()
|
||||
{
|
||||
int iRet = APP_ERR_OK;
|
||||
|
||||
httplib::Server svr;
|
||||
|
||||
svr.Get("/hello", [](const httplib::Request& req, httplib::Response& res){
|
||||
res.set_content("Hello, World!", "text/plain");
|
||||
});
|
||||
|
||||
|
||||
|
||||
svr.Post("/queryDataSource", [=](const httplib::Request& req, httplib::Response& res){
|
||||
std::string add_result = queryDataSource(req.body);
|
||||
Json::Value response;
|
||||
if (add_result.empty())
|
||||
{
|
||||
response["success"] = true;
|
||||
response["msg"] = add_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
response["success"] = false;
|
||||
response["msg"] = add_result;
|
||||
}
|
||||
res.set_content(response.toStyledString(), "application/json");
|
||||
});
|
||||
|
||||
LogInfo << "开启Api服务,端口:" << 8080;
|
||||
svr.listen("0.0.0.0", 8080);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看当前使用的数据源
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
std::string ApiEngine::queryDataSource(const std::string &req)
|
||||
{
|
||||
try {
|
||||
Json::CharReaderBuilder readerBuilder;
|
||||
std::istringstream iss(req);
|
||||
Json::Value root;
|
||||
std::string errs;
|
||||
bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs);
|
||||
if (parsingSuccessful)
|
||||
{
|
||||
// std::shared_ptr<VTrainInfo> pTrainInfo = std::make_shared<VTrainInfo>();
|
||||
// pTrainInfo->strTrackNo = root["strTrackNo"].asString();
|
||||
// if (root.isMember("numCoordinate"))
|
||||
MyYaml::GetIns()->GetUseDataSourceConfig();
|
||||
|
||||
|
||||
|
||||
// 转发到上传接口引擎中
|
||||
// outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pTrainInfo));
|
||||
// 存储到本地数据库
|
||||
// outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pTrainInfo));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return "接口调用参数异常,所传数据非json:" + req;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
return "接口调用失败!请求内容:" + req + "。 \n异常内容:" + std::string(e.what());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* 拉流engine
|
||||
* */
|
||||
|
||||
#ifndef INC_APIENGINE_H
|
||||
#define INC_APIENGINE_H
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include "AppCommon.h"
|
||||
|
||||
#include "EngineBase.h"
|
||||
#include "EngineFactory.h"
|
||||
|
||||
#include "MyYaml.h"
|
||||
|
||||
#include "json/json.h"
|
||||
#include "httplib.h"
|
||||
|
||||
//#define RTSP_PULL_CAMERA_VIDEO_STREAM
|
||||
class ApiEngine : public ai_matrix::EngineBase
|
||||
{
|
||||
public:
|
||||
ApiEngine();
|
||||
~ApiEngine();
|
||||
|
||||
APP_ERROR Init() override;
|
||||
APP_ERROR DeInit() override;
|
||||
APP_ERROR Process() override;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
std::string strPort0_;
|
||||
std::string strPort1_;
|
||||
|
||||
std::string queryDataSource(const std::string &req);
|
||||
};
|
||||
|
||||
ENGINE_REGIST(ApiEngine)
|
||||
|
||||
#endif
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -50,6 +50,7 @@ private:
|
|||
std::map<int, std::vector<std::string>> mapSourcePushPort_;
|
||||
|
||||
MoveData moveData_;
|
||||
std::queue<MoveData> queuwMoveData_;
|
||||
std::string strDataDir_;
|
||||
|
||||
uint32_t iOrigDataNO_; //原过车数据个数
|
||||
|
|
|
|||
|
|
@ -407,6 +407,31 @@ int DataDealTwoEngine::GetPostData(std::shared_ptr<ProcessData> pProcessData, Js
|
|||
return pPostData->vecPostSubData.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* push数据到队列,队列满时则休眠一段时间再push。
|
||||
* inParam : const std::string strPort push的端口
|
||||
: const std::shared_ptr<ProcessData> &pProcessData push的数据
|
||||
* outParam: N/A
|
||||
* return : N/A
|
||||
*/
|
||||
void DataDealTwoEngine::PushData(const std::string &strPort, const std::shared_ptr<ProcessData> &pProcessData)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pProcessData));
|
||||
if (iRet != 0)
|
||||
{
|
||||
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet;
|
||||
if (iRet == 2)
|
||||
{
|
||||
usleep(10000); // 10ms
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造处理数据并push
|
||||
* inParam : N/A
|
||||
|
|
@ -490,14 +515,14 @@ void DataDealTwoEngine::MakeProcessData(std::shared_ptr<TrainRange> pTrainRange)
|
|||
{
|
||||
if (iPort == vecPushPorts.size() - 1)
|
||||
{
|
||||
iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pProcessData), true);
|
||||
// PushData(vecPushPorts[iPort], pProcessData);
|
||||
//iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pProcessData), true);
|
||||
PushData(vecPushPorts[iPort], pProcessData);
|
||||
continue;
|
||||
}
|
||||
std::shared_ptr<ProcessData> pNewProcessData = std::make_shared<ProcessData>();
|
||||
*pNewProcessData = *pProcessData;
|
||||
iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pNewProcessData), true);
|
||||
// PushData(vecPushPorts[iPort], pNewProcessData);
|
||||
//iRet = outputQueMap_[vecPushPorts[iPort]]->push(std::static_pointer_cast<void>(pNewProcessData), true);
|
||||
PushData(vecPushPorts[iPort], pNewProcessData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -593,7 +618,7 @@ APP_ERROR DataDealTwoEngine::Process()
|
|||
//处理当车厢的每帧信息
|
||||
MakeProcessData(pTrainRange);
|
||||
// push结果汇总
|
||||
iRet = outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_9"]->push(std::static_pointer_cast<void>(pTrainRange), true);
|
||||
iRet = outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_9"]->push(std::static_pointer_cast<void>(pTrainRange));
|
||||
|
||||
iTrainIndex_++;
|
||||
if (pTrainRange->bIsEnd)
|
||||
|
|
|
|||
|
|
@ -306,10 +306,13 @@ APP_ERROR CameraEngine::Process() {
|
|||
if (iRet != APP_ERR_OK) {
|
||||
LogError << "engineId_:" << engineId_ << "push the h264 frame data failed...";
|
||||
}
|
||||
} else if (pkt.stream_index == iAudioStream_) {
|
||||
//音频流不处理。
|
||||
// } else if (pkt.stream_index == iAudioStream_) {
|
||||
// //音频流不处理。
|
||||
|
||||
} else {
|
||||
av_packet_unref(&pkt); //unref
|
||||
LogError << "engineId_:" << engineId_ << " stream err stream_index:" << pkt.stream_index;
|
||||
continue;
|
||||
}
|
||||
av_packet_unref(&pkt); //unref
|
||||
|
||||
|
|
|
|||
|
|
@ -220,9 +220,9 @@ bool DeviceStatusUpSerEngine::ResultToHttpSrv(Json::Value &jvRequest)
|
|||
APP_ERROR DeviceStatusUpSerEngine::Process()
|
||||
{
|
||||
int iRet = APP_ERR_OK;
|
||||
if (0 == MyYaml::GetIns()->GetIntValue("gc_device_status_open"))
|
||||
if (0 == MyYaml::GetIns()->GetIntValue("gc_http_open"))
|
||||
{
|
||||
LogDebug << " gc_device_status_open value is 0";
|
||||
LogDebug << " gc_http_open value is 0";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -342,12 +342,12 @@ APP_ERROR ResultToHttpSrvEngine::Process()
|
|||
usleep(1000); //1ms
|
||||
|
||||
//无数据大于1分钟
|
||||
iNoDataCnt_++;
|
||||
if (iNoDataCnt_ > (60 * 1000))
|
||||
{
|
||||
DealHttpFailInfo();
|
||||
iNoDataCnt_ = 0;
|
||||
}
|
||||
// iNoDataCnt_++;
|
||||
// if (iNoDataCnt_ > (60 * 1000))
|
||||
// {
|
||||
// DealHttpFailInfo();
|
||||
// iNoDataCnt_ = 0;
|
||||
// }
|
||||
continue;
|
||||
}
|
||||
iNoDataCnt_ = 0;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ APP_ERROR DeleteExpiredFolderEngine::Init()
|
|||
{
|
||||
iDaysNumber_ = MyYaml::GetIns()->GetIntValue("gc_days_for_result_expire_folder");
|
||||
strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
|
||||
strLogBakPath_ = MyYaml::GetIns()->GetPathValue("gc_log_logfile_bakpath");
|
||||
|
||||
LogInfo << "DeleteExpiredFolderEngine Init ok";
|
||||
return APP_ERR_OK;
|
||||
|
|
@ -24,13 +25,29 @@ APP_ERROR DeleteExpiredFolderEngine::DeInit()
|
|||
APP_ERROR DeleteExpiredFolderEngine::Process()
|
||||
{
|
||||
int iRet = APP_ERR_OK;
|
||||
const std::chrono::hours LOG_INTERVAL(12); // 每12小时一次
|
||||
auto last_log_time = std::chrono::steady_clock::now() - LOG_INTERVAL;
|
||||
while (!isStop_)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
if (now - last_log_time < LOG_INTERVAL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
last_log_time = now;
|
||||
std::string strTrainDate_temp = MyUtils::getins()->GetDate();
|
||||
|
||||
DeletePreviousFolder(strResultPath_, strTrainDate_temp, iDaysNumber_);
|
||||
// DeletePreviousFolder(this->baseConfig_.strResultPath, strTrainDate_temp, this->baseConfig_.iResultSaveDays + 10);
|
||||
|
||||
usleep(1000*1000*3600*24); //每二十四小时执行一次
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
LogError << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
return APP_ERR_OK;
|
||||
|
|
@ -41,7 +58,7 @@ void DeleteExpiredFolderEngine::DeletePreviousFolder(std::string path, const std
|
|||
// 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;
|
||||
std::cout << "Date before " << n_days << " days from " << date << " is: " << previous_date << std::endl;
|
||||
|
||||
|
||||
// 2
|
||||
|
|
@ -139,7 +156,7 @@ void DeleteExpiredFolderEngine::GetSubfolderNames(std::string &directory, std::v
|
|||
while ((ent = readdir(dir)) != nullptr)
|
||||
{
|
||||
// 排除"."和".."
|
||||
if (ent->d_type == DT_DIR && ent->d_name[0] != '.' && ent->d_name != "best")
|
||||
if (ent->d_type == DT_DIR && ent->d_name[0] != '.' && strcmp(ent->d_name, "best") != 0)
|
||||
{
|
||||
folder_names.push_back(StrToDate(ent->d_name));
|
||||
}
|
||||
|
|
@ -158,9 +175,9 @@ void DeleteExpiredFolderEngine::DeleteFolder(const std::string directory)
|
|||
int result = system(command.c_str());
|
||||
|
||||
if (result != 0)
|
||||
LogError << "Failed to remove directory recursively: " << directory;
|
||||
std::cout << "Failed to remove directory recursively: " << directory << std::endl;
|
||||
else
|
||||
LogError << "delete folder successfully : " << directory;
|
||||
std::cout << "delete folder successfully : " << directory << std::endl;
|
||||
}
|
||||
|
||||
// 删除向量中小于指定日期的所有元素
|
||||
|
|
@ -185,3 +202,21 @@ void DeleteExpiredFolderEngine::DeleteEarlierDatesFolder(std::string &path, std:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void DeleteExpiredFolderEngine::PushData(const std::string &strPort, const std::shared_ptr<ProcessData> &pSaveImgData)
|
||||
// {
|
||||
// while (true)
|
||||
// {
|
||||
// int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pSaveImgData));
|
||||
// if (iRet != 0)
|
||||
// {
|
||||
// LogDebug << "sourceid:" << pSaveImgData->iDataSource << " frameid:" << pSaveImgData->iFrameId << " push fail iRet:" << iRet;
|
||||
// if (iRet == 2)
|
||||
// {
|
||||
// usleep(10000); // 10ms
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ private:
|
|||
|
||||
private:
|
||||
std::string strResultPath_;
|
||||
std::string strLogBakPath_;
|
||||
|
||||
int iDaysNumber_;
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -328,7 +328,9 @@ APP_ERROR MergerAllEngine::Process()
|
|||
特殊处理:针对车头在后的且当前为最后一节,且未识别到车型,则默认设置为车头。
|
||||
防止车尾间隔误识别,多切分车型,且web端无法过滤的问题。
|
||||
*/
|
||||
if (!bHeadFrontFlag_ && pTrain->bIsEnd && pTrain->trainNum.iTrainTypeId == -1)
|
||||
if (!bHeadFrontFlag_
|
||||
&& pTrain->bIsEnd
|
||||
&& pTrain->trainNum.iTrainTypeId == -1)
|
||||
{
|
||||
LogDebug << "cometime:" << pTrain->strTrainDate << " " << pTrain->strTrainName << " iCarXH:" << pTrain->iCarXH
|
||||
<< " num:" << pTrain->trainNum.strTrainNum;
|
||||
|
|
@ -346,6 +348,8 @@ APP_ERROR MergerAllEngine::Process()
|
|||
}
|
||||
}
|
||||
|
||||
// if (pTrain->trainPro.strLoad.size() > 2 && pTrain->trainPro.strLoad[0] != '1') pTrain->trainPro.strLoad = "";
|
||||
|
||||
PushData(pTrain);
|
||||
|
||||
//最后一节处理后,初始化参数
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ APP_ERROR LocalDataMoveEngine::Process()
|
|||
pFtpData->strFtpFilePath = strImgPath;
|
||||
pFtpData->strFtpFileName = strImgName;
|
||||
pFtpData->bIsEnd = pProcessData->bIsEnd;
|
||||
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pFtpData), true);
|
||||
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pFtpData), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
#include "SocketEngine.h"
|
||||
#include "SocketEngine.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ void* SocketEngine::heart_handler(void* arg)
|
|||
++it;
|
||||
}
|
||||
}
|
||||
sleep(3); // 定时三秒
|
||||
sleep(1); // 定时三秒
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -516,6 +516,7 @@ void TransTrainEngine::TransNum(TransSubData &transSubData, std::map<int, std::v
|
|||
|
||||
//校验车型是否符合验证
|
||||
typeInfo.IsChkFlag = AuthTransNum(transSubData.iBigClassId, strTemp);
|
||||
// LogInfo << "--->>> 符合正则吗?" << typeInfo.IsChkFlag << " --- " << strTemp;
|
||||
|
||||
transSubData.vecTransInfo.emplace_back(typeInfo);
|
||||
}
|
||||
|
|
@ -641,15 +642,15 @@ void TransTrainEngine::RecordNum(const TransSubData &transSubData, const std::sh
|
|||
bool bIntervalFlag = ((int)(pProcessData->iFrameId - mapPreFrameId_[pProcessData->iDataSource]) > iSkipInterval_ * 2);
|
||||
if (mapNumInfo_[pProcessData->iDataSource].find(strValue) == mapNumInfo_[pProcessData->iDataSource].end())
|
||||
{
|
||||
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " NUM:" << strValue
|
||||
LogDebug << " frameid:" << pProcessData->iFrameId << " NUM:" << strValue
|
||||
<< " bIntervalFlag:" << bIntervalFlag;
|
||||
if (bIntervalFlag)
|
||||
{
|
||||
mapNumInfo_[pProcessData->iDataSource][strValue] = pProcessData->iFrameId;
|
||||
}
|
||||
}
|
||||
LogDebug << "sourceid:" << pProcessData->iDataSource << " preframeid:" << mapPreFrameId_[pProcessData->iDataSource]
|
||||
<< " frameid:" << pProcessData->iFrameId << " mapsize:" << mapNumInfo_[pProcessData->iDataSource].size();
|
||||
// LogDebug << " preframeid:" << mapPreFrameId_[pProcessData->iDataSource]
|
||||
// << " frameid:" << pProcessData->iFrameId << " mapsize:" << mapNumInfo_[pProcessData->iDataSource].size();
|
||||
mapPreFrameId_[pProcessData->iDataSource] = pProcessData->iFrameId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -389,21 +389,25 @@ int HardH264FFmpegDecode::HardH264FFmpegDecoderV2(AVCodecContext* pDecCtx, AVFra
|
|||
if (ret < 0)
|
||||
{
|
||||
// fprintf(stderr, "Error sending a packet for decoding\n");
|
||||
exit(1);
|
||||
return -9;
|
||||
}
|
||||
|
||||
while (ret >= 0)
|
||||
{
|
||||
ret = avcodec_receive_frame(pDecCtx, pSrcFrame); // 解码
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
if (ret == AVERROR(EAGAIN))
|
||||
{
|
||||
// fprintf(stderr, "During decoding eof\n");
|
||||
return -1;
|
||||
}
|
||||
else if (ret == AVERROR_EOF)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
// fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
return -2;
|
||||
}
|
||||
|
||||
////printf("saving frame %3d\n", pDecCtx->frame_number);
|
||||
|
|
|
|||
|
|
@ -69,19 +69,19 @@ APP_ERROR VideoDecodeEngine::Process()
|
|||
{
|
||||
usleep(10*1000); //10ms
|
||||
|
||||
iNoCameraDataCnt++;
|
||||
if (iNoCameraDataCnt >= 1000) //10秒内收不到,认为相机断开
|
||||
{
|
||||
LogError << "engineId:" << engineId_ << " 超过10秒获取到摄像头数据,疑似摄像头断开。计数:" << iNoCameraDataCnt;
|
||||
iNoCameraDataCnt = 0;
|
||||
//camera异常时,构造空的解码数据push,确保一直有数据流转到后面Engine
|
||||
std::shared_ptr<ProcessData> pProcessData = std::make_shared<ProcessData>();
|
||||
pProcessData->iDataSource = engineId_;
|
||||
pProcessData->i64TimeStamp = MyUtils::getins()->GetCurrentTimeMillis();
|
||||
pProcessData->iSize = 0;
|
||||
pProcessData->pData = nullptr;
|
||||
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData));
|
||||
}
|
||||
// iNoCameraDataCnt++;
|
||||
// if (iNoCameraDataCnt >= 1000) //10秒内收不到,认为相机断开
|
||||
// {
|
||||
// LogError << "engineId:" << engineId_ << " 超过10秒获取到摄像头数据,疑似摄像头断开。计数:" << iNoCameraDataCnt;
|
||||
// iNoCameraDataCnt = 0;
|
||||
// //camera异常时,构造空的解码数据push,确保一直有数据流转到后面Engine
|
||||
// std::shared_ptr<ProcessData> pProcessData = std::make_shared<ProcessData>();
|
||||
// pProcessData->iDataSource = engineId_;
|
||||
// pProcessData->i64TimeStamp = MyUtils::getins()->GetCurrentTimeMillis();
|
||||
// pProcessData->iSize = 0;
|
||||
// pProcessData->pData = nullptr;
|
||||
// iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData));
|
||||
// }
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -161,14 +161,30 @@ APP_ERROR VideoDecodeEngine::Process()
|
|||
LogError << "push the after hard h264 decode yuv420m frame data failed...";
|
||||
}
|
||||
}
|
||||
else if (iDecodeRet == -1)
|
||||
{
|
||||
// 视频结束 或者 数据量不足 一般为正常情况
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError << "engineId:" << engineId_ << " HardH264FFmpegDecoderV2 failed...iDecodeRet:" << iDecodeRet;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
if (hard_h264_ffmpeg_decoder_ != nullptr)
|
||||
{
|
||||
LogError << "解码异常!!";
|
||||
hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderDeInit();
|
||||
delete hard_h264_ffmpeg_decoder_;
|
||||
hard_h264_ffmpeg_decoder_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
LogError << "解码异常!报警:" << e.what();
|
||||
if (hard_h264_ffmpeg_decoder_ != nullptr)
|
||||
{
|
||||
hard_h264_ffmpeg_decoder_->HardH264FFmpegDecoderDeInit();
|
||||
delete hard_h264_ffmpeg_decoder_;
|
||||
hard_h264_ffmpeg_decoder_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,6 +218,8 @@ void MoveEngine::SingleDeviceProcess(std::shared_ptr<ProcessData> pProcessData,
|
|||
APP_ERROR MoveEngine::Process()
|
||||
{
|
||||
int iRet = APP_ERR_OK;
|
||||
const std::chrono::milliseconds LOG_INTERVAL(20000); // 每20秒打印一次
|
||||
auto last_log_time = std::chrono::steady_clock::now() - LOG_INTERVAL;
|
||||
while (!isStop_)
|
||||
{
|
||||
//pop端口0
|
||||
|
|
@ -317,7 +319,7 @@ APP_ERROR MoveEngine::Process()
|
|||
else
|
||||
{
|
||||
iHasTrainNum_ = iHasTrainNum_ == 0 ? iHasTrainNum_ : iHasTrainNum_ - 1;
|
||||
if (iHasTrainNum_ == 0) LogInfo << "----- 当前无车 -----";
|
||||
// if (iHasTrainNum_ == 0) LogInfo << "----- 当前无车 -----";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -351,6 +353,12 @@ APP_ERROR MoveEngine::Process()
|
|||
LogDebug << "while iStepInter_: " << iStepInter_ << " queSize:" << queProcessData_.size();
|
||||
queProcessData_.pop();
|
||||
}
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
if (now - last_log_time > LOG_INTERVAL)
|
||||
{
|
||||
last_log_time = now; // 重置计时器
|
||||
LogInfo << "----- 当前无车 -----";
|
||||
}
|
||||
}
|
||||
//有车识别处理
|
||||
if (iStepInter_ != 0)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ APP_ERROR TrainStepOneEngine::Init()
|
|||
bUseEngine_ = MyUtils::getins()->ChkIsHaveTarget("NUM");
|
||||
if (!bUseEngine_)
|
||||
{
|
||||
LogWarn << "engineId_:" << engineId_ << " not use engine";
|
||||
LogInfo << "engineId_:" << engineId_ << " not use engine";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ APP_ERROR TrainStepOneEngine::InitModel()
|
|||
int nRet = yolov5model.YoloV5ClearityInferenceInit(&modelinfo, strModelName, modelConfig_.strOmPath);
|
||||
if (nRet != 0)
|
||||
{
|
||||
LogInfo << "YoloV5ClassifyInferenceInit nRet:" << nRet;
|
||||
LogError << "YoloV5ClassifyInferenceInit nRet:" << nRet;
|
||||
return APP_ERR_COMM_READ_FAIL;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
|
|
@ -147,7 +147,7 @@ APP_ERROR TrainStepOneEngine::DeInit()
|
|||
{
|
||||
if (!bUseEngine_)
|
||||
{
|
||||
LogWarn << "engineId_:" << engineId_ << " not use engine";
|
||||
LogInfo << "engineId_:" << engineId_ << " not use engine";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ void TrainStepOneEngine::PushData(const std::string &strPort, const std::shared_
|
|||
int iRet = outputQueMap_[strPort]->push(std::static_pointer_cast<void>(pProcessData));
|
||||
if (iRet != 0)
|
||||
{
|
||||
LogDebug << "sourceid:" << pProcessData->iDataSource << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet;
|
||||
LogError << " frameid:" << pProcessData->iFrameId << " push fail iRet:" << iRet;
|
||||
if (iRet == 2)
|
||||
{
|
||||
usleep(10000); // 10ms
|
||||
|
|
@ -194,9 +194,9 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
std::vector<stDetection> vecSpaceInfo;
|
||||
for (auto it = vecRet.begin(); it != vecRet.end();)
|
||||
{
|
||||
LogDebug << "frameId:" << pProcessData->iFrameId
|
||||
<< " bigclassid:" << it->class_id << " ltx:" << it->bbox[0] << " lty:" << it->bbox[1]
|
||||
<< " rbx:" << it->bbox[2] << " rby:" << it->bbox[3];
|
||||
// LogDebug << "frameId:" << pProcessData->iFrameId
|
||||
// << " bigclassid:" << it->class_id << " ltx:" << it->bbox[0] << " lty:" << it->bbox[1]
|
||||
// << " rbx:" << it->bbox[2] << " rby:" << it->bbox[3];
|
||||
// 根据配置文件中 设置的识别范围,过滤掉无效数据
|
||||
if (!(it->bbox[0] >= dataSourceCfg.fIdentifyAreasLTX &&
|
||||
it->bbox[1] >= dataSourceCfg.fIdentifyAreasLTY &&
|
||||
|
|
@ -211,7 +211,7 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
continue;
|
||||
}
|
||||
|
||||
// 如果设置了不识别车头,则去掉车头所有大框
|
||||
// 如果设置了不识别车头,则去掉车头标记的大框
|
||||
if (!MyYaml::GetIns()->GetBoolValue("gc_train_heard_detect") && it->class_id == TRAIN_HEAD)
|
||||
{
|
||||
LogDebug << "frameId:" << pProcessData->iFrameId << " 过滤掉车头编号";
|
||||
|
|
@ -219,7 +219,7 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
continue;
|
||||
}
|
||||
|
||||
// 过滤车头部分的非车头编号大框
|
||||
// 去除车头时的非车头编号信息
|
||||
if(pProcessData->nMonitorState == MONITOR_MODEL_TRAIN_HEAD )
|
||||
{
|
||||
if(it->class_id != TRAIN_HEAD)
|
||||
|
|
@ -231,6 +231,18 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
}
|
||||
}
|
||||
|
||||
// 去除非车头的车头编号信息
|
||||
if (pProcessData->nMonitorState != MONITOR_MODEL_TRAIN_HEAD)
|
||||
{
|
||||
if (it->class_id == TRAIN_HEAD)
|
||||
{
|
||||
LogDebug << " 帧号:" << pProcessData->iFrameId
|
||||
<< " 大类:" << it->class_id << " 识别于非车头位置,无效!";
|
||||
it = vecRet.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 去除车尾的间隔信息
|
||||
if (pProcessData->nMonitorState == MONITOR_MODEL_TRAIN_TAIL
|
||||
&& ((it->class_id >= 9 && it->class_id <= 17 && it->class_id != 15) || it->class_id == 18))
|
||||
|
|
@ -242,12 +254,12 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
continue;
|
||||
}
|
||||
|
||||
// 去除无车状态下的大框信息
|
||||
// 过滤掉识别于模型反馈无车状态下的所有大框信息
|
||||
if (pProcessData->nMonitorState == MONITOR_MODEL_NO_TRAIN)
|
||||
{
|
||||
LogDebug << " frameId:" << pProcessData->iFrameId
|
||||
<< " bigclassid:" << it->class_id
|
||||
<<" 识别于无车状态,无效!";
|
||||
<<" 识别于模型反馈的无车状态下,无效!";
|
||||
it = vecRet.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -310,6 +322,22 @@ void TrainStepOneEngine::FilterInvalidInfo(std::vector<stDetection> &vecRet, std
|
|||
continue;
|
||||
}
|
||||
|
||||
if (it->class_id == K_TRAIN_NUM)
|
||||
{
|
||||
int iCenterY = pProcessData->iHeight / 2;
|
||||
int iHeight0 = it->bbox[1] / 2 + it->bbox[3] / 2;
|
||||
if (iHeight0 > iCenterY) {
|
||||
LogWarn << "矿车编号大框在画面Y轴中线以下,帧号:"
|
||||
<< pProcessData->iFrameId
|
||||
<< " 画面Y轴中心:" << iCenterY
|
||||
<< " 大框Y轴中心:" << iHeight0 ;
|
||||
// << "[" << it->bbox[0] << "," << it->bbox[1] << "]"
|
||||
// << "[" << it->bbox[2] << "," << it->bbox[3] << "]";
|
||||
it = vecRet.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//补连塔的相机比较近,间隔基本在画面底部,因此当间隔比较靠画面上时过滤掉。
|
||||
if ((it->class_id >= 9 && it->class_id <= 17 && it->class_id != 15) || it->class_id == U_TRAIN_SPACE)
|
||||
{
|
||||
|
|
@ -401,7 +429,7 @@ APP_ERROR TrainStepOneEngine::Process()
|
|||
{
|
||||
if (!bUseEngine_)
|
||||
{
|
||||
LogWarn << "engineId_:" << engineId_ << " not use engine";
|
||||
LogInfo << "engineId_:" << engineId_ << " not use engine";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
int iRet = APP_ERR_OK;
|
||||
|
|
@ -431,10 +459,7 @@ APP_ERROR TrainStepOneEngine::Process()
|
|||
|
||||
//进行推理
|
||||
std::vector<stDetection> res;
|
||||
//auto start = std::chrono::system_clock::now(); //计时开始
|
||||
yolov5model.YoloV5ClearityInferenceModel(img, res);
|
||||
//auto end = std::chrono::system_clock::now();
|
||||
//LogInfo << "nopr1 inference time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms";
|
||||
|
||||
//过滤无效信息
|
||||
FilterInvalidInfo(res, pProcessData);
|
||||
|
|
@ -475,10 +500,10 @@ APP_ERROR TrainStepOneEngine::Process()
|
|||
SetTargetType(postSubData);
|
||||
pPostData->vecPostSubData.emplace_back(postSubData);
|
||||
|
||||
// LogDebug << "数据源:" << pProcessData->iDataSource << " 帧:" << pProcessData->iFrameId
|
||||
// << " --iClassId:" << singledata.iClassId << " iLine:" << singledata.iLine << " confidence=" << singledata.fScore
|
||||
// << " lx=" << singledata.fLTX << " ly=" << singledata.fLTY << " rx=" << singledata.fRBX << " ry=" << singledata.fRBY
|
||||
// << " clear:" << singledata.fClear;
|
||||
LogDebug << "数据源:" << pProcessData->iDataSource << " 帧:" << pProcessData->iFrameId
|
||||
<< " --iClassId:" << singledata.iClassId << " iLine:" << singledata.iLine << " confidence=" << singledata.fScore
|
||||
<< " lx=" << singledata.fLTX << " ly=" << singledata.fLTY << " rx=" << singledata.fRBX << " ry=" << singledata.fRBY
|
||||
<< " clear:" << singledata.fClear;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -492,8 +517,7 @@ APP_ERROR TrainStepOneEngine::Process()
|
|||
|
||||
//push端口0,第1步推理
|
||||
pProcessData->pVoidData = std::static_pointer_cast<void>(pPostData);
|
||||
iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData), true);
|
||||
// PushData(strPort0_, pProcessData);
|
||||
PushData(strPort0_, pProcessData);
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue