Initial commit to add all 3 custom projects
This commit is contained in:
257
ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.cpp
Normal file
257
ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.cpp
Normal 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 {};
|
||||
}
|
||||
33
ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h
Normal file
33
ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h
Normal 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();
|
||||
};
|
||||
60
ANSCustomHelmetDetection/CMakeLists.txt
Normal file
60
ANSCustomHelmetDetection/CMakeLists.txt
Normal 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()
|
||||
23
ANSCustomHelmetDetection/dllmain.cpp
Normal file
23
ANSCustomHelmetDetection/dllmain.cpp
Normal 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();
|
||||
}
|
||||
7
ANSCustomHelmetDetection/framework.h
Normal file
7
ANSCustomHelmetDetection/framework.h
Normal 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>
|
||||
5
ANSCustomHelmetDetection/pch.cpp
Normal file
5
ANSCustomHelmetDetection/pch.cpp
Normal 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.
|
||||
13
ANSCustomHelmetDetection/pch.h
Normal file
13
ANSCustomHelmetDetection/pch.h
Normal 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
|
||||
Reference in New Issue
Block a user