#include "ANSLIB.h" #include #include #define RETAINFRAMES 80 #define FILTERFRAMES 10 //#define FNS_DEBUG class CUSTOM_API ANSCustomFS : public IANSCustomClass { typedef std::pair Range; struct ImageSection { cv::Rect region; int priority; ImageSection(const cv::Rect& r) : region(r), priority(0) {} }; private: using ANSLIBPtr = std::unique_ptr; int engineType{ 0 }; ANSLIBPtr _motiondetector{ nullptr, &ANSCENTER::ANSLIB::Destroy }; ANSLIBPtr _detector{ nullptr, &ANSCENTER::ANSLIB::Destroy }; ANSLIBPtr _filter{ nullptr, &ANSCENTER::ANSLIB::Destroy }; std::recursive_mutex _mutex; cv::Rect _detectedArea; cv::Rect _previousDetectedArea; int _retainDetectedArea{ 0 }; bool _isFireNSmokeDetected{ false }; float _detectionScoreThreshold{ 0.5 }; std::vector _frameHistory; std::deque _frameQueue; std::string _filterLabels; int _realFireCheck{ 0 }; bool _isRealFireFrame{ false }; double _hsvThreshold; std::vector _smoke_colour; std::vector _fire_colour; // ----- Model config ----- int _detectorModelType; int _detectorDetectionType; int _filterModelType; int _filterDetectionType; int _motionModelType; int _motionDetectionType; // Add these constants at class level int MIN_ROI_SIZE = 50; float SMOKE_CONFIDENCE_THRESHOLD = 0.7f; float DETECTION_CONFIDENCE_THRESHOLD = 0.5f; float MAX_AREA_OVERLAP = 0.5f; int MAX_MOTION_TRACKING = 10; int FILTER_VERIFICATION_FRAMES = 10; int MIN_IMAGE_SIZE = 10; float INCLUSIVE_IOU_THRESHOLD = 0.001f; float MOTION_SENSITIVITY = 0.5f; // Excluded filter class IDs const std::unordered_set EXCLUDED_FILTER_CLASSES = { 13, // bench 59, // bed 60, // dining table 68, // microwave 69, // oven 70 // toaster }; cv::Size previousImageSize = cv::Size(0, 0); std::vector cachedSections; int _currentPriority{ 0 }; bool _readROIs{ false }; std::vector _exclusiveROIs; float _smokeDetetectionThreshold{ 0 }; float _motionSpecificity{ 0 }; cv::Rect GenerateMinimumSquareBoundingBox(const std::vector& detectedObjects, int minSize = 640); void UpdateNoDetectionCondition(); bool detectStaticFire(std::deque& frameQueue); bool detectScreenFlicker(const std::vector& frames); bool detectReflection(const cv::Mat& frame); bool MajorityColourInFrame(cv::Mat frame, Range range, float area_threshold); bool MajorityColourInFrame(cv::Mat frame, std::vector ranges, float area_threshold); bool DetectFireNSmokeColourInFrame(const cv::Mat& frame, const cv::Rect& bBox, const std::vector& ranges, float area_threshold); bool IsFireDetected(const cv::Mat image, const cv::Rect bBox); bool IsSmokeDetected(const cv::Mat image, const cv::Rect bBox); float calculateIoU(const cv::Rect& box1, const cv::Rect& box2); bool IsOverlapping(const ANSCENTER::Object& obj, const std::vector& objectList, float iouThreshold = 0.5); bool IsOverlapping(const ANSCENTER::Object& obj, const std::vector& objectList, float iouThreshold = 0.5); bool IsROIOverlapping(const cv::Rect& obj, const std::vector& objectList, float iouThreshold = 0.5); bool IsDetectedAreaValid(const cv::Rect& area) const; bool IsFireOrSmoke(int classId, float confidence) const; bool ValidateMotionCorrelation(const std::vector& fireNSmokeRects) const; void UpdatePositiveDetection(); void ResetDetectedArea(); void UpdatePriorityRegion(const cv::Mat& frame); int CalculateOptimalCropSize(const cv::Mat& frame) const; void RefineDetectedArea(const cv::Mat& frame, const ANSCENTER::Object& detection); std::vector ConvertToCustomObjects(const std::vector& objects); void ResetDetectionState(); void GetModelParameters(); std::vector ProcessExistingDetectedArea(const cv::Mat& frame, const std::string& camera_id, cv::Mat& draw); bool ProcessValidDetection(const cv::Mat& frame, const std::string& camera_id, cv::Mat& draw, ANSCENTER::Object& detectedObj, std::vector& output); void AddConfirmedDetection(ANSCENTER::Object& detectedObj, std::vector& output); #ifdef FNS_DEBUG void DisplayDebugFrame(cv::Mat& draw) { cv::resize(draw, draw, cv::Size(1920, (1920 * draw.rows) / draw.cols)); cv::imshow("Combined Detected Areas", draw); cv::waitKey(1); } #endif // Function to separate screen size double calculateDistanceToCenter(const cv::Point& center, const cv::Rect& rect); std::vector divideImage(const cv::Mat& image); int getHighestPriorityRegion(); int getLowestPriorityRegion(); cv::Rect getRegionByPriority(int priority); std::vector ProcessExistingDetectedArea( const cv::Mat& frame, const std::string& camera_id, const std::vector& fireNSmokeRects, cv::Mat& draw); bool ProcessDetectedObject( const cv::Mat& frame, ANSCENTER::Object& detectedObj, const std::string& camera_id, const std::vector& fireNSmokeRects, std::vector& output, cv::Mat& draw); bool ValidateWithFilter( const cv::Mat& frame, const ANSCENTER::Object& detectedObj, const std::string& camera_id, std::vector& output, cv::Mat& draw); std::vector FindNewDetectedArea( const cv::Mat& frame, const std::string& camera_id, cv::Mat& draw); std::vector FindMovementObjects( const cv::Mat& frame, const std::string& camera_id, cv::Mat& draw); std::vector FindExcludedObjects( const cv::Mat& frame, const std::string& camera_id, cv::Mat& draw); 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 RunInference(const cv::Mat& input) override; std::vector RunInference(const cv::Mat& input, const std::string& camera_id) override; bool Destroy() override; ANSCustomFS(); ~ANSCustomFS(); };