Initial commit to add all 3 custom projects

This commit is contained in:
2026-03-30 21:43:47 +11:00
commit fed40b0c90
29 changed files with 3127 additions and 0 deletions

View File

@@ -0,0 +1,257 @@
#include "ANSCustomCodeHelmetDetection.h"
static std::string toUpperCase(const std::string& input) {
std::string result = input;
std::transform(result.begin(), result.end(), result.begin(),
[](unsigned char c) { return std::toupper(c); });
return result;
}
ANSCustomHMD::ANSCustomHMD() {
_isInitialized = false;
_readROIs = false;
}
ANSCustomHMD::~ANSCustomHMD() {
Destroy();
}
bool ANSCustomHMD::Destroy() {
try {
_detector.reset();
_classifier.reset();
_isInitialized = false;
return true;
}
catch (...) {
return false;
}
}
bool ANSCustomHMD::OptimizeModel(bool fp16) {
try {
if (!_detector || !_classifier) return false;
int detectorResult = _detector->Optimize(fp16);
int classifierResult = _classifier->Optimize(fp16);
if ((detectorResult != 1) || (classifierResult != 1)) return false;
else return true;
}
catch (...) {
return false;
}
}
bool ANSCustomHMD::Initialize(const std::string& modelDirectory, float detectionScoreThreshold, std::string& labelMap) {
try {
_modelDirectory = modelDirectory;
_detectionScoreThreshold = detectionScoreThreshold;
_isInitialized = false;
// Create model instances using factory pattern (ABI-safe)
_detector = ANSLIBPtr(ANSCENTER::ANSLIB::Create(), &ANSCENTER::ANSLIB::Destroy);
_classifier = ANSLIBPtr(ANSCENTER::ANSLIB::Create(), &ANSCENTER::ANSLIB::Destroy);
// NVIDIA GPU: Use TensorRT
_detectorModelType = 31; // TENSORRT
_detectorDetectionType = 1; // DETECTION
_classifierModelType = 31; // TENSORRT
_classifierDetectionType = 0; // CLASSIFICATION
//Check the hardware type
engineType = _detector->GetEngineType();
if (engineType == 1) {
// NVIDIA GPU: Use TensorRT
_detectorModelType = 31; // TENSORRT
_detectorDetectionType = 1; // DETECTION
_classifierModelType = 31; // TENSORRT
_classifierDetectionType = 0; // CLASSIFICATION
std::cout << "NVIDIA GPU detected. Using TensorRT" << std::endl;
}
else {
// CPU/Other: Use YOLO
_detectorModelType = 3; // YOLOV8/YOLOV11
_detectorDetectionType = 1; // DETECTION
_classifierModelType = 20; // ANSONNXCL
_classifierDetectionType = 0; // CLASSIFICATION
std::cout << "CPU detected. Using YOLO/ANSONNXCL" << std::endl;
}
if (_detectionScoreThreshold < 0.25f) _detectionScoreThreshold = 0.25f;
// classId: 0=license plate, 1=motorcyclist, 2=helmet, 3=no_helmet
labelMap = "license plate,motorcyclist,helmet,no_helmet";
#ifdef FNS_DEBUG
this->_loadEngineOnCreate = true;
#endif
int loadEngineOnCreation = _loadEngineOnCreate ? 1 : 0;
int autoEngineDetection = 1;
std::string licenseKey = "";
// Load detector model
float detScoreThreshold = _detectionScoreThreshold;
float detConfThreshold = 0.5f;
float detNMSThreshold = 0.5f;
std::string detLabelMap;
int detResult = _detector->LoadModelFromFolder(
licenseKey.c_str(),
"detector", "detector.names",
detScoreThreshold, detConfThreshold, detNMSThreshold,
autoEngineDetection,
_detectorModelType, _detectorDetectionType,
loadEngineOnCreation,
modelDirectory.c_str(),
detLabelMap);
if (detResult != 1) {
std::cerr << "ANSCustomHMD::Initialize: Failed to load detector model." << std::endl;
return false;
}
// Load classifier model
float clsScoreThreshold = 0.25f;
float clsConfThreshold = 0.5f;
float clsNMSThreshold = 0.5f;
int clsResult = _classifier->LoadModelFromFolder(
licenseKey.c_str(),
"classifier", "classifier.names",
clsScoreThreshold, clsConfThreshold, clsNMSThreshold,
autoEngineDetection,
_classifierModelType, _classifierDetectionType,
loadEngineOnCreation,
modelDirectory.c_str(),
_classifierLabels);
if (clsResult != 1) {
std::cerr << "ANSCustomHMD::Initialize: Failed to load classifier model." << std::endl;
return false;
}
_isInitialized = true;
return true;
}
catch (const std::exception& e) {
std::cerr << "ANSCustomHMD::Initialize: Exception: " << e.what() << std::endl;
return false;
}
catch (...) {
std::cerr << "ANSCustomHMD::Initialize: Unknown exception." << std::endl;
return false;
}
}
bool ANSCustomHMD::ConfigureParameters(CustomParams& param) {
param.ROI_Config.clear();
param.ROI_Options.clear();
param.Parameters.clear();
param.ROI_Values.clear();
return true;
}
std::vector<CustomObject> ANSCustomHMD::RunInference(const cv::Mat& input) {
return RunInference(input, "CustomCam");
}
std::vector<CustomObject> ANSCustomHMD::RunInference(const cv::Mat& input, const std::string& camera_id) {
std::lock_guard<std::recursive_mutex> lock(_mutex);
if (!_isInitialized || !_detector) {
return {};
}
if (input.empty() || input.cols < 10 || input.rows < 10) {
return {};
}
try {
// One-time parameter reading
if (!_readROIs) {
for (const auto& param : _params.Parameters) {
if (param.Name.find("ALPR") != std::string::npos) {
std::string paramValue = toUpperCase(param.Value);
// ALPR feature currently disabled
}
}
_readROIs = true;
}
// Run object detection
std::vector<ANSCENTER::Object> detectionResults;
_detector->RunInference(input, camera_id.c_str(), detectionResults);
if (detectionResults.empty()) {
return {};
}
std::vector<CustomObject> results;
results.reserve(detectionResults.size());
const cv::Rect frameBounds(0, 0, input.cols, input.rows);
const float scoreThreshold = _detectionScoreThreshold;
for (const auto& obj : detectionResults) {
if (obj.confidence < scoreThreshold) {
continue;
}
CustomObject customObject;
customObject.confidence = obj.confidence;
customObject.box = obj.box;
customObject.cameraId = camera_id;
switch (obj.classId) {
case 0: { // License plate
customObject.classId = 0;
customObject.className = "license plate";
customObject.extraInfo = "license plate";
results.push_back(std::move(customObject));
break;
}
case 1: { // Motorcycle
customObject.classId = 1;
customObject.className = "motorcyclist";
results.push_back(std::move(customObject));
break;
}
case 2: // Helmet
case 3: { // No helmet - classify to confirm
// Validate bounding box
if ((obj.box & frameBounds) != obj.box) {
continue;
}
if (!_classifier) {
continue;
}
cv::Mat croppedImage = input(obj.box);
std::vector<ANSCENTER::Object> classifierResults;
_classifier->RunInference(croppedImage, camera_id.c_str(), classifierResults);
if (classifierResults.empty()) {
continue;
}
const bool isNoHelmet = (classifierResults[0].classId == 1);
customObject.classId = isNoHelmet ? 3 : 2;
customObject.className = isNoHelmet ? "no_helmet" : "helmet";
results.push_back(std::move(customObject));
break;
}
default:
break;
}
}
return results;
}
catch (const std::exception& e) {
std::cerr << "ANSCustomHMD::RunInference: Exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "ANSCustomHMD::RunInference: Unknown exception." << std::endl;
}
return {};
}

