From e009257dfd7229d04476f16dc19993fe43589c6f Mon Sep 17 00:00:00 2001 From: Tuan Nghia Nguyen Date: Mon, 6 Apr 2026 07:11:04 +1000 Subject: [PATCH] Add unitest --- .claude/settings.local.json | 18 ++- .../ANSCustomFireNSmoke.cpp | 18 +-- .../ANSCustomFireNSmoke.h | 4 +- ANSCustomFireNSmokeDetection/CMakeLists.txt | 8 +- .../ANSCustomCodeHelmetDetection.h | 2 +- ANSCustomHelmetDetection/CMakeLists.txt | 8 +- ANSCustomWeaponDetection/CMakeLists.txt | 8 +- CMakeLists.txt | 5 + tests/CMakeLists.txt | 7 +- tests/FireNSmokeDetection/CMakeLists.txt | 71 ++++++---- tests/FireNSmokeDetection/main.cpp | 127 ++++++++++++++++++ tests/HelmetDetection/CMakeLists.txt | 13 -- tests/WeaponDetection/CMakeLists.txt | 13 -- 13 files changed, 225 insertions(+), 77 deletions(-) create mode 100644 tests/FireNSmokeDetection/main.cpp diff --git a/.claude/settings.local.json b/.claude/settings.local.json index e7aec9a..cda4626 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -12,7 +12,23 @@ "Bash(cp \"C:/Projects/ANLS/ANSLIB/ANSCustomFireNSmokeDetection/pch.cpp\" \"C:/Projects/CLionProjects/ANSCustomModels/ANSCustomFireNSmokeDetection/pch.cpp\")", "Read(//c/ANSLibs/opencv/x64/vc17/**)", "Read(//c/ANSLibs/opencv/**)", - "Bash(find C:/ANSLibs -name *.dll -type f)" + "Bash(find C:/ANSLibs -name *.dll -type f)", + "Bash(xargs grep:*)", + "Bash(dumpbin /c/Projects/CLionProjects/ANSCORE/cmake-build-release/bin/ANSLIB.dll /imports)", + "Bash(objdump -p /c/Projects/CLionProjects/ANSCORE/cmake-build-release/bin/ANSLIB.dll)", + "Bash(nm -D /c/Projects/CLionProjects/ANSCORE/cmake-build-release/bin/ANSMOT.dll)", + "Bash(find /c/Projects/ANLS/ANSLIB -type f -name *ANSMOT*)", + "Bash(grep -r \"add_custom_command\\\\|install\\(\" /c/Projects/CLionProjects/ANSCORE --include=CMakeLists.txt --include=*.cmake)", + "Bash(find C:/Projects/CLionProjects/ANSCORE/cmake-build-release/bin -name *.dll -type f)", + "Read(//c/Projects/CLionProjects/ANSCustomModels/**)", + "Bash(dumpbin /EXPORTS C:/ProgramData/ANSCENTER/Shared/ANSODEngine.dll)", + "Bash(dumpbin /DEPENDENTS C:/ProgramData/ANSCENTER/Shared/ANSODEngine.dll)", + "Bash(cmd.exe /c \"dumpbin /DEPENDENTS C:\\\\ProgramData\\\\ANSCENTER\\\\Shared\\\\ANSODEngine.dll\")", + "Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/dumpbin.exe\" /DEPENDENTS \"C:/ProgramData/ANSCENTER/Shared/ANSODEngine.dll\")", + "Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/dumpbin.exe\" //DEPENDENTS ANSODEngine.dll)", + "Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/dumpbin.exe\" //EXPORTS ANSLicensingSystem.dll)", + "Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/dumpbin.exe\" //IMPORTS ANSODEngine.dll)", + "Bash(\"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/dumpbin.exe\" //IMPORTS ANSMOT.dll)" ] } } diff --git a/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.cpp b/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.cpp index 72a68d9..6c6f661 100644 --- a/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.cpp +++ b/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.cpp @@ -461,9 +461,9 @@ bool ANSCustomFS::Initialize(const std::string& modelDirectory, float detectionS _motiondetector = ANSLIBPtr(ANSCENTER::ANSLIB::Create(), &ANSCENTER::ANSLIB::Destroy); - _detectorModelType = 4; // TENSORRT + _detectorModelType = 31; // TENSORRT _detectorDetectionType = 1; // DETECTION - _filterModelType = 4; // TENSORRT + _filterModelType = 31; // TENSORRT _filterDetectionType = 1; // DETECTION _motionModelType = 19; // Motion detection (generic CPU) _motionDetectionType = 1; // DETECTION @@ -472,17 +472,17 @@ bool ANSCustomFS::Initialize(const std::string& modelDirectory, float detectionS engineType = _detector->GetEngineType(); if (engineType == 1) { // NVIDIA GPU: Use TensorRT - _detectorModelType = 4; // TENSORRT + _detectorModelType = 31; // TENSORRT _detectorDetectionType = 1; // DETECTION - _filterModelType = 4; // TENSORRT + _filterModelType = 31; // TENSORRT _filterDetectionType = 1; // DETECTION std::cout << "NVIDIA GPU detected. Using TensorRT" << std::endl; } else { // CPU/Other: Use OpenVINO - _detectorModelType = 17; // OPENVINO + _detectorModelType = 30; // OPENVINO _detectorDetectionType = 1; // DETECTION - _filterModelType = 17; //Yolo v12 + _filterModelType = 30; //Yolo v12 _filterDetectionType = 1; // DETECTION std::cout << "CPU detected. Using OpenVINO and ONNX" << std::endl; @@ -556,7 +556,7 @@ bool ANSCustomFS::Initialize(const std::string& modelDirectory, float detectionS return false; } - // Load motion detector model (background subtraction / frame differencing) + // Load motion detector model (optional — not used in Stage A tracker-based pipeline) float motionScoreThreshold = MOTION_SENSITIVITY; float motionConfThreshold = 0.5f; float motionNMSThreshold = 0.5f; @@ -570,8 +570,8 @@ bool ANSCustomFS::Initialize(const std::string& modelDirectory, float detectionS "", // Empty model directory - motion detector is algorithmic motionDetectorLabels); if (motionResult != 1) { - std::cerr << "ANSCustomFS::Initialize: Failed to load motion detector model." << std::endl; - return false; + std::cerr << "ANSCustomFS::Initialize: Warning - Motion detector not loaded (not required for Stage A)." << std::endl; + // Non-fatal: motion detector is not used in the tracker-based Stage A pipeline } return true; diff --git a/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.h b/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.h index 5f98e50..14d475f 100644 --- a/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.h +++ b/ANSCustomFireNSmokeDetection/ANSCustomFireNSmoke.h @@ -5,7 +5,7 @@ #define RETAINFRAMES 80 #define FILTERFRAMES 10 -//#define FNS_DEBUG +#define FNS_DEBUG class CUSTOM_API ANSCustomFS : public IANSCustomClass { typedef std::pair Range; @@ -33,7 +33,7 @@ class CUSTOM_API ANSCustomFS : public IANSCustomClass private: using ANSLIBPtr = std::unique_ptr; - int engineType{ 0 }; + int engineType{ 0 }; ANSLIBPtr _motiondetector{ nullptr, &ANSCENTER::ANSLIB::Destroy }; ANSLIBPtr _detector{ nullptr, &ANSCENTER::ANSLIB::Destroy }; ANSLIBPtr _filter{ nullptr, &ANSCENTER::ANSLIB::Destroy }; diff --git a/ANSCustomFireNSmokeDetection/CMakeLists.txt b/ANSCustomFireNSmokeDetection/CMakeLists.txt index f4a9cc6..a5701c7 100644 --- a/ANSCustomFireNSmokeDetection/CMakeLists.txt +++ b/ANSCustomFireNSmokeDetection/CMakeLists.txt @@ -30,7 +30,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # ---------- include directories ---------- target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - C:/Projects/ANLS/ANSLIB/ANSLIB + C:/ProgramData/ANSCENTER/Shared # ANSLIB.h + ANSLIB.lib from same location C:/ANSLibs/opencv/include ) @@ -51,10 +51,12 @@ if(MSVC) /W3 # Warning level 3 /sdl # SDL checks /permissive- # Conformance mode - $<$:/O2 /Oi /GL> # Optimize + intrinsics + whole-program opt + /Zi # Generate full debug info (PDB) in all configs + $<$:/O2 /Oi> # Optimize + intrinsics (no /GL — incompatible with debugging) ) target_link_options(${PROJECT_NAME} PRIVATE - $<$:/OPT:REF /OPT:ICF /LTCG> # Optimize refs, COMDAT folding, link-time codegen + /DEBUG # Emit PDB for debugger in all configs + $<$:/OPT:REF /OPT:ICF> # Optimize refs, COMDAT folding (no /LTCG — incompatible with debugging) ) endif() diff --git a/ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h b/ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h index 41f205c..de19974 100644 --- a/ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h +++ b/ANSCustomHelmetDetection/ANSCustomCodeHelmetDetection.h @@ -1,6 +1,6 @@ #include "ANSLIB.h" -//#define FNS_DEBUG +#define FNS_DEBUG class CUSTOM_API ANSCustomHMD : public IANSCustomClass { private: diff --git a/ANSCustomHelmetDetection/CMakeLists.txt b/ANSCustomHelmetDetection/CMakeLists.txt index 2299646..27428d6 100644 --- a/ANSCustomHelmetDetection/CMakeLists.txt +++ b/ANSCustomHelmetDetection/CMakeLists.txt @@ -30,7 +30,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # ---------- include directories ---------- target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - C:/Projects/ANLS/ANSLIB/ANSLIB + C:/ProgramData/ANSCENTER/Shared # ANSLIB.h + ANSLIB.lib from same location C:/ANSLibs/opencv/include ) @@ -51,10 +51,12 @@ if(MSVC) /W3 # Warning level 3 /sdl # SDL checks /permissive- # Conformance mode - $<$:/O2 /Oi /GL> # Optimize + intrinsics + whole-program opt + /Zi # Generate full debug info (PDB) in all configs + $<$:/O2 /Oi> # Optimize + intrinsics (no /GL — incompatible with debugging) ) target_link_options(${PROJECT_NAME} PRIVATE - $<$:/OPT:REF /OPT:ICF /LTCG> # Optimize refs, COMDAT folding, link-time codegen + /DEBUG # Emit PDB for debugger in all configs + $<$:/OPT:REF /OPT:ICF> # Optimize refs, COMDAT folding (no /LTCG — incompatible with debugging) ) endif() diff --git a/ANSCustomWeaponDetection/CMakeLists.txt b/ANSCustomWeaponDetection/CMakeLists.txt index 539c749..1b169c5 100644 --- a/ANSCustomWeaponDetection/CMakeLists.txt +++ b/ANSCustomWeaponDetection/CMakeLists.txt @@ -30,7 +30,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # ---------- include directories ---------- target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - C:/Projects/ANLS/ANSLIB/ANSLIB + C:/ProgramData/ANSCENTER/Shared # ANSLIB.h + ANSLIB.lib from same location C:/ANSLibs/opencv/include ) @@ -51,10 +51,12 @@ if(MSVC) /W3 # Warning level 3 /sdl # SDL checks /permissive- # Conformance mode - $<$:/O2 /Oi /GL> # Optimize + intrinsics + whole-program opt + /Zi # Generate full debug info (PDB) in all configs + $<$:/O2 /Oi> # Optimize + intrinsics (no /GL — incompatible with debugging) ) target_link_options(${PROJECT_NAME} PRIVATE - $<$:/OPT:REF /OPT:ICF /LTCG> # Optimize refs, COMDAT folding, link-time codegen + /DEBUG # Emit PDB for debugger in all configs + $<$:/OPT:REF /OPT:ICF> # Optimize refs, COMDAT folding (no /LTCG — incompatible with debugging) ) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 4defbc5..7c065a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,11 @@ project(ANSCustomModels LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Place all build outputs (.exe and .dll) in the same directory so our own +# custom model DLLs are found next to the test/demo executables at runtime. +# External DLLs (ANSLIB, OpenCV, etc.) are loaded from C:\ProgramData\ANSCENTER\Shared. +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + add_subdirectory(ANSCustomHelmetDetection) add_subdirectory(ANSCustomFireNSmokeDetection) add_subdirectory(ANSCustomWeaponDetection) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71e2ec6..e428bae 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,18 +13,13 @@ FetchContent_MakeAvailable(googletest) enable_testing() # ---------- Common paths (propagated to sub-projects via variables) ---------- -set(ANSLIB_INCLUDE_DIR "C:/Projects/ANLS/ANSLIB/ANSLIB" CACHE PATH "") +set(ANSLIB_INCLUDE_DIR "C:/ProgramData/ANSCENTER/Shared" CACHE PATH "") set(OPENCV_INCLUDE_DIR "C:/ANSLibs/opencv/include" CACHE PATH "") set(ANSLIB_LIB_DIR "C:/ProgramData/ANSCENTER/Shared" CACHE PATH "") set(OPENCV_LIB_DIR "C:/ANSLibs/opencv/x64/vc17/lib" CACHE PATH "") set(OPENCV_BIN_DIR "C:/ProgramData/ANSCENTER/Shared" CACHE PATH "") set(TEST_COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "") -# ---------- Place all test .exe files alongside the DLLs they need ---------- -# This ensures custom model DLLs (built by sibling projects) land in the same -# directory as the test executables so Windows can find them at runtime. -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "" FORCE) - # ---------- Sub-project test executables ---------- add_subdirectory(FireNSmokeDetection) add_subdirectory(HelmetDetection) diff --git a/tests/FireNSmokeDetection/CMakeLists.txt b/tests/FireNSmokeDetection/CMakeLists.txt index dc66467..11b07e4 100644 --- a/tests/FireNSmokeDetection/CMakeLists.txt +++ b/tests/FireNSmokeDetection/CMakeLists.txt @@ -1,25 +1,37 @@ project(FireNSmokeDetection_Tests LANGUAGES CXX) -add_executable(${PROJECT_NAME} - FireNSmokeDetectionTest.cpp +# ============================================================================ +# Common settings shared by both targets +# ============================================================================ +set(COMMON_INCLUDES + ${TEST_COMMON_DIR} + ${ANSLIB_INCLUDE_DIR} + ${OPENCV_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/ANSCustomFireNSmokeDetection ) -target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) - -target_compile_definitions(${PROJECT_NAME} PRIVATE +set(COMMON_DEFS WIN32_LEAN_AND_MEAN NOMINMAX $<$:_DEBUG> $<$:NDEBUG> ) -target_include_directories(${PROJECT_NAME} PRIVATE - ${TEST_COMMON_DIR} - ${ANSLIB_INCLUDE_DIR} - ${OPENCV_INCLUDE_DIR} - ${CMAKE_SOURCE_DIR}/ANSCustomFireNSmokeDetection +# All runtime DLLs (ANSLIB, ANSODEngine, ANSLicensingSystem, ANSMOT, OpenCV, etc.) +# live in C:\ProgramData\ANSCENTER\Shared — same directory as the .lib files. +# Windows resolves them via the standard DLL search order. + +# ============================================================================ +# 1. Google Test unit/integration test executable +# ============================================================================ +add_executable(${PROJECT_NAME} + FireNSmokeDetectionTest.cpp ) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) +target_compile_definitions(${PROJECT_NAME} PRIVATE ${COMMON_DEFS}) +target_include_directories(${PROJECT_NAME} PRIVATE ${COMMON_INCLUDES}) + target_link_directories(${PROJECT_NAME} PRIVATE ${ANSLIB_LIB_DIR} ${OPENCV_LIB_DIR} @@ -37,18 +49,31 @@ if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W3 /sdl /permissive-) endif() -# Copy required DLLs next to the test executable so Windows can find them -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - # ANSLIB.dll - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${ANSLIB_LIB_DIR}/ANSLIB.dll" - "$" - # OpenCV DLL - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${OPENCV_BIN_DIR}/opencv_world4130.dll" - "$" - COMMENT "Copying runtime DLLs for ${PROJECT_NAME}" -) - include(GoogleTest) gtest_discover_tests(${PROJECT_NAME} DISCOVERY_MODE PRE_TEST) + +# ============================================================================ +# 2. Interactive video demo executable (visual verification with OpenCV window) +# ============================================================================ +add_executable(FireNSmokeDetection_Demo + main.cpp +) + +target_compile_features(FireNSmokeDetection_Demo PRIVATE cxx_std_17) +target_compile_definitions(FireNSmokeDetection_Demo PRIVATE ${COMMON_DEFS}) +target_include_directories(FireNSmokeDetection_Demo PRIVATE ${COMMON_INCLUDES}) + +target_link_directories(FireNSmokeDetection_Demo PRIVATE + ${ANSLIB_LIB_DIR} + ${OPENCV_LIB_DIR} +) + +target_link_libraries(FireNSmokeDetection_Demo PRIVATE + ANSLIB + opencv_world4130 + ANSCustomFireNSmokeDetection +) + +if(MSVC) + target_compile_options(FireNSmokeDetection_Demo PRIVATE /W3 /sdl /permissive-) +endif() diff --git a/tests/FireNSmokeDetection/main.cpp b/tests/FireNSmokeDetection/main.cpp new file mode 100644 index 0000000..0513094 --- /dev/null +++ b/tests/FireNSmokeDetection/main.cpp @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include "ANSCustomFireNSmoke.h" + +int FireNSmokeDetection() { + std::string modelDirectory = "C:\\Projects\\ANSVIS\\Models\\ANS_FireSmoke_v3.0"; + std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\ANSFireFull.mp4";// passed + //std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\ANSVIS_Issues\\FGFire.mp4";// passed + //std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\HFire1.mp4"; // passed + //std::string videoFilePath = "E:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\HFire3.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\FireTest\\road.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\FireTest\\video_20.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\FireTest\\BCA1.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\E112 v4-1.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\E112Full.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\SimFire.mp4"; // passed + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\BCA3.mp4"; // pass (smoke issue) + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\E112 fire.mp4"; // pass + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\e112 v3-2.mp4"; // pass + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\e112 v3-3.mp4"; // pass + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\e112 v3-4.mp4"; // pass + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\E112 v4-1.mp4"; // pass + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\Fire25m.mp4"; // passed (fire is too small and low resolution cam) + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\Failed\\fire 25cm 480p.mp4"; // passed (fire is too small and low resolution cam) + + //std::string videoFilePath = "C:\\Programs\\FireTest\\BCA2.mp4"; // failed (fire is too small and low resolution cam) + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\fire4.mp4"; // failed (smoke issue, too low resolution) + //std::string videoFilePath = "C:\\Programs\\FireTest\\HFire2.mp4"; // failed as camera is moving + //std::string videoFilePath = "C:\\Programs\\DemoAssets\\Videos\\FireNSmoke\\E112 v4-2.mp4"; // failed white smoke low resolution cam + + std::vector classes; + ANSCustomFS detector; + std::string labelMap; + + // Optimize model + bool optimize = detector.OptimizeModel(true); + + // Initialize the detector and parse the label map + detector.Initialize(modelDirectory, 0.5, labelMap); + std::stringstream ss(labelMap); + while (ss.good()) { + std::string substr; + getline(ss, substr, ','); + classes.push_back(substr); + } + + // Open video capture + cv::VideoCapture capture(videoFilePath); + if (!capture.isOpened()) { + std::cerr << "Error: Unable to open video file!" << std::endl; + return -1; + } + + // Get the original video dimensions + int originalWidth = static_cast(capture.get(cv::CAP_PROP_FRAME_WIDTH)); + int originalHeight = static_cast(capture.get(cv::CAP_PROP_FRAME_HEIGHT)); + double aspectRatio = static_cast(originalWidth) / originalHeight; + + // Create a resizable window + const std::string windowName = "ANS Fire Detection"; + cv::namedWindow(windowName, cv::WINDOW_NORMAL); + + while (true) { + cv::Mat frame; + if (!capture.read(frame)) { + break; + } + + // Run inference on the frame + std::vector customObjects; + auto start = std::chrono::system_clock::now(); + customObjects = detector.RunInference(frame); + auto end = std::chrono::system_clock::now(); + auto elapsed = std::chrono::duration_cast(end - start); + printf("Time = %lld ms\n", static_cast(elapsed.count())); + + // Draw detection results on the frame + if (!customObjects.empty()) { + for (const auto& obj : customObjects) { + cv::rectangle(frame, cv::Rect(obj.box.x, obj.box.y, obj.box.width, obj.box.height), cv::Scalar(123, 255, 123), 2); + cv::putText(frame, + cv::format("%s:%d:%.2f", classes[obj.classId].c_str(), obj.classId, obj.confidence), + cv::Point(obj.box.x, obj.box.y - 5), + cv::FONT_HERSHEY_SIMPLEX, + 0.6, + cv::Scalar(0, 0, 255), + 1, + cv::LINE_AA); + } + } + + // Handle resizing and maintain aspect ratio + int currentWidth = static_cast(cv::getWindowProperty(windowName, cv::WND_PROP_AUTOSIZE)); + int currentHeight = static_cast(cv::getWindowProperty(windowName, cv::WND_PROP_AUTOSIZE)); + + if (currentWidth > 0 && currentHeight > 0) { + int newWidth = currentWidth; + int newHeight = static_cast(newWidth / aspectRatio); + if (newHeight > currentHeight) { + newHeight = currentHeight; + newWidth = static_cast(newHeight * aspectRatio); + } + cv::resize(frame, frame, cv::Size(newWidth, newHeight)); + } + + // Display the frame + cv::imshow(windowName, frame); + + // Exit the loop if 'esc' key is pressed + if (cv::waitKey(30) == 27) { + break; + } + } + + // Clean up + capture.release(); + cv::destroyAllWindows(); + return 0; +} + +int main() { + return FireNSmokeDetection(); +} diff --git a/tests/HelmetDetection/CMakeLists.txt b/tests/HelmetDetection/CMakeLists.txt index 8f1c496..1d62b57 100644 --- a/tests/HelmetDetection/CMakeLists.txt +++ b/tests/HelmetDetection/CMakeLists.txt @@ -37,18 +37,5 @@ if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W3 /sdl /permissive-) endif() -# Copy required DLLs next to the test executable so Windows can find them -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - # ANSLIB.dll - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${ANSLIB_LIB_DIR}/ANSLIB.dll" - "$" - # OpenCV DLL - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${OPENCV_BIN_DIR}/opencv_world4130.dll" - "$" - COMMENT "Copying runtime DLLs for ${PROJECT_NAME}" -) - include(GoogleTest) gtest_discover_tests(${PROJECT_NAME} DISCOVERY_MODE PRE_TEST) diff --git a/tests/WeaponDetection/CMakeLists.txt b/tests/WeaponDetection/CMakeLists.txt index f88259b..7ea0b4c 100644 --- a/tests/WeaponDetection/CMakeLists.txt +++ b/tests/WeaponDetection/CMakeLists.txt @@ -37,18 +37,5 @@ if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W3 /sdl /permissive-) endif() -# Copy required DLLs next to the test executable so Windows can find them -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - # ANSLIB.dll - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${ANSLIB_LIB_DIR}/ANSLIB.dll" - "$" - # OpenCV DLL - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${OPENCV_BIN_DIR}/opencv_world4130.dll" - "$" - COMMENT "Copying runtime DLLs for ${PROJECT_NAME}" -) - include(GoogleTest) gtest_discover_tests(${PROJECT_NAME} DISCOVERY_MODE PRE_TEST)