268 lines
8.2 KiB
Markdown
268 lines
8.2 KiB
Markdown
# Frame Hook System
|
|
|
|
## Overview
|
|
|
|
The Frame Hook System provides a flexible and extensible mechanism for processing video frames at various stages in the meteor detection pipeline. It allows for modular frame processing capabilities such as overlay addition, filtering, enhancement, and analysis without modifying the core detection pipeline.
|
|
|
|
## Purpose
|
|
|
|
This hook-based architecture offers several key benefits:
|
|
|
|
1. **Modularity**: New frame processing capabilities can be added without modifying existing code
|
|
2. **Configurability**: Individual hooks can be enabled or disabled as needed
|
|
3. **Reusability**: Common frame processing tasks can be encapsulated and reused
|
|
4. **Prioritization**: Hooks can be ordered to ensure correct processing sequence
|
|
5. **Extensibility**: Third-party hooks can be easily integrated
|
|
|
|
## Core Components
|
|
|
|
### FrameHook Trait
|
|
|
|
The foundation of the hook system is the `FrameHook` trait, defined in `src/hooks/mod.rs`:
|
|
|
|
```rust
|
|
pub trait FrameHook: Send + Sync {
|
|
fn process_frame(&mut self, frame: &mut core::Mat, timestamp: DateTime<Utc>) -> Result<()>;
|
|
fn get_id(&self) -> &str;
|
|
fn get_name(&self) -> &str;
|
|
fn get_description(&self) -> &str;
|
|
fn is_enabled(&self) -> bool;
|
|
fn set_enabled(&mut self, enabled: bool);
|
|
}
|
|
```
|
|
|
|
This trait defines the essential capabilities that all hooks must implement:
|
|
|
|
- **Processing Function**: The `process_frame` method receives a frame and applies transformations
|
|
- **Identification**: Methods to get the hook's ID, name, and description
|
|
- **State Management**: Methods to check and change the hook's enabled state
|
|
|
|
### HookManager
|
|
|
|
The `HookManager` class manages a collection of hooks and is responsible for:
|
|
|
|
- Registering new hooks
|
|
- Removing hooks
|
|
- Executing hooks in sequence on frames
|
|
- Providing access to hooks for configuration
|
|
|
|
```rust
|
|
pub struct HookManager {
|
|
hooks: Vec<SharedFrameHook>,
|
|
}
|
|
```
|
|
|
|
The manager maintains a vector of thread-safe hook references (`SharedFrameHook`) to allow concurrent access.
|
|
|
|
### BasicFrameHook
|
|
|
|
For simple use cases, the `BasicFrameHook` implementation provides a convenient way to create hooks with closures:
|
|
|
|
```rust
|
|
pub struct BasicFrameHook {
|
|
id: String,
|
|
name: String,
|
|
description: String,
|
|
enabled: bool,
|
|
processor: Box<dyn Fn(&mut core::Mat, DateTime<Utc>) -> Result<()> + Send + Sync>,
|
|
}
|
|
```
|
|
|
|
This allows for creating hooks without implementing the full trait:
|
|
|
|
```rust
|
|
let hook = BasicFrameHook::new(
|
|
"brightness",
|
|
"Brightness Adjustment",
|
|
"Adjusts frame brightness by a configurable amount",
|
|
true,
|
|
|frame, _| {
|
|
// Increase brightness by 30
|
|
frame.convert_to(frame, -1, 1.0, 30.0)?;
|
|
Ok(())
|
|
}
|
|
);
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### Watermark Overlay Hook
|
|
|
|
The watermark overlay system is integrated using the hook system:
|
|
|
|
```rust
|
|
// Create a watermark hook
|
|
let watermark_hook = hooks::BasicFrameHook::new(
|
|
"watermark",
|
|
"Watermark Overlay",
|
|
"Adds timestamp, GPS, and sensor data overlay to frames",
|
|
config.watermark.enabled,
|
|
move |frame, timestamp| {
|
|
let mut watermark_instance = watermark.lock().unwrap();
|
|
watermark_instance.apply(frame, timestamp)?;
|
|
Ok(())
|
|
}
|
|
);
|
|
|
|
// Register with the hook manager
|
|
hook_manager.lock().await.register_hook(Box::new(watermark_hook));
|
|
```
|
|
|
|
### Image Enhancement Hook
|
|
|
|
A hook for enhancing low-light frames could be implemented as:
|
|
|
|
```rust
|
|
let enhancement_hook = hooks::BasicFrameHook::new(
|
|
"enhance",
|
|
"Low-light Enhancement",
|
|
"Enhances visibility in low-light conditions",
|
|
true,
|
|
|frame, _| {
|
|
// Convert to YUV color space
|
|
let mut yuv = core::Mat::default();
|
|
imgproc::cvt_color(frame, &mut yuv, imgproc::COLOR_BGR2YUV, 0)?;
|
|
|
|
// Split channels
|
|
let mut channels = types::VectorOfMat::new();
|
|
core::split(&yuv, &mut channels)?;
|
|
|
|
// Apply CLAHE to Y channel
|
|
let clahe = imgproc::create_clahe(2.0, core::Size::new(8, 8))?;
|
|
clahe.apply(&channels.get(0)?, &mut channels.get_mut(0)?)?;
|
|
|
|
// Merge channels back
|
|
core::merge(&channels, &mut yuv)?;
|
|
|
|
// Convert back to BGR
|
|
imgproc::cvt_color(&yuv, frame, imgproc::COLOR_YUV2BGR, 0)?;
|
|
|
|
Ok(())
|
|
}
|
|
);
|
|
|
|
hook_manager.lock().await.register_hook(Box::new(enhancement_hook));
|
|
```
|
|
|
|
### Debug Information Hook
|
|
|
|
A hook for adding debug information to frames during development:
|
|
|
|
```rust
|
|
let debug_hook = hooks::BasicFrameHook::new(
|
|
"debug",
|
|
"Debug Overlay",
|
|
"Adds debug information for development",
|
|
cfg!(debug_assertions),
|
|
|frame, timestamp| {
|
|
// Add frame rate information
|
|
static mut LAST_FRAME: Option<DateTime<Utc>> = None;
|
|
static mut FRAME_COUNTER: u32 = 0;
|
|
static mut FRAME_RATE: f64 = 0.0;
|
|
|
|
unsafe {
|
|
FRAME_COUNTER += 1;
|
|
|
|
if let Some(last) = LAST_FRAME {
|
|
let duration = timestamp - last;
|
|
if duration.num_milliseconds() > 1000 {
|
|
FRAME_RATE = FRAME_COUNTER as f64 / duration.num_seconds() as f64;
|
|
FRAME_COUNTER = 0;
|
|
LAST_FRAME = Some(timestamp);
|
|
}
|
|
} else {
|
|
LAST_FRAME = Some(timestamp);
|
|
}
|
|
|
|
imgproc::put_text(
|
|
frame,
|
|
&format!("FPS: {:.1}", FRAME_RATE),
|
|
core::Point::new(10, 30),
|
|
imgproc::FONT_HERSHEY_SIMPLEX,
|
|
1.0,
|
|
core::Scalar::new(0.0, 255.0, 0.0, 255.0),
|
|
2,
|
|
imgproc::LINE_AA,
|
|
false,
|
|
)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
);
|
|
```
|
|
|
|
## Advanced Usage
|
|
|
|
### Hook Prioritization
|
|
|
|
Although not explicitly implemented in the current version, the hook system design allows for future extension to support ordered hook execution:
|
|
|
|
```rust
|
|
// Future enhancement - add priority to hooks
|
|
hook_manager.register_hook_with_priority(Box::new(preprocessing_hook), 10);
|
|
hook_manager.register_hook_with_priority(Box::new(enhancement_hook), 20);
|
|
hook_manager.register_hook_with_priority(Box::new(watermark_hook), 30);
|
|
```
|
|
|
|
### Conditional Hooks
|
|
|
|
Hooks can be created that only activate under certain conditions:
|
|
|
|
```rust
|
|
let night_mode_hook = hooks::BasicFrameHook::new(
|
|
"night_mode",
|
|
"Night Mode Enhancement",
|
|
"Enhances frames during night time",
|
|
true,
|
|
move |frame, timestamp| {
|
|
// Only apply during night hours (8 PM to 6 AM)
|
|
let hour = timestamp.hour();
|
|
if hour >= 20 || hour < 6 {
|
|
// Apply night-time enhancement
|
|
// ...
|
|
}
|
|
Ok(())
|
|
}
|
|
);
|
|
```
|
|
|
|
### Dynamic Hook Configuration
|
|
|
|
The hook system allows for runtime configuration changes:
|
|
|
|
```rust
|
|
// Find a hook by ID and update its configuration
|
|
if let Some(hook) = hook_manager.lock().await.get_hook("watermark") {
|
|
let mut hook = hook.lock().unwrap();
|
|
hook.set_enabled(new_config.watermark.enabled);
|
|
}
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
The hook system is designed with performance in mind:
|
|
|
|
1. **Minimal Overhead**: Hooks that are disabled have almost zero impact on performance
|
|
2. **Thread Safety**: The use of Arc<Mutex<>> enables safe concurrent access
|
|
3. **Lazy Evaluation**: Hooks are only processed when frames are being processed
|
|
4. **Efficient Registration**: Hook registration is a one-time cost at startup
|
|
|
|
For resource-constrained environments, consider:
|
|
- Limiting the number of active hooks
|
|
- Optimizing individual hook processing functions
|
|
- Using condition checks to skip processing when not needed
|
|
|
|
## Extending the System
|
|
|
|
The hook system can be extended in several ways:
|
|
|
|
1. **Adding New Hooks**: Implement the `FrameHook` trait for new functionality
|
|
2. **Hook Factory**: Create a factory pattern for generating hooks from configuration
|
|
3. **Hook Pipelines**: Group hooks into pipelines for different processing scenarios
|
|
4. **Hook Events**: Add event callbacks for hook lifecycle events
|
|
|
|
## Conclusion
|
|
|
|
The Frame Hook System provides a powerful and flexible architecture for extending the frame processing capabilities of the meteor detection system. By breaking down frame processing into modular hooks, it enables a clean separation of concerns and allows for easy addition of new features without modifying existing code.
|