View File

@@ -0,0 +1,33 @@
#include "ANSLIB.h"
//#define FNS_DEBUG
class CUSTOM_API ANSCustomHMD : public IANSCustomClass
{
private:
using ANSLIBPtr = std::unique_ptr<ANSCENTER::ANSLIB, decltype(&ANSCENTER::ANSLIB::Destroy)>;
std::recursive_mutex _mutex;
int engineType{ 0 };
ANSLIBPtr _detector{ nullptr, &ANSCENTER::ANSLIB::Destroy };
ANSLIBPtr _classifier{ nullptr, &ANSCENTER::ANSLIB::Destroy };
// ----- Model config -----
int _detectorModelType;
int _detectorDetectionType;
int _classifierModelType;
int _classifierDetectionType;
std::string _classifierLabels;
bool _isInitialized{ false };
bool _readROIs{ false };
public:
bool Initialize(const std::string& modelDiretory, float detectionScoreThreshold, std::string& labelMap) override;
bool OptimizeModel(bool fp16) override;
bool ConfigureParameters(CustomParams& param) override;
std::vector<CustomObject> RunInference(const cv::Mat& input) override;
std::vector<CustomObject> RunInference(const cv::Mat& input, const std::string& camera_id) override;
bool Destroy() override;
ANSCustomHMD();
~ANSCustomHMD();
};

View File

@@ -0,0 +1,60 @@
project(ANSCustomHelmetDetection LANGUAGES CXX)
# ---------- sources ----------
set(SOURCES
ANSCustomCodeHelmetDetection.cpp
dllmain.cpp
pch.cpp
)
set(HEADERS
ANSCustomCodeHelmetDetection.h
framework.h
pch.h
)
# ---------- shared library (DLL) ----------
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
# ---------- preprocessor definitions ----------
target_compile_definitions(${PROJECT_NAME} PRIVATE
ANSCUSTOMHELMETDETECTION_EXPORTS
_WINDOWS
_USRDLL
WIN32_LEAN_AND_MEAN
NOMINMAX
$<$<CONFIG:Debug>:_DEBUG>
$<$<CONFIG:Release>:NDEBUG>
)
# ---------- include directories ----------
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
C:/Projects/ANLS/ANSLIB/ANSLIB
C:/ANSLibs/opencv/include
)
# ---------- library directories & linking ----------
target_link_directories(${PROJECT_NAME} PRIVATE
C:/ProgramData/ANSCENTER/Shared
C:/ANSLibs/opencv/x64/vc17/lib
)
target_link_libraries(${PROJECT_NAME} PRIVATE
ANSLIB
opencv_world4130
)
# ---------- compiler options (MSVC) ----------
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE
/W3 # Warning level 3
/sdl # SDL checks
/permissive- # Conformance mode
$<$<CONFIG:Release>:/O2 /Oi /GL> # Optimize + intrinsics + whole-program opt
)
target_link_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Release>:/OPT:REF /OPT:ICF /LTCG> # Optimize refs, COMDAT folding, link-time codegen
)
endif()

View File

@@ -0,0 +1,23 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "ANSCustomCodeHelmetDetection.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// expose the class to the outside world
extern "C" __declspec(dllexport) IANSCustomClass* Create() {
return new ANSCustomHMD();
}

View File

@@ -0,0 +1,7 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define NOMINMAX // Prevent windows.h from defining min/max macros
// which break std::min / std::max (C2589)
// Windows Header Files
#include <windows.h>

View File

@@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@@ -0,0 +1,13 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#endif //PCH_H