Refactor project structure
This commit is contained in:
398
modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp
Normal file
398
modules/ANSODEngine/ANSCUSTOMDETECTOR.cpp
Normal file
@@ -0,0 +1,398 @@
|
||||
#include "ANSCUSTOMDetector.h"
|
||||
#include "Utility.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace ANSCENTER
|
||||
{
|
||||
std::string ANSCUSTOMDETECTOR::FindANSCustomLibraryName(const std::string& folderPath, const std::string& keyword) {
|
||||
std::string searchPath = folderPath + "\\*.dll";
|
||||
WIN32_FIND_DATAA findFileData;
|
||||
HANDLE hFind = FindFirstFileA(searchPath.c_str(), &findFileData);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
return ""; // Return an empty string if no file is found
|
||||
}
|
||||
|
||||
do {
|
||||
std::string fileName = findFileData.cFileName;
|
||||
if (fileName.find(keyword) != std::string::npos) {
|
||||
FindClose(hFind); // Close the handle before returning
|
||||
return folderPath + "\\" + fileName; // Return the full path
|
||||
}
|
||||
} while (FindNextFileA(hFind, &findFileData) != 0);
|
||||
|
||||
FindClose(hFind); // Close the handle after finishing the loop
|
||||
return ""; // Return an empty string if no match is found
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::OptimizeModel(bool fp16, std::string& optimizedModelFolder) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!ANSODBase::OptimizeModel(fp16, optimizedModelFolder)) {
|
||||
return false;
|
||||
}
|
||||
optimizedModelFolder = _modelFolder;
|
||||
return _customDetector->OptimizeModel(fp16);
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
std::string labelMap;
|
||||
CreateCustomDetector();
|
||||
//_customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation);
|
||||
return _customDetector->Initialize(_modelFolder,_modelConfig.detectionScoreThreshold, labelMap);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::LoadModel", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
_modelFolder = modelFolder;
|
||||
std::string labelMap;
|
||||
_modelConfig = modelConfig;
|
||||
if (_modelConfig.modelMNSThreshold < 0.2)
|
||||
_modelConfig.modelMNSThreshold = 0.5;
|
||||
if (_modelConfig.modelConfThreshold < 0.2)
|
||||
_modelConfig.modelConfThreshold = 0.5;
|
||||
CreateCustomDetector();
|
||||
_customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation);
|
||||
_isInitialized = _customDetector->Initialize(_modelFolder, _modelConfig.detectionScoreThreshold, labelMap);
|
||||
return _isInitialized;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::LoadModel", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::ConfigureParameters(Params& param) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
if (!_customDetector) {
|
||||
this->_logger.LogError("ANSCUSTOMDETECTOR::ConfigureParamaters", "Custom detector is not initialized", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
// Convert the vector of Params to a vector of CustomParams
|
||||
CustomParams customParams;
|
||||
_customDetector->ConfigureParameters(customParams);
|
||||
|
||||
// loop throught this->_params and set the values
|
||||
param.ROI_Config.clear();
|
||||
for (auto& cf : customParams.ROI_Config) {
|
||||
ROIConfig ROIConfig;
|
||||
ROIConfig.Rectangle = cf.Rectangle;
|
||||
ROIConfig.Polygon = cf.Polygon;
|
||||
ROIConfig.Line = cf.Line;
|
||||
ROIConfig.MinItems = cf.MinItems;
|
||||
ROIConfig.MaxItems = cf.MaxItems;
|
||||
ROIConfig.Name = cf.Name;
|
||||
ROIConfig.ROIMatch = cf.ROIMatch;
|
||||
param.ROI_Config.push_back(ROIConfig);
|
||||
}
|
||||
param.ROI_Options.clear();
|
||||
for (auto& op : customParams.ROI_Options) {
|
||||
param.ROI_Options.push_back(op);
|
||||
}
|
||||
param.Parameters.clear();
|
||||
for (auto& par : customParams.Parameters) {
|
||||
Parameter Param;
|
||||
Param.Name = par.Name;
|
||||
Param.DataType = par.DataType;
|
||||
Param.NoOfDecimals = par.NoOfDecimals;
|
||||
Param.MaxValue = par.MaxValue;
|
||||
Param.MinValue = par.MinValue;
|
||||
Param.StartValue = par.StartValue;
|
||||
Param.ListItems.clear();
|
||||
for (auto& item : par.ListItems) {
|
||||
Param.ListItems.push_back(item);
|
||||
}
|
||||
Param.DefaultValue = par.DefaultValue;
|
||||
Param.Value = par.Value;
|
||||
param.Parameters.push_back(Param);
|
||||
}
|
||||
param.ROI_Values.clear();
|
||||
for (auto& roi : customParams.ROI_Values) {
|
||||
ROIValue roiValue;
|
||||
roiValue.ROIMatch = roi.ROIMatch;
|
||||
roiValue.OriginalImageSize = roi.OriginalImageSize;
|
||||
roiValue.Name = roi.Name;
|
||||
roiValue.Option = roi.Option;
|
||||
roiValue.ROIPoints.clear();
|
||||
for (auto& point : roi.ROIPoints) {
|
||||
Point customPoint;
|
||||
customPoint.x = point.x;
|
||||
customPoint.y = point.y;
|
||||
roiValue.ROIPoints.push_back(customPoint);
|
||||
}
|
||||
param.ROI_Values.push_back(roiValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::ConfigureParamaters", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::SetParameters(const Params& param) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
// Convert the vector of Params to a vector of CustomParams
|
||||
ANSODBase::SetParameters(param);
|
||||
CustomParams customParams;
|
||||
customParams.ROI_Config.clear();
|
||||
for (auto& cf : param.ROI_Config) {
|
||||
CustomROIConfig customROIConfig;
|
||||
customROIConfig.Rectangle = cf.Rectangle;
|
||||
customROIConfig.Polygon = cf.Polygon;
|
||||
customROIConfig.Line = cf.Line;
|
||||
customROIConfig.MinItems = cf.MinItems;
|
||||
customROIConfig.MaxItems = cf.MaxItems;
|
||||
customROIConfig.Name = cf.Name;
|
||||
customROIConfig.ROIMatch = cf.ROIMatch;
|
||||
customParams.ROI_Config.push_back(customROIConfig);
|
||||
}
|
||||
customParams.ROI_Options.clear();
|
||||
for (auto& op : param.ROI_Options) {
|
||||
customParams.ROI_Options.push_back(op);
|
||||
}
|
||||
customParams.Parameters.clear();
|
||||
for (auto& par : param.Parameters) {
|
||||
CustomParameter customParam;
|
||||
customParam.Name = par.Name;
|
||||
customParam.DataType = par.DataType;
|
||||
customParam.NoOfDecimals = par.NoOfDecimals;
|
||||
customParam.MaxValue = par.MaxValue;
|
||||
customParam.MinValue = par.MinValue;
|
||||
customParam.StartValue = par.StartValue;
|
||||
customParam.ListItems.clear();
|
||||
for (auto& item : par.ListItems) {
|
||||
customParam.ListItems.push_back(item);
|
||||
}
|
||||
customParam.DefaultValue = par.DefaultValue;
|
||||
customParam.Value = par.Value;
|
||||
customParams.Parameters.push_back(customParam);
|
||||
}
|
||||
customParams.ROI_Values.clear();
|
||||
for (auto& roi : param.ROI_Values) {
|
||||
CustomROIValue roiValue;
|
||||
roiValue.ROIMatch = roi.ROIMatch;
|
||||
roiValue.OriginalImageSize = roi.OriginalImageSize;
|
||||
roiValue.Name = roi.Name;
|
||||
roiValue.Option = roi.Option;
|
||||
roiValue.ROIPoints.clear();
|
||||
for (auto& point : roi.ROIPoints) {
|
||||
CustomPoint customPoint;
|
||||
customPoint.x = point.x;
|
||||
customPoint.y = point.y;
|
||||
roiValue.ROIPoints.push_back(customPoint);
|
||||
}
|
||||
customParams.ROI_Values.push_back(roiValue);
|
||||
}
|
||||
return _customDetector->SetParameters(customParams);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::SetParamaters", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::CreateCustomDetector() {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
Destroy();
|
||||
//1. Load dynamic library
|
||||
_modelFilePath = FindANSCustomLibraryName(_modelFolder, "ANSCustom");//
|
||||
if (!FileExist(_modelFilePath)) {
|
||||
_modelFilePath = CreateFilePath(_modelFolder, "ANSCustomCode.dll"); // This is the dynamic library
|
||||
}
|
||||
//2. Check if the file exists again
|
||||
if (!FileExist(_modelFilePath)) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot find ANSCustomCode.dll", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. Load the library
|
||||
std::wstring dllPath = String2WString(_modelFilePath);
|
||||
hMod = LoadLibrary(dllPath.c_str());
|
||||
if (!hMod) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot open library", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
CreatePluginFunc createPlugin = (CreatePluginFunc)GetProcAddress(hMod, "Create");
|
||||
|
||||
if (!createPlugin) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize.", "Cannot load Create", __FILE__, __LINE__);
|
||||
FreeLibrary(hMod);
|
||||
return false;
|
||||
}
|
||||
_customDetector = std::unique_ptr<IANSCustomClass>(createPlugin());
|
||||
if (!_customDetector) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", "Cannot create custom detector", __FILE__, __LINE__);
|
||||
FreeLibrary(hMod);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
_modelConfig = modelConfig;
|
||||
if (_modelConfig.modelMNSThreshold < 0.2)
|
||||
_modelConfig.modelMNSThreshold = 0.5;
|
||||
if (_modelConfig.modelConfThreshold < 0.2)
|
||||
_modelConfig.modelConfThreshold = 0.5;
|
||||
_modelConfig.detectionType = ANSCENTER::DetectionType::DETECTION;
|
||||
labelMap.clear();
|
||||
//1. Create custom detector
|
||||
CreateCustomDetector();
|
||||
//2. Load initial model
|
||||
_customDetector->SetLoadEngineOnCreate(this->_loadEngineOnCreation);
|
||||
_isInitialized = _customDetector->Initialize(_modelFolder, _modelConfig.detectionScoreThreshold,labelMap);
|
||||
return _isInitialized;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Initialize", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::vector<Object> ANSCUSTOMDETECTOR::RunInference(const cv::Mat& input) {
|
||||
return RunInference(input, "CustomCam");
|
||||
}
|
||||
std::vector<Object> ANSCUSTOMDETECTOR::RunInference(const cv::Mat& input,const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
std::vector<Object> result;
|
||||
|
||||
try {
|
||||
// Early returns - good practice maintained
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference",
|
||||
"Invalid License", __FILE__, __LINE__);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference",
|
||||
"Model is not initialized", __FILE__, __LINE__);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (input.empty() || input.cols < 10 || input.rows < 10) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Run inference
|
||||
std::vector<CustomObject> customResult = _customDetector->RunInference(input, camera_id);
|
||||
|
||||
// Pre-allocate to avoid reallocations
|
||||
result.reserve(customResult.size());
|
||||
|
||||
//// Use emplace_back + move semantics for zero-copy construction
|
||||
for (auto& customObj : customResult) {
|
||||
Object obj;
|
||||
obj.classId = customObj.classId;
|
||||
obj.trackId = customObj.trackId;
|
||||
obj.className = std::move(customObj.className);
|
||||
obj.confidence = customObj.confidence;
|
||||
obj.mask = std::move(customObj.mask);
|
||||
obj.box = customObj.box;
|
||||
obj.extraInfo = std::move(customObj.extraInfo);
|
||||
obj.kps = std::move(customObj.kps);
|
||||
obj.polygon = std::move(customObj.polygon);
|
||||
obj.cameraId = std::move(customObj.cameraId);
|
||||
|
||||
result.emplace_back(std::move(obj));
|
||||
}
|
||||
|
||||
if (_trackerEnabled) {
|
||||
result = ApplyTracking(result, camera_id);
|
||||
if (_stabilizationEnabled) result = StabilizeDetections(result, camera_id);
|
||||
}
|
||||
|
||||
return result; // RVO applies, no copy
|
||||
}
|
||||
catch (const std::exception& e) { // Catch by const reference
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::RunInference",
|
||||
e.what(), __FILE__, __LINE__);
|
||||
return {}; // Return empty vector
|
||||
}
|
||||
}
|
||||
|
||||
ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR() {
|
||||
try {
|
||||
//this->_logger.LogDebug("ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR()", "Release ANSCUSTOMDETECTOR ", __FILE__, __LINE__);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::~ANSCUSTOMDETECTOR()", e.what(), __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::Destroy() {
|
||||
try {
|
||||
if (_customDetector) {
|
||||
_customDetector->Destroy();
|
||||
_customDetector.reset();
|
||||
}
|
||||
if (hMod) {
|
||||
FreeLibrary(hMod);
|
||||
hMod = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
this->_logger.LogFatal("ANSCUSTOMDETECTOR::Destroy", e.what(), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//std::vector<Object> ANSCUSTOMDETECTOR::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
// std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
// std::vector<Object> result;
|
||||
// try {
|
||||
// if (!_licenseValid) {
|
||||
// this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference", "Invalid License", __FILE__, __LINE__);
|
||||
// return result;
|
||||
// }
|
||||
// if (!_isInitialized) {
|
||||
// this->_logger.LogError("ANSCUSTOMDETECTOR::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
// return result;
|
||||
// }
|
||||
// // Run inference
|
||||
// if (input.empty()) return result;
|
||||
// if ((input.cols < 10) || (input.rows < 10)) return result;
|
||||
// std::vector<CustomObject> customResult;
|
||||
// customResult = _customDetector->RunInference(input,camera_id);
|
||||
// for (int i = 0; i < customResult.size(); i++) {
|
||||
// Object obj;
|
||||
// obj.classId = customResult[i].classId;
|
||||
// obj.trackId = customResult[i].trackId;
|
||||
// obj.className = customResult[i].className;
|
||||
// obj.confidence = customResult[i].confidence;
|
||||
// obj.mask = customResult[i].mask;
|
||||
// obj.box = customResult[i].box;
|
||||
// obj.extraInfo = customResult[i].extraInfo;
|
||||
// obj.kps = customResult[i].kps;
|
||||
// obj.polygon = customResult[i].polygon;
|
||||
// obj.cameraId = customResult[i].cameraId;
|
||||
// //obj.attributes = customResult[i].attributes;
|
||||
// result.push_back(obj);
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
// catch (std::exception& e) {
|
||||
// result.clear();
|
||||
// this->_logger.LogFatal("ANSCUSTOMDETECTOR::RunInference", e.what(), __FILE__, __LINE__);
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
Reference in New Issue
Block a user