Initial setup for CLion
This commit is contained in:
247
ANSODEngine/ANSMotionDetector.h
Normal file
247
ANSODEngine/ANSMotionDetector.h
Normal file
@@ -0,0 +1,247 @@
|
||||
#ifndef ANSMOTIONDETECTOR_H
|
||||
#define ANSMOTIONDETECTOR_H
|
||||
#pragma once
|
||||
#include "ANSEngineCommon.h"
|
||||
#include <string>
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <openvino/openvino.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace ANSCENTER
|
||||
{
|
||||
class ANSENGINE_API ANSMOTIONDETECTOR : public ANSODBase
|
||||
{
|
||||
|
||||
protected:
|
||||
struct CameraStats {
|
||||
size_t total_frames_processed = 0;
|
||||
size_t frames_with_movement = 0;
|
||||
size_t frames_rejected_by_temporal_check = 0;
|
||||
size_t control_frames_count = 0;
|
||||
double average_psnr = 0.0;
|
||||
double min_psnr = std::numeric_limits<double>::max();
|
||||
double max_psnr = 0.0;
|
||||
double average_temporal_consistency = 0.0;
|
||||
std::chrono::milliseconds total_processing_time{ 0 };
|
||||
std::chrono::high_resolution_clock::time_point last_movement_time;
|
||||
|
||||
// Reset stats
|
||||
void reset()
|
||||
{
|
||||
total_frames_processed = 0;
|
||||
frames_with_movement = 0;
|
||||
frames_rejected_by_temporal_check = 0;
|
||||
control_frames_count = 0;
|
||||
average_psnr = 0.0;
|
||||
min_psnr = std::numeric_limits<double>::max();
|
||||
max_psnr = 0.0;
|
||||
average_temporal_consistency = 0.0;
|
||||
total_processing_time = std::chrono::milliseconds{ 0 };
|
||||
}
|
||||
};
|
||||
struct CameraData
|
||||
{
|
||||
// Detection state
|
||||
bool movement_detected = false;
|
||||
bool transition_detected = false;
|
||||
size_t next_frame_index = 0;
|
||||
size_t next_key_frame = 0;
|
||||
double most_recent_psnr_score = 0.0;
|
||||
size_t frame_index_with_movement = 0;
|
||||
double max_change_percentage = 15.0;
|
||||
double min_change_percentage = 0.5;
|
||||
std::chrono::high_resolution_clock::time_point movement_last_detected;
|
||||
|
||||
// Control frames storage
|
||||
std::map<size_t, cv::Mat> control_frames;
|
||||
|
||||
// Output data
|
||||
cv::Mat output;
|
||||
cv::Mat mask;
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
|
||||
// Configuration parameters
|
||||
size_t key_frame_frequency = 20;
|
||||
size_t number_of_control_frames = 5; // CHANGED: Reduce from 10 to 5
|
||||
double psnr_threshold = 35;
|
||||
double thumbnail_ratio = 0.1;
|
||||
cv::Size thumbnail_size = cv::Size(0, 0);
|
||||
|
||||
// NEW: Maximum age of control frames to compare (in frames)
|
||||
size_t max_control_frame_age = 20; // Only compare frames within last 100 frames (~5 seconds at 20fps)
|
||||
|
||||
|
||||
// NEW: Sensitivity multiplier (1.0 = normal, 1.2 = more sensitive, 0.8 = less sensitive)
|
||||
double sensitivity_multiplier = 1.1;
|
||||
|
||||
// Mask computation parameters
|
||||
int mask_diff_threshold = 10; // Fixed threshold for difference detection
|
||||
double mask_min_percentage = 0.01; // Min % of frame to be valid movement
|
||||
double mask_max_percentage = 40.0; // Max % of frame (reject as scene change)
|
||||
double min_mask_pixels_percentage = 0.05; // 0.02% of working image
|
||||
|
||||
// Filtering parameters
|
||||
double min_object_area = 1000;
|
||||
int min_object_dimension = 5;
|
||||
int min_object_total_size = 25;
|
||||
|
||||
// Morphology parameters
|
||||
int morphology_iterations = 2;
|
||||
|
||||
// Temporal consistency parameters
|
||||
bool temporal_consistency_enabled = true;
|
||||
double mask_overlap_threshold = 0.1;
|
||||
size_t temporal_history_size = 5;
|
||||
size_t min_consistent_frames = 3;
|
||||
bool location_stability_enabled = true;
|
||||
double max_location_jitter = 30.0;
|
||||
|
||||
// Temporal consistency state
|
||||
std::deque<cv::Mat> mask_history;
|
||||
std::deque<cv::Point> centroid_history;
|
||||
size_t consistent_frame_count = 0;
|
||||
double last_temporal_consistency_score = 0.0;
|
||||
|
||||
// Statistics
|
||||
CameraStats stats;
|
||||
|
||||
// Clear function to release memory
|
||||
void clear()
|
||||
{
|
||||
for (auto& [index, frame] : control_frames)
|
||||
{
|
||||
frame.release();
|
||||
}
|
||||
control_frames.clear();
|
||||
output.release();
|
||||
mask.release();
|
||||
contours.clear();
|
||||
|
||||
// Clear temporal history
|
||||
for (auto& m : mask_history)
|
||||
{
|
||||
m.release();
|
||||
}
|
||||
mask_history.clear();
|
||||
centroid_history.clear();
|
||||
|
||||
// Reset state
|
||||
movement_detected = false;
|
||||
transition_detected = false;
|
||||
most_recent_psnr_score = 0.0;
|
||||
frame_index_with_movement = 0;
|
||||
thumbnail_size = cv::Size(0, 0);
|
||||
consistent_frame_count = 0;
|
||||
last_temporal_consistency_score = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
// Private member functions
|
||||
double psnr(const cv::Mat& src, const cv::Mat& dst);
|
||||
cv::Mat simple_colour_balance(const cv::Mat& src);
|
||||
cv::Rect BoundingBoxFromContour(const std::vector<cv::Point>& contour);
|
||||
void setDynamicPSNRThreshold(CameraData& camera, const cv::Mat& working_image);
|
||||
// Multi-camera data storage
|
||||
std::unordered_map<std::string, CameraData> cameras;
|
||||
mutable std::recursive_mutex cameras_mutex;
|
||||
|
||||
// Helper functions
|
||||
CameraData& getCameraData(const std::string& camera_id);
|
||||
const CameraData* getCameraDataConst(const std::string& camera_id) const;
|
||||
bool cameraExists(const std::string& camera_id) const;
|
||||
|
||||
// Processing helpers
|
||||
cv::Mat computeMovementMask(const cv::Mat& control_frame, const cv::Mat& current_frame,
|
||||
const cv::Size& output_size, int morphology_iterations, const CameraData& camera);
|
||||
std::vector<Object> extractObjectsFromMask(const cv::Mat& mask, const cv::Mat& image,
|
||||
CameraData& camera, const std::string& camera_id);
|
||||
void updateControlFrames(CameraData& camera, size_t frame_index, const cv::Mat& thumbnail);
|
||||
void updateStatistics(CameraData& camera, double psnr, bool movement_detected,
|
||||
std::chrono::milliseconds processing_time);
|
||||
|
||||
// Temporal consistency helpers
|
||||
bool checkTemporalConsistency(CameraData& camera, const cv::Mat& current_mask);
|
||||
double calculateMaskOverlap(const cv::Mat& mask1, const cv::Mat& mask2);
|
||||
cv::Point calculateMaskCentroid(const cv::Mat& mask);
|
||||
double calculateLocationStability(const std::deque<cv::Point>& centroids);
|
||||
void updateTemporalHistory(CameraData& camera, const cv::Mat& mask);
|
||||
|
||||
std::vector<Object> MovementDetectInternal(const std::string& camera_id,const size_t frame_index,const cv::Mat& image,CameraData& camera);
|
||||
// Main detection methods
|
||||
std::vector<Object> MovementDetect(const std::string& camera_id, const cv::Mat& next_image);
|
||||
std::vector<Object> MovementDetect(const std::string& camera_id, const size_t frame_index, const cv::Mat& image);
|
||||
|
||||
// Camera management
|
||||
bool hasCameraData(const std::string& camera_id) const;
|
||||
void removeCamera(const std::string& camera_id);
|
||||
std::vector<std::string> getCameraIds() const;
|
||||
|
||||
// Configuration methods
|
||||
void setThreshold(const std::string& camera_id, double threshold);
|
||||
void setKeyFrameFrequency(const std::string& camera_id, size_t frequency);
|
||||
void setNumberOfControlFrames(const std::string& camera_id, size_t count);
|
||||
void setThumbnailRatio(const std::string& camera_id, double ratio);
|
||||
//void setMaskEnabled(const std::string& camera_id, bool enabled);
|
||||
//void setContoursEnabled(const std::string& camera_id, bool enabled);
|
||||
//void setBboxEnabled(const std::string& camera_id, bool enabled);
|
||||
//void setContourThickness(const std::string& camera_id, int thickness);
|
||||
//void setBboxThickness(const std::string& camera_id, int thickness);
|
||||
void setMinObjectArea(const std::string& camera_id, double area);
|
||||
void setMinObjectSize(const std::string& camera_id, int size);
|
||||
void setMorphologyIterations(const std::string& camera_id, int iterations);
|
||||
|
||||
// Temporal consistency settings
|
||||
void setTemporalConsistency(const std::string& camera_id, bool enabled);
|
||||
void setMaskOverlapThreshold(const std::string& camera_id, double threshold);
|
||||
void setTemporalHistorySize(const std::string& camera_id, size_t size);
|
||||
void setMinConsistentFrames(const std::string& camera_id, size_t frames);
|
||||
void setLocationStabilityEnabled(const std::string& camera_id, bool enabled);
|
||||
void setMaxLocationJitter(const std::string& camera_id, double pixels);
|
||||
|
||||
// Getters for configuration
|
||||
double getThreshold(const std::string& camera_id) const;
|
||||
size_t getKeyFrameFrequency(const std::string& camera_id) const;
|
||||
size_t getNumberOfControlFrames(const std::string& camera_id) const;
|
||||
double getThumbnailRatio(const std::string& camera_id) const;
|
||||
bool isMaskEnabled(const std::string& camera_id) const;
|
||||
bool isContoursEnabled(const std::string& camera_id) const;
|
||||
bool isBboxEnabled(const std::string& camera_id) const;
|
||||
bool isTemporalConsistencyEnabled(const std::string& camera_id) const;
|
||||
|
||||
// State query methods
|
||||
bool isMovementDetected(const std::string& camera_id) const;
|
||||
bool wasTransitionDetected(const std::string& camera_id) const;
|
||||
double getPSNRScore(const std::string& camera_id) const;
|
||||
size_t getFrameIndexWithMovement(const std::string& camera_id) const;
|
||||
std::chrono::milliseconds getTimeSinceLastMovement(const std::string& camera_id) const;
|
||||
size_t getControlFrameCount(const std::string& camera_id) const;
|
||||
size_t getNextFrameIndex(const std::string& camera_id) const;
|
||||
double getTemporalConsistencyScore(const std::string& camera_id) const;
|
||||
|
||||
// Public utility methods
|
||||
bool empty(const std::string& camera_id) const;
|
||||
void clear(const std::string& camera_id);
|
||||
void clearAll();
|
||||
/*cv::Mat getOutput(const std::string& camera_id) const;*/
|
||||
const cv::Mat& getOutput(const std::string& camera_id) const;
|
||||
const cv::Mat getMask(const std::string& camera_id) const;
|
||||
std::vector<std::vector<cv::Point>> getContours(const std::string& camera_id) const;
|
||||
CameraStats getStats(const std::string& camera_id) const;
|
||||
void resetStats(const std::string& camera_id);
|
||||
|
||||
protected:
|
||||
std::string _modelFilePath;
|
||||
public:
|
||||
virtual bool Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) override;
|
||||
virtual bool LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) override;
|
||||
virtual bool LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap)override;
|
||||
virtual bool OptimizeModel(bool fp16, std::string& optimizedModelFolder);
|
||||
std::vector<Object> RunInference(const cv::Mat& input);
|
||||
std::vector<Object> RunInference(const cv::Mat& input, const std::string& camera_id);
|
||||
|
||||
bool Destroy();
|
||||
~ANSMOTIONDETECTOR();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user