Fix mutex lock issues
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "ANSLPR_OCR.h"
|
||||
#include "ANSRTYOLO.h"
|
||||
#include "ANSONNXYOLO.h"
|
||||
#include "ANSOnnxOCR.h"
|
||||
#include "ANSOCRBase.h"
|
||||
@@ -20,6 +21,59 @@ static void WriteEventLog(const char* message, WORD eventType = EVENTLOG_INFORMA
|
||||
OutputDebugStringA("\n");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SEH wrapper for loading ANSRTYOLO (TensorRT) models — used when NVIDIA GPU
|
||||
// is detected. Falls back to ANSONNXYOLO if TRT fails.
|
||||
// ---------------------------------------------------------------------------
|
||||
struct LoadRtParams_OCR {
|
||||
const std::string* licenseKey;
|
||||
ANSCENTER::ModelConfig* config;
|
||||
const std::string* modelFolder;
|
||||
const char* modelName;
|
||||
const char* classFile;
|
||||
std::string* labels;
|
||||
std::unique_ptr<ANSCENTER::ANSODBase>* detector;
|
||||
bool enableTracker;
|
||||
bool disableStabilization;
|
||||
};
|
||||
|
||||
static bool LoadRtModel_OCR_Impl(const LoadRtParams_OCR& p) {
|
||||
try {
|
||||
auto rtyolo = std::make_unique<ANSCENTER::ANSRTYOLO>();
|
||||
bool ok = rtyolo->LoadModelFromFolder(
|
||||
*p.licenseKey, *p.config, p.modelName, p.classFile,
|
||||
*p.modelFolder, *p.labels);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
if (p.enableTracker) {
|
||||
rtyolo->SetTracker(ANSCENTER::TrackerType::BYTETRACK, true);
|
||||
} else {
|
||||
rtyolo->SetTracker(ANSCENTER::TrackerType::BYTETRACK, false);
|
||||
}
|
||||
if (p.disableStabilization) {
|
||||
rtyolo->SetStabilization(false);
|
||||
}
|
||||
*p.detector = std::move(rtyolo);
|
||||
return true;
|
||||
}
|
||||
catch (...) {
|
||||
p.detector->reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool LoadRtModel_OCR_SEH(const LoadRtParams_OCR& p, DWORD* outCode) {
|
||||
*outCode = 0;
|
||||
__try {
|
||||
return LoadRtModel_OCR_Impl(p);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
*outCode = GetExceptionCode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct LoadOnnxParams_OCR {
|
||||
const std::string* licenseKey;
|
||||
ANSCENTER::ModelConfig* config;
|
||||
@@ -186,40 +240,81 @@ namespace ANSCENTER
|
||||
|
||||
bool valid = false;
|
||||
|
||||
// ── Step 2: Load LP detector with ONNX Runtime ───────────────
|
||||
// ── Step 2: Load LP detector ─────────────────────────────────
|
||||
if (FileExist(lprModel)) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with ONNX Runtime");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with ONNX Runtime", __FILE__, __LINE__);
|
||||
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
|
||||
_lpdmodelConfig.modelType = ModelType::ONNXYOLO;
|
||||
std::string _lprClasses;
|
||||
{
|
||||
LoadOnnxParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpdmodelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpd";
|
||||
p.classFile = "lpd.names";
|
||||
p.labels = &_lprClasses;
|
||||
p.detector = &_lpDetector;
|
||||
p.enableTracker = true;
|
||||
p.disableStabilization = true;
|
||||
// Try TensorRT (ANSRTYOLO) when NVIDIA GPU is detected
|
||||
if (engineType == EngineType::NVIDIA_GPU) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with TensorRT");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with TensorRT", __FILE__, __LINE__);
|
||||
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
|
||||
_lpdmodelConfig.modelType = ModelType::RTYOLO;
|
||||
std::string _lprClasses;
|
||||
{
|
||||
LoadRtParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpdmodelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpd";
|
||||
p.classFile = "lpd.names";
|
||||
p.labels = &_lprClasses;
|
||||
p.detector = &_lpDetector;
|
||||
p.enableTracker = true;
|
||||
p.disableStabilization = true;
|
||||
|
||||
DWORD sehCode = 0;
|
||||
bool lpSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 2 LPD SEH exception 0x%08X — LP detector disabled", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogFatal("ANSALPR_OCR::LoadEngine",
|
||||
"Step 2: LP detector crashed (SEH). LP detector disabled.", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
DWORD sehCode = 0;
|
||||
bool lpSuccess = LoadRtModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 2 LPD TRT SEH exception 0x%08X — falling back to ONNX Runtime", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Step 2: LP detector TensorRT crashed (SEH). Falling back to ONNX Runtime.", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
}
|
||||
else if (!lpSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load LP detector (TensorRT). Falling back to ONNX Runtime.", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
}
|
||||
}
|
||||
else if (!lpSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load LP detector (ONNX Runtime).", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
}
|
||||
|
||||
// Fallback to ONNX Runtime (ANSONNXYOLO) if TRT was not attempted or failed
|
||||
if (!_lpDetector) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 2 - Loading LP detector with ONNX Runtime");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 2: Loading LP detector with ONNX Runtime", __FILE__, __LINE__);
|
||||
_lpdmodelConfig.detectionType = DetectionType::DETECTION;
|
||||
_lpdmodelConfig.modelType = ModelType::ONNXYOLO;
|
||||
std::string _lprClasses;
|
||||
{
|
||||
LoadOnnxParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpdmodelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpd";
|
||||
p.classFile = "lpd.names";
|
||||
p.labels = &_lprClasses;
|
||||
p.detector = &_lpDetector;
|
||||
p.enableTracker = true;
|
||||
p.disableStabilization = true;
|
||||
|
||||
DWORD sehCode = 0;
|
||||
bool lpSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 2 LPD SEH exception 0x%08X — LP detector disabled", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogFatal("ANSALPR_OCR::LoadEngine",
|
||||
"Step 2: LP detector crashed (SEH). LP detector disabled.", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
}
|
||||
else if (!lpSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load LP detector (ONNX Runtime).", __FILE__, __LINE__);
|
||||
if (_lpDetector) _lpDetector.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,37 +397,77 @@ namespace ANSCENTER
|
||||
|
||||
// ── Step 4: Load colour classifier (optional) ────────────────
|
||||
if (FileExist(colorModel) && (_lpColourModelConfig.detectionScoreThreshold > 0)) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with ONNX Runtime");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with ONNX Runtime", __FILE__, __LINE__);
|
||||
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
|
||||
_lpColourModelConfig.modelType = ModelType::ONNXYOLO;
|
||||
{
|
||||
LoadOnnxParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpColourModelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpc";
|
||||
p.classFile = "lpc.names";
|
||||
p.labels = &_lpColourLabels;
|
||||
p.detector = &_lpColourDetector;
|
||||
p.enableTracker = false;
|
||||
p.disableStabilization = false;
|
||||
// Try TensorRT (ANSRTYOLO) when NVIDIA GPU is detected
|
||||
if (engineType == EngineType::NVIDIA_GPU) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with TensorRT");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with TensorRT", __FILE__, __LINE__);
|
||||
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
|
||||
_lpColourModelConfig.modelType = ModelType::RTYOLO;
|
||||
{
|
||||
LoadRtParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpColourModelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpc";
|
||||
p.classFile = "lpc.names";
|
||||
p.labels = &_lpColourLabels;
|
||||
p.detector = &_lpColourDetector;
|
||||
p.enableTracker = false;
|
||||
p.disableStabilization = false;
|
||||
|
||||
DWORD sehCode = 0;
|
||||
bool colourSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 4 LPC SEH exception 0x%08X — colour detection disabled", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Step 4: Colour classifier crashed. Colour detection disabled.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
DWORD sehCode = 0;
|
||||
bool colourSuccess = LoadRtModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 4 LPC TRT SEH exception 0x%08X — falling back to ONNX Runtime", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Step 4: Colour classifier TensorRT crashed (SEH). Falling back to ONNX Runtime.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
}
|
||||
else if (!colourSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load colour classifier (TensorRT). Falling back to ONNX Runtime.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
}
|
||||
}
|
||||
else if (!colourSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load colour detector (ONNX Runtime). Colour detection disabled.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
}
|
||||
|
||||
// Fallback to ONNX Runtime (ANSONNXYOLO) if TRT was not attempted or failed
|
||||
if (!_lpColourDetector) {
|
||||
WriteEventLog("ANSALPR_OCR::LoadEngine: Step 4 - Loading colour classifier with ONNX Runtime");
|
||||
this->_logger.LogInfo("ANSALPR_OCR::LoadEngine", "Step 4: Loading colour classifier with ONNX Runtime", __FILE__, __LINE__);
|
||||
_lpColourModelConfig.detectionType = DetectionType::CLASSIFICATION;
|
||||
_lpColourModelConfig.modelType = ModelType::ONNXYOLO;
|
||||
{
|
||||
LoadOnnxParams_OCR p{};
|
||||
p.licenseKey = &_licenseKey;
|
||||
p.config = &_lpColourModelConfig;
|
||||
p.modelFolder = &_modelFolder;
|
||||
p.modelName = "lpc";
|
||||
p.classFile = "lpc.names";
|
||||
p.labels = &_lpColourLabels;
|
||||
p.detector = &_lpColourDetector;
|
||||
p.enableTracker = false;
|
||||
p.disableStabilization = false;
|
||||
|
||||
DWORD sehCode = 0;
|
||||
bool colourSuccess = LoadOnnxModel_OCR_SEH(p, &sehCode);
|
||||
if (sehCode != 0) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf),
|
||||
"ANSALPR_OCR::LoadEngine: Step 4 LPC SEH exception 0x%08X — colour detection disabled", sehCode);
|
||||
WriteEventLog(buf, EVENTLOG_ERROR_TYPE);
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Step 4: Colour classifier crashed. Colour detection disabled.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
}
|
||||
else if (!colourSuccess) {
|
||||
this->_logger.LogError("ANSALPR_OCR::LoadEngine",
|
||||
"Failed to load colour detector (ONNX Runtime). Colour detection disabled.", __FILE__, __LINE__);
|
||||
if (_lpColourDetector) _lpColourDetector.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ namespace ANSCENTER { class ANSONNXOCR; struct OCRModelConfig; }
|
||||
|
||||
namespace ANSCENTER
|
||||
{
|
||||
/// ANSALPR_OCR — License plate recognition using ONNX YOLO for LP detection
|
||||
/// ANSALPR_OCR — License plate recognition using YOLO for LP detection
|
||||
/// and ANSONNXOCR (PaddleOCR v5) for text recognition.
|
||||
///
|
||||
/// Pipeline:
|
||||
/// 1. Detect license plates using _lpDetector (ANSONNXYOLO)
|
||||
/// 1. Detect license plates using _lpDetector (ANSRTYOLO on NVIDIA GPU, ANSONNXYOLO otherwise)
|
||||
/// 2. For each detected plate, run OCR using _ocrEngine (ANSONNXOCR)
|
||||
/// 3. Optionally classify plate colour using _lpColourDetector (ANSONNXYOLO)
|
||||
/// 3. Optionally classify plate colour using _lpColourDetector (ANSRTYOLO on NVIDIA GPU, ANSONNXYOLO otherwise)
|
||||
///
|
||||
/// Supports multiple countries via the Country enum and ALPR post-processing
|
||||
/// from ANSOCR's ANSOCRBase infrastructure.
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSANOMALIB::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -86,6 +87,7 @@ namespace ANSCENTER {
|
||||
|
||||
bool ANSANOMALIB::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -159,6 +161,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSANOMALIB::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
|
||||
//this->_logger.LogDebug("ANSANOMALIB::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
|
||||
@@ -232,7 +235,7 @@ namespace ANSCENTER {
|
||||
return RunInference(input, "ANSANOMALIBCAM");
|
||||
}
|
||||
std::vector<Object> ANSANOMALIB::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("ANSANOMALIB::RunInference")) return {};
|
||||
std::vector<Object> output;
|
||||
output.clear();
|
||||
if (!_licenseValid) {
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSCUSTOMDETECTOR::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -50,6 +51,7 @@ namespace ANSCENTER
|
||||
}
|
||||
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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelFolder = modelFolder;
|
||||
std::string labelMap;
|
||||
@@ -242,6 +244,7 @@ namespace ANSCENTER
|
||||
}
|
||||
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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -268,7 +271,7 @@ namespace ANSCENTER
|
||||
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);
|
||||
if (!PreInferenceCheck("ANSCUSTOMDETECTOR::RunInference")) return {};
|
||||
std::vector<Object> result;
|
||||
|
||||
try {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include "ANSMOT.h"
|
||||
#include "onnxruntime_cxx_api.h"
|
||||
|
||||
@@ -729,6 +731,58 @@ namespace ANSCENTER
|
||||
void LoadClassesFromString();
|
||||
void LoadClassesFromFile();
|
||||
std::recursive_mutex _mutex;
|
||||
// Guard: true while Initialize/LoadModel is in progress on any thread.
|
||||
// Inference callers can check this to fail-fast instead of blocking.
|
||||
std::atomic<bool> _modelLoading{ false };
|
||||
|
||||
// Try to lock _mutex with a timeout. Returns a unique_lock that
|
||||
// evaluates to true on success. On timeout, logs a warning with
|
||||
// the caller name and returns an unlocked unique_lock.
|
||||
std::unique_lock<std::recursive_mutex> TryLockWithTimeout(
|
||||
const char* caller, unsigned int timeoutMs = 5000)
|
||||
{
|
||||
const auto deadline = std::chrono::steady_clock::now()
|
||||
+ std::chrono::milliseconds(timeoutMs);
|
||||
std::unique_lock<std::recursive_mutex> lk(_mutex, std::defer_lock);
|
||||
while (!lk.try_lock()) {
|
||||
if (std::chrono::steady_clock::now() >= deadline) {
|
||||
_logger.LogWarn(caller,
|
||||
"Mutex acquisition timed out after "
|
||||
+ std::to_string(timeoutMs) + " ms"
|
||||
+ (_modelLoading.load() ? " (model loading in progress)" : ""),
|
||||
__FILE__, __LINE__);
|
||||
return lk; // unlocked
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
return lk; // locked
|
||||
}
|
||||
|
||||
// Pre-inference gate: checks _modelLoading, validates state
|
||||
// (_modelLoadValid, _licenseValid, _isInitialized), and acquires
|
||||
// _mutex with a timeout. Returns true if inference may proceed.
|
||||
// On failure (loading in progress, timeout, or invalid state)
|
||||
// returns false and the caller should return {}.
|
||||
bool PreInferenceCheck(const char* caller) {
|
||||
if (_modelLoading.load()) return false;
|
||||
auto lk = TryLockWithTimeout(caller);
|
||||
if (!lk.owns_lock()) return false;
|
||||
if (!_licenseValid || !_isInitialized)
|
||||
return false;
|
||||
return true; // lock released here — caller proceeds unlocked
|
||||
}
|
||||
|
||||
// RAII helper: sets _modelLoading=true on construction, false on destruction.
|
||||
// Use in Initialize/LoadModel/LoadModelFromFolder to guarantee the flag
|
||||
// is always cleared, even on exceptions or early returns.
|
||||
struct ModelLoadingGuard {
|
||||
std::atomic<bool>& flag;
|
||||
explicit ModelLoadingGuard(std::atomic<bool>& f) : flag(f) { flag.store(true); }
|
||||
~ModelLoadingGuard() { flag.store(false); }
|
||||
ModelLoadingGuard(const ModelLoadingGuard&) = delete;
|
||||
ModelLoadingGuard& operator=(const ModelLoadingGuard&) = delete;
|
||||
};
|
||||
|
||||
MoveDetectsHandler _handler;
|
||||
size_t QUEUE_SIZE = 20;
|
||||
|
||||
|
||||
@@ -2135,8 +2135,9 @@ namespace ANSCENTER
|
||||
|
||||
// Update model configuration with the new parameters (brief lock for config)
|
||||
if (confidenceThreshold > 0) {
|
||||
std::lock_guard<std::recursive_mutex> cfgLock(_mutex);
|
||||
_modelConfig.detectionScoreThreshold = confidenceThreshold;
|
||||
auto cfgLock = TryLockWithTimeout("ANSODBase::RunInferenceWithOption", 2000);
|
||||
if (cfgLock.owns_lock())
|
||||
_modelConfig.detectionScoreThreshold = confidenceThreshold;
|
||||
}
|
||||
switch (mode) {
|
||||
case 0: // Normal mode
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ODHUBAPI::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -77,6 +78,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ODHUBAPI::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -147,6 +149,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ODHUBAPI::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -218,7 +221,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<Object> ODHUBAPI::RunInference(const cv::Mat& input, const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("ODHUBAPI::RunInference")) return {};
|
||||
std::vector<Object> result;
|
||||
|
||||
try {
|
||||
|
||||
@@ -870,6 +870,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSONNXCL::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelLoadValid = false;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -931,6 +932,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSONNXCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -986,6 +988,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSONNXCL::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1056,25 +1059,7 @@ namespace ANSCENTER
|
||||
Destroy();
|
||||
}
|
||||
std::vector<Object> ANSONNXCL::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSONNXCL::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSONNXCL::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSONNXCL::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!PreInferenceCheck("ANSONNXCL::RunInference")) return {};
|
||||
try {
|
||||
std::vector<Object> result;
|
||||
if (input.empty()) return result;
|
||||
|
||||
@@ -1372,6 +1372,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXOBB::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelLoadValid = false;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -1433,6 +1434,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXOBB::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -1488,6 +1490,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXOBB::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1551,25 +1554,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
}
|
||||
std::vector<Object> ANSONNXOBB::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSONNXOBB::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!PreInferenceCheck("ANSONNXOBB::RunInference")) return {};
|
||||
try {
|
||||
std::vector<Object> result;
|
||||
if (input.empty()) return result;
|
||||
|
||||
@@ -1262,6 +1262,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelLoadValid = false;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -1324,6 +1325,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -1380,6 +1382,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1444,25 +1447,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
}
|
||||
std::vector<Object> ANSONNXPOSE::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSONNXPOSE::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!PreInferenceCheck("ANSONNXPOSE::RunInference")) return {};
|
||||
try {
|
||||
std::vector<Object> result;
|
||||
if (input.empty()) return result;
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace ANSCENTER
|
||||
std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig,
|
||||
modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -84,6 +85,7 @@ namespace ANSCENTER
|
||||
const std::string& modelZipPassword)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -131,6 +133,7 @@ namespace ANSCENTER
|
||||
const std::string& modelFolder, std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
|
||||
modelName, className, modelFolder, labelMap);
|
||||
@@ -281,29 +284,7 @@ namespace ANSCENTER
|
||||
|
||||
std::vector<Object> ANSONNXSAM3::RunInference(const cv::Mat& input, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSONNXSAM3::RunInference", "Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSONNXSAM3::RunInference", "Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSONNXSAM3::RunInference", "Model not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!m_promptSet) {
|
||||
_logger.LogError("ANSONNXSAM3::RunInference",
|
||||
"No prompt set. Call SetPrompt() first.", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (input.empty() || input.cols < 10 || input.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("ANSONNXSAM3::RunInference")) return {};
|
||||
|
||||
try {
|
||||
// Run ONNX engine inference
|
||||
|
||||
@@ -1153,6 +1153,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelLoadValid = false;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
@@ -1215,6 +1216,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -1271,6 +1273,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSONNXSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1335,25 +1338,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
}
|
||||
std::vector<Object> ANSONNXSEG::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSONNXSEG::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
std::vector<Object> result;
|
||||
result.clear();
|
||||
return result;
|
||||
}
|
||||
if (!PreInferenceCheck("ANSONNXSEG::RunInference")) return {};
|
||||
try {
|
||||
std::vector<Object> result;
|
||||
if (input.empty()) return result;
|
||||
|
||||
@@ -1734,6 +1734,7 @@ namespace ANSCENTER {
|
||||
std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_modelLoadValid = false;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig,
|
||||
@@ -1810,6 +1811,7 @@ namespace ANSCENTER {
|
||||
const std::string& modelZipPassword)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -1873,6 +1875,7 @@ namespace ANSCENTER {
|
||||
std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
|
||||
modelName, className,
|
||||
@@ -1948,8 +1951,10 @@ namespace ANSCENTER {
|
||||
std::vector<Object> ANSONNXYOLO::RunInference(const cv::Mat& inputImgBGR,
|
||||
const std::string& camera_id)
|
||||
{
|
||||
if (_modelLoading.load()) return {};
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
auto lock = TryLockWithTimeout("ANSONNXYOLO::RunInference");
|
||||
if (!lock.owns_lock()) return {};
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSONNXYOLO::RunInference", "Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
@@ -1976,29 +1981,55 @@ namespace ANSCENTER {
|
||||
const std::string& camera_id)
|
||||
{
|
||||
try {
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: cam=%s acquiring mutex...", camera_id.c_str());
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: mutex acquired, cam=%s", camera_id.c_str());
|
||||
if (!m_ortEngine) {
|
||||
_logger.LogError("ANSONNXYOLO::DetectObjects", "ORT engine is null", __FILE__, __LINE__);
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: ORT engine is null!");
|
||||
// Fail-fast if a model load/init is in progress on another thread
|
||||
if (_modelLoading.load()) {
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: skipped — model loading in progress, cam=%s", camera_id.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
// ── Snapshot config under a brief lock ──────────────────
|
||||
// Only hold _mutex long enough to validate state and copy
|
||||
// the parameters needed for inference. The actual ORT
|
||||
// detect() call runs outside the lock so that concurrent
|
||||
// Initialize/LoadModel calls are not blocked for the full
|
||||
// duration of inference.
|
||||
float probThresh, nmsThresh;
|
||||
int numKps;
|
||||
std::vector<std::string> classes;
|
||||
bool trackerEnabled, stabilizationEnabled;
|
||||
{
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: cam=%s acquiring mutex...", camera_id.c_str());
|
||||
auto lk = TryLockWithTimeout("ANSONNXYOLO::DetectObjects");
|
||||
if (!lk.owns_lock()) return {}; // timed out
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: mutex acquired, cam=%s", camera_id.c_str());
|
||||
|
||||
if (!m_ortEngine) {
|
||||
_logger.LogError("ANSONNXYOLO::DetectObjects", "ORT engine is null", __FILE__, __LINE__);
|
||||
ANS_DBG("ONNXYOLO", "DetectObjects: ORT engine is null!");
|
||||
return {};
|
||||
}
|
||||
|
||||
// Snapshot parameters while locked
|
||||
probThresh = PROBABILITY_THRESHOLD;
|
||||
nmsThresh = NMS_THRESHOLD;
|
||||
numKps = NUM_KPS;
|
||||
classes = _classes;
|
||||
trackerEnabled = _trackerEnabled;
|
||||
stabilizationEnabled = _stabilizationEnabled;
|
||||
}
|
||||
// ── _mutex released — heavy work below runs lock-free ───
|
||||
|
||||
// --- NV12 fast path: try to get full-res BGR from GPU NV12 frame ---
|
||||
cv::Mat inferenceImage = inputImage;
|
||||
float bgrScaleX = 1.0f, bgrScaleY = 1.0f;
|
||||
{
|
||||
auto* gpuData = tl_currentGpuFrame();
|
||||
if (gpuData && gpuData->width > 0 && gpuData->height > 0) {
|
||||
// Full-res NV12 available — convert to BGR on CPU for ORT
|
||||
// (ORT preprocessing is CPU-based, so we need a cv::Mat)
|
||||
if (gpuData->cpuYPlane && gpuData->cpuUvPlane &&
|
||||
gpuData->cpuYLinesize >= gpuData->width &&
|
||||
gpuData->cpuUvLinesize >= gpuData->width) {
|
||||
const int fw = gpuData->width;
|
||||
const int fh = gpuData->height;
|
||||
// NV12 requires even dimensions
|
||||
if ((fw % 2) == 0 && (fh % 2) == 0) {
|
||||
try {
|
||||
cv::Mat yPlane(fh, fw, CV_8UC1,
|
||||
@@ -2017,10 +2048,12 @@ namespace ANSCENTER {
|
||||
}
|
||||
}
|
||||
}
|
||||
auto results = m_ortEngine->detect(inferenceImage, _classes,
|
||||
PROBABILITY_THRESHOLD,
|
||||
NMS_THRESHOLD,
|
||||
NUM_KPS);
|
||||
|
||||
// Run ORT inference — no mutex held, this is the expensive call
|
||||
auto results = m_ortEngine->detect(inferenceImage, classes,
|
||||
probThresh,
|
||||
nmsThresh,
|
||||
numKps);
|
||||
|
||||
// --- Rescale coordinates from full-res back to display-res ---
|
||||
if (bgrScaleX != 1.0f || bgrScaleY != 1.0f) {
|
||||
@@ -2044,21 +2077,16 @@ namespace ANSCENTER {
|
||||
for (auto& obj : results)
|
||||
obj.cameraId = camera_id;
|
||||
|
||||
// Skip tracking for classification models
|
||||
if (_trackerEnabled && !m_ortEngine->lastWasClassification) {
|
||||
// Tracking/stabilization (ApplyTracking has its own lock)
|
||||
if (trackerEnabled && !m_ortEngine->lastWasClassification) {
|
||||
results = ApplyTracking(results, camera_id);
|
||||
if (_stabilizationEnabled) results = StabilizeDetections(results, camera_id);
|
||||
if (stabilizationEnabled) results = StabilizeDetections(results, camera_id);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
const std::string msg = e.what();
|
||||
|
||||
// ── DML device-removal detection ──────────────────────────
|
||||
// HRESULT 887A0005 = DXGI_ERROR_DEVICE_REMOVED ("The GPU
|
||||
// device instance has been suspended"). Once the D3D12
|
||||
// device is gone the ORT session is permanently broken.
|
||||
// Log once, attempt CPU fallback, suppress further flood.
|
||||
if (msg.find("887A0005") != std::string::npos) {
|
||||
if (!_dmlDeviceLost) {
|
||||
_dmlDeviceLost = true;
|
||||
@@ -2067,6 +2095,7 @@ namespace ANSCENTER {
|
||||
__FILE__, __LINE__);
|
||||
ANS_DBG("ONNXYOLO", "DML device lost — recreating session on CPU");
|
||||
try {
|
||||
std::lock_guard<std::recursive_mutex> lk(_mutex);
|
||||
m_ortEngine.reset();
|
||||
if (InitOrtEngine(ANSCENTER::EngineType::CPU)) {
|
||||
_logger.LogInfo("ANSONNXYOLO::DetectObjects",
|
||||
@@ -2084,7 +2113,6 @@ namespace ANSCENTER {
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
// Suppress flood — already logged above
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -2101,8 +2129,10 @@ namespace ANSCENTER {
|
||||
std::vector<std::vector<Object>> ANSONNXYOLO::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
|
||||
{
|
||||
if (_modelLoading.load()) return {};
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
auto lock = TryLockWithTimeout("ANSONNXYOLO::RunInferencesBatch");
|
||||
if (!lock.owns_lock()) return {};
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogFatal("ANSONNXYOLO::RunInferencesBatch",
|
||||
"Cannot load ONNX model", __FILE__, __LINE__);
|
||||
@@ -2154,16 +2184,33 @@ namespace ANSCENTER {
|
||||
const std::vector<cv::Mat>& inputImages, const std::string& camera_id)
|
||||
{
|
||||
try {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!m_ortEngine) {
|
||||
_logger.LogError("ANSONNXYOLO::DetectObjectsBatch",
|
||||
"ORT engine is null", __FILE__, __LINE__);
|
||||
return {};
|
||||
if (_modelLoading.load()) return {};
|
||||
|
||||
// Snapshot config under brief lock
|
||||
float probThresh, nmsThresh;
|
||||
int numKps;
|
||||
std::vector<std::string> classes;
|
||||
bool trackerEnabled, stabilizationEnabled;
|
||||
{
|
||||
auto lk = TryLockWithTimeout("ANSONNXYOLO::DetectObjectsBatch");
|
||||
if (!lk.owns_lock()) return {};
|
||||
|
||||
if (!m_ortEngine) {
|
||||
_logger.LogError("ANSONNXYOLO::DetectObjectsBatch",
|
||||
"ORT engine is null", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
probThresh = PROBABILITY_THRESHOLD;
|
||||
nmsThresh = NMS_THRESHOLD;
|
||||
numKps = NUM_KPS;
|
||||
classes = _classes;
|
||||
trackerEnabled = _trackerEnabled;
|
||||
stabilizationEnabled = _stabilizationEnabled;
|
||||
}
|
||||
|
||||
// Heavy work outside lock
|
||||
auto batchResults = m_ortEngine->detectBatch(
|
||||
inputImages, _classes,
|
||||
PROBABILITY_THRESHOLD, NMS_THRESHOLD, NUM_KPS);
|
||||
inputImages, classes, probThresh, nmsThresh, numKps);
|
||||
|
||||
const bool isClassification = m_ortEngine->lastBatchWasClassification;
|
||||
|
||||
@@ -2171,10 +2218,9 @@ namespace ANSCENTER {
|
||||
for (auto& obj : results)
|
||||
obj.cameraId = camera_id;
|
||||
|
||||
// Skip tracking for classification models
|
||||
if (_trackerEnabled && !isClassification) {
|
||||
if (trackerEnabled && !isClassification) {
|
||||
results = ApplyTracking(results, camera_id);
|
||||
if (_stabilizationEnabled) results = StabilizeDetections(results, camera_id);
|
||||
if (stabilizationEnabled) results = StabilizeDetections(results, camera_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2189,6 +2235,7 @@ namespace ANSCENTER {
|
||||
"DirectML GPU device lost (887A0005) — attempting CPU fallback",
|
||||
__FILE__, __LINE__);
|
||||
try {
|
||||
std::lock_guard<std::recursive_mutex> lk(_mutex);
|
||||
m_ortEngine.reset();
|
||||
if (!InitOrtEngine(ANSCENTER::EngineType::CPU))
|
||||
_logger.LogFatal("ANSONNXYOLO::DetectObjectsBatch",
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -78,6 +79,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOCL::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -173,6 +175,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOCL::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
|
||||
//this->_logger.LogDebug("OPENVINOCL::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
|
||||
@@ -242,20 +245,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<Object> OPENVINOCL::RunInference(const cv::Mat& input,const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Early validation
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("OPENVINOCL::RunInference", "Invalid License",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("OPENVINOCL::RunInference", "Model is not initialized",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!PreInferenceCheck("OPENVINOCL::RunInference")) return {};
|
||||
|
||||
if (input.empty() || input.cols < 20 || input.rows < 20) {
|
||||
_logger.LogError("OPENVINOCL::RunInference", "Input image is invalid",
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -79,6 +80,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -180,6 +182,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool OPENVINOOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -248,20 +251,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<Object> OPENVINOOD::RunInference(const cv::Mat& input, const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Early validation
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("OPENVINOOD::RunInference", "Invalid License",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("OPENVINOOD::RunInference", "Model is not initialized",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!PreInferenceCheck("OPENVINOOD::RunInference")) return {};
|
||||
|
||||
if (input.empty() || input.cols < 10 || input.rows < 10) {
|
||||
_logger.LogError("OPENVINOOD::RunInference", "Invalid input image",
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSOVSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -77,6 +78,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSOVSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -143,6 +145,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSOVSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
|
||||
this->_logger.LogDebug("ANSOVSEG::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
|
||||
@@ -211,7 +214,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
std::vector<Object> ANSOVSEG::RunInference(const cv::Mat& input,const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("ANSOVSEG::RunInference")) return {};
|
||||
|
||||
try {
|
||||
// Validation
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace ANSCENTER {
|
||||
|
||||
bool ANSPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -76,6 +77,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -137,6 +139,7 @@ namespace ANSCENTER {
|
||||
|
||||
bool ANSPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
|
||||
this->_logger.LogDebug("ANSPOSE::Initialize. OpenVINO version", openVINOVersion, __FILE__, __LINE__);
|
||||
@@ -199,7 +202,7 @@ namespace ANSCENTER {
|
||||
std::vector<Object> ANSPOSE::RunInference(const cv::Mat& input,
|
||||
const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("ANSPOSE::RunInference")) return {};
|
||||
|
||||
try {
|
||||
// Validation
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace ANSCENTER {
|
||||
bool ANSRTYOLO::LoadModel(const std::string& modelZipFilePath,
|
||||
const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_isFixedBatch = false;
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
@@ -148,6 +149,7 @@ namespace ANSCENTER {
|
||||
std::string modelName, std::string className,
|
||||
const std::string& modelFolder, std::string& labelMap) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_isFixedBatch = false;
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,
|
||||
@@ -250,6 +252,7 @@ namespace ANSCENTER {
|
||||
const std::string& modelZipPassword,
|
||||
std::string& labelMap) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -351,23 +354,7 @@ namespace ANSCENTER {
|
||||
|
||||
std::vector<Object> ANSRTYOLO::RunInference(const cv::Mat& inputImgBGR,
|
||||
const std::string& camera_id) {
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSRTYOLO::RunInference", "Cannot load TensorRT model", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSRTYOLO::RunInference", "Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSRTYOLO::RunInference", "Model not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10)
|
||||
return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSRTYOLO::RunInference")) return {};
|
||||
try { return DetectObjects(inputImgBGR, camera_id); }
|
||||
catch (const std::exception& e) {
|
||||
_logger.LogFatal("ANSRTYOLO::RunInference", e.what(), __FILE__, __LINE__);
|
||||
@@ -377,25 +364,7 @@ namespace ANSCENTER {
|
||||
|
||||
std::vector<std::vector<Object>> ANSRTYOLO::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Cannot load the TensorRT model", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Runtime license is not valid or expired", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Initialisation is not valid", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputs.empty()) {
|
||||
_logger.LogFatal("ANSRTYOLO::RunInferencesBatch", "Input images vector is empty", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("ANSRTYOLO::RunInferencesBatch")) return {};
|
||||
try {
|
||||
if (_isFixedBatch) return ANSODBase::RunInferencesBatch(inputs, camera_id);
|
||||
else return DetectObjectsBatch(inputs, camera_id);
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace ANSCENTER {
|
||||
|
||||
bool ANSSAM::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -67,6 +68,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool ANSSAM::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -108,6 +110,7 @@ namespace ANSCENTER {
|
||||
{
|
||||
try {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
_modelConfig = modelConfig;
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -146,7 +149,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
std::vector<Object> ANSSAM::RunInference(const cv::Mat& input,const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("ANSSAM::RunInference")) return {};
|
||||
|
||||
try {
|
||||
if (!_licenseValid || !_isInitialized || input.empty() ||
|
||||
|
||||
@@ -687,6 +687,7 @@ namespace ANSCENTER
|
||||
std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -746,6 +747,7 @@ namespace ANSCENTER
|
||||
bool ANSSAM3::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -803,6 +805,7 @@ namespace ANSCENTER
|
||||
const std::string& modelFolder, std::string& labelMap)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1010,15 +1013,7 @@ namespace ANSCENTER
|
||||
|
||||
std::vector<Object> ANSSAM3::RunInference(const cv::Mat& input, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid || !_isInitialized) return {};
|
||||
if (!m_promptSet) {
|
||||
_logger.LogError("ANSSAM3::RunInference", "No prompt set", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (input.empty() || input.cols < 10 || input.rows < 10) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSSAM3::RunInference")) return {};
|
||||
try {
|
||||
return Detect(input, camera_id);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTCL::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -152,6 +153,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTCL::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -257,6 +259,7 @@ namespace ANSCENTER
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -360,33 +363,7 @@ namespace ANSCENTER
|
||||
std::vector<Object> TENSORRTCL::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
|
||||
{
|
||||
// Validate state under brief lock
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("TENSORRTCL::RunInference",
|
||||
"Cannot load the TensorRT model. Please check if it exists",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("TENSORRTCL::RunInference",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("TENSORRTCL::RunInference",
|
||||
"Model is not initialized",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 5 || inputImgBGR.rows < 5) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("TENSORRTCL::RunInference")) return {};
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
}
|
||||
@@ -397,28 +374,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<std::vector<Object>> TENSORRTCL::RunInferencesBatch(const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
|
||||
// Validate state under brief lock
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
|
||||
"Cannot load the TensorRT model. Please check if it exists", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("TENSORRTCL::RunInferencesBatch",
|
||||
"Engine not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (inputs.empty()) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("TENSORRTCL::RunInferencesBatch")) return {};
|
||||
try {
|
||||
return DetectObjectsBatch(inputs, camera_id);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSTENSORRTPOSE::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -144,6 +145,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSTENSORRTPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try
|
||||
{
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
@@ -245,6 +247,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSTENSORRTPOSE::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -347,35 +350,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<Object> ANSTENSORRTPOSE::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Validation checks
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInference",
|
||||
"Cannot load the TensorRT model. Please check if it exists",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInference",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInference",
|
||||
"Model is not initialized",
|
||||
__FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("ANSTENSORRTPOSE::RunInference")) return {};
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
}
|
||||
@@ -983,25 +958,7 @@ namespace ANSCENTER
|
||||
std::vector<std::vector<Object>> ANSTENSORRTPOSE::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
|
||||
"Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
|
||||
"Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSTENSORRTPOSE::RunInferencesBatch",
|
||||
"Engine not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputs.empty()) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSTENSORRTPOSE::RunInferencesBatch")) return {};
|
||||
try {
|
||||
return DetectObjectsBatch(inputs, camera_id);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTSEG::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -144,6 +145,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try
|
||||
{
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
@@ -245,6 +247,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTSEG::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -347,27 +350,7 @@ namespace ANSCENTER
|
||||
}
|
||||
std::vector<Object> TENSORRTSEG::RunInference(const cv::Mat& inputImgBGR,const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("TENSORRTSEG::RunInference",
|
||||
"Cannot load TensorRT model", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("TENSORRTSEG::RunInference",
|
||||
"Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("TENSORRTSEG::RunInference",
|
||||
"Model not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("TENSORRTSEG::RunInference")) return {};
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
}
|
||||
@@ -1134,25 +1117,7 @@ namespace ANSCENTER
|
||||
std::vector<std::vector<Object>> TENSORRTSEG::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
|
||||
"Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
|
||||
"Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("TENSORRTSEG::RunInferencesBatch",
|
||||
"Engine not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputs.empty()) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("TENSORRTSEG::RunInferencesBatch")) return {};
|
||||
try {
|
||||
return DetectObjectsBatch(inputs, camera_id);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
_isFixedBatch = false;
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
@@ -151,6 +152,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try
|
||||
{
|
||||
_isFixedBatch = false;
|
||||
@@ -256,6 +258,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool TENSORRTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -364,31 +367,7 @@ namespace ANSCENTER
|
||||
{
|
||||
// Validate state under a brief lock — do NOT hold across DetectObjects so that
|
||||
// the Engine pool can run concurrent inferences on different GPU slots.
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("TENSORRTOD::RunInference",
|
||||
"Cannot load TensorRT model", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("TENSORRTOD::RunInference",
|
||||
"Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("TENSORRTOD::RunInference",
|
||||
"Model not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
} // mutex released here — DetectObjects manages its own locking per phase
|
||||
if (!PreInferenceCheck("TENSORRTOD::RunInference")) return {};
|
||||
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
@@ -401,34 +380,7 @@ namespace ANSCENTER
|
||||
std::vector<std::vector<Object>> TENSORRTOD::RunInferencesBatch(const std::vector<cv::Mat>& inputs, const std::string& camera_id) {
|
||||
// Validate state under a brief lock — do NOT hold across DetectObjectsBatch so that
|
||||
// the Engine pool can serve concurrent batch requests on different GPU slots.
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
// Validate model, license, and initialization
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
|
||||
"Cannot load the TensorRT model. Please check if it exists", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
|
||||
"Initialisation is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Validate inputs
|
||||
if (inputs.empty()) {
|
||||
this->_logger.LogFatal("TENSORRTOD::RunInferenceBatch",
|
||||
"Input images vector is empty", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
} // mutex released here — DetectObjectsBatch manages its own GPU dispatch
|
||||
if (!PreInferenceCheck("TENSORRTOD::RunInferencesBatch")) return {};
|
||||
|
||||
try {
|
||||
if (_isFixedBatch) return ANSODBase::RunInferencesBatch(inputs, camera_id);
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool YOLO12OD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -81,6 +82,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool YOLO12OD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className,modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -153,6 +155,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
bool YOLO12OD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -223,7 +226,7 @@ namespace ANSCENTER {
|
||||
}
|
||||
std::vector<Object> YOLO12OD::RunInference(const cv::Mat& input,const std::string& camera_id)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!PreInferenceCheck("YOLO12OD::RunInference")) return {};
|
||||
try {
|
||||
// Validation
|
||||
if (!_licenseValid) {
|
||||
|
||||
@@ -938,6 +938,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool YOLOOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -1030,6 +1031,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool YOLOOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig, modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1152,6 +1154,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool YOLOOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::Initialize(licenseKey, modelConfig, modelZipFilePath, modelZipPassword, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -1266,18 +1269,7 @@ namespace ANSCENTER
|
||||
return RunInference(input, "CustomCam");
|
||||
}
|
||||
std::vector<Object> YOLOOD::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Early validation - before try block
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogError("YOLOOD::RunInference", "Invalid License", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogError("YOLOOD::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!PreInferenceCheck("YOLOOD::RunInference")) return {};
|
||||
|
||||
if (input.empty() || input.cols < 10 || input.rows < 10) {
|
||||
return {};
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace ANSCENTER
|
||||
|
||||
bool ANSOYOLOV10OVOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -88,6 +89,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSOYOLOV10OVOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -157,6 +159,7 @@ namespace ANSCENTER
|
||||
|
||||
bool ANSOYOLOV10OVOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
std::string openVINOVersion = ov::get_openvino_version().buildNumber;
|
||||
std::cout << "OpenVINO version: " << openVINOVersion << std::endl;
|
||||
@@ -222,18 +225,7 @@ namespace ANSCENTER
|
||||
return RunInference(input, "OpenVINO10Cam");
|
||||
}
|
||||
std::vector<Object> ANSOYOLOV10OVOD::RunInference(const cv::Mat& input, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Validate license and initialization status
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSOYOLOV10OVOD::RunInference", "Invalid License", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSOYOLOV10OVOD::RunInference", "Model is not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSOYOLOV10OVOD::RunInference")) return {};
|
||||
|
||||
// Validate input
|
||||
if (input.empty()) {
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSYOLOV10RTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -154,6 +155,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSYOLOV10RTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className, modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -260,6 +262,7 @@ namespace ANSCENTER
|
||||
bool ANSYOLOV10RTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -362,27 +365,7 @@ namespace ANSCENTER
|
||||
|
||||
std::vector<Object> ANSYOLOV10RTOD::RunInference(const cv::Mat& inputImgBGR, const std::string& camera_id) {
|
||||
// Validate under brief lock
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
|
||||
"Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSYOLOV10RTOD::RunInference",
|
||||
"Initialisation is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (!PreInferenceCheck("ANSYOLOV10RTOD::RunInference")) return {};
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
}
|
||||
@@ -1000,25 +983,7 @@ namespace ANSCENTER
|
||||
std::vector<std::vector<Object>> ANSYOLOV10RTOD::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
|
||||
"Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
|
||||
"Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSYOLOV10RTOD::RunInferencesBatch",
|
||||
"Engine not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputs.empty()) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSYOLOV10RTOD::RunInferencesBatch")) return {};
|
||||
try {
|
||||
return DetectObjectsBatch(inputs, camera_id);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSYOLOV12RTOD::LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModel(modelZipFilePath, modelZipPassword);
|
||||
if (!result) return false;
|
||||
@@ -147,6 +148,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSYOLOV12RTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
bool result = ANSODBase::LoadModelFromFolder(licenseKey, modelConfig,modelName, className,modelFolder, labelMap);
|
||||
if (!result) return false;
|
||||
@@ -248,6 +250,7 @@ namespace ANSCENTER
|
||||
}
|
||||
bool ANSYOLOV12RTOD::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);
|
||||
ModelLoadingGuard mlg(_modelLoading);
|
||||
try {
|
||||
const bool engineAlreadyLoaded = _modelLoadValid && _isInitialized && m_trtEngine != nullptr;
|
||||
_modelLoadValid = false;
|
||||
@@ -343,35 +346,11 @@ namespace ANSCENTER
|
||||
return RunInference(inputImgBGR, "TensorRT12Cam");
|
||||
}
|
||||
std::vector<Object> ANSYOLOV12RTOD::RunInference(const cv::Mat& inputImgBGR, const std::string& camera_id) {
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
|
||||
// Validate model, license, and initialization
|
||||
if (!_modelLoadValid) {
|
||||
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
|
||||
"Cannot load the TensorRT model. Please check if it is exist", __FILE__, __LINE__);
|
||||
if (!PreInferenceCheck("ANSYOLOV12RTOD::RunInference")) return {};
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_licenseValid) {
|
||||
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
|
||||
"Runtime license is not valid or expired. Please contact ANSCENTER", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!_isInitialized) {
|
||||
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference",
|
||||
"Model is not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Validate input
|
||||
if (inputImgBGR.empty() || inputImgBGR.cols < 10 || inputImgBGR.rows < 10) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
return DetectObjects(inputImgBGR, camera_id);
|
||||
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
this->_logger.LogFatal("ANSYOLOV12RTOD::RunInference", e.what(), __FILE__, __LINE__);
|
||||
@@ -919,22 +898,7 @@ namespace ANSCENTER
|
||||
std::vector<std::vector<Object>> ANSYOLOV12RTOD::RunInferencesBatch(
|
||||
const std::vector<cv::Mat>& inputs, const std::string& camera_id)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||
if (!_modelLoadValid) {
|
||||
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Model not loaded", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_licenseValid) {
|
||||
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Invalid license", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (!_isInitialized) {
|
||||
_logger.LogError("ANSYOLOV12RTOD::RunInferencesBatch", "Engine not initialized", __FILE__, __LINE__);
|
||||
return {};
|
||||
}
|
||||
if (inputs.empty()) return {};
|
||||
}
|
||||
if (!PreInferenceCheck("ANSYOLOV12RTOD::RunInferencesBatch")) return {};
|
||||
try {
|
||||
return DetectObjectsBatch(inputs, camera_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user