mirror of
https://github.com/azaion/gps-denied-desktop.git
synced 2026-04-23 00:16:36 +00:00
component assesment and fixes done
This commit is contained in:
@@ -13,7 +13,11 @@ class IImageRotationManager(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def try_rotation_steps(self, flight_id: str, frame_id: int, image: np.ndarray, satellite_tile: np.ndarray, tile_bounds: TileBounds, timestamp: datetime) -> Optional[RotationResult]:
|
||||
def try_rotation_steps(self, flight_id: str, frame_id: int, image: np.ndarray, satellite_tile: np.ndarray, tile_bounds: TileBounds, timestamp: datetime, matcher: IImageMatcher) -> Optional[RotationResult]:
|
||||
"""
|
||||
Performs rotation sweep.
|
||||
'matcher' is an injected dependency (usually F09) to avoid direct coupling.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
@@ -41,22 +45,27 @@ class IImageRotationManager(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def try_chunk_rotation_steps(self, chunk_images: List[np.ndarray], satellite_tile: np.ndarray, tile_bounds: TileBounds) -> Optional[RotationResult]:
|
||||
def try_chunk_rotation_steps(self, chunk_images: List[np.ndarray], satellite_tile: np.ndarray, tile_bounds: TileBounds, matcher: IImageMatcher) -> Optional[RotationResult]:
|
||||
pass
|
||||
```
|
||||
|
||||
## Component Description
|
||||
|
||||
### Responsibilities
|
||||
- Handle UAV image rotation preprocessing
|
||||
- **Critical**: LiteSAM (F09 Metric Refinement) fails if images rotated >45°, requires preprocessing
|
||||
- Perform 30° step rotation sweeps (12 rotations: 0°, 30°, 60°, ..., 330°)
|
||||
- Track UAV heading angle across flight
|
||||
- Calculate precise rotation angle from homography point correspondences
|
||||
- Detect sharp turns requiring rotation sweep
|
||||
- Pre-rotate images to known heading for subsequent frames
|
||||
- **Chunk rotation operations (rotate all images in chunk)**
|
||||
- **Chunk rotation sweeps (delegates matching to F09 Metric Refinement)**
|
||||
- Image rotation utility.
|
||||
- Heading tracking.
|
||||
- Coordination of rotation sweeps.
|
||||
|
||||
### Decoupling Fix
|
||||
- **Problem**: F06 previously depended directly on `F09 Metric Refinement`.
|
||||
- **Fix**: Methods `try_rotation_steps` and `try_chunk_rotation_steps` now accept a `matcher` argument conforming to `IImageMatcher`.
|
||||
- **IImageMatcher Interface**:
|
||||
```python
|
||||
class IImageMatcher(ABC):
|
||||
def align_to_satellite(self, uav_image, satellite_tile, tile_bounds) -> AlignmentResult: pass
|
||||
def align_chunk_to_satellite(self, chunk_images, satellite_tile, tile_bounds) -> ChunkAlignmentResult: pass
|
||||
```
|
||||
- **Runtime**: F02.2 injects F09 instance when calling F06 methods.
|
||||
|
||||
### Scope
|
||||
- Image rotation operations (pure rotation, no matching)
|
||||
@@ -103,7 +112,7 @@ np.ndarray # Rotated image (same dimensions)
|
||||
|
||||
---
|
||||
|
||||
### `try_rotation_steps(flight_id: str, frame_id: int, image: np.ndarray, satellite_tile: np.ndarray, tile_bounds: TileBounds, timestamp: datetime) -> Optional[RotationResult]`
|
||||
### `try_rotation_steps(flight_id: str, frame_id: int, image: np.ndarray, satellite_tile: np.ndarray, tile_bounds: TileBounds, timestamp: datetime, matcher: IImageMatcher) -> Optional[RotationResult]`
|
||||
|
||||
**Description**: Performs 30° rotation sweep, rotating image at each step and delegating matching to F09 Metric Refinement.
|
||||
|
||||
@@ -119,6 +128,7 @@ image: np.ndarray # UAV image
|
||||
satellite_tile: np.ndarray # Satellite reference tile
|
||||
tile_bounds: TileBounds # GPS bounds and GSD of satellite tile (passed to F09)
|
||||
timestamp: datetime # Timestamp for heading persistence
|
||||
matcher: IImageMatcher # Injected matcher (F09)
|
||||
```
|
||||
|
||||
**About tile_bounds**: `TileBounds` contains the GPS bounding box of the satellite tile:
|
||||
@@ -142,7 +152,7 @@ RotationResult:
|
||||
```
|
||||
For angle in [0°, 30°, 60°, 90°, 120°, 150°, 180°, 210°, 240°, 270°, 300°, 330°]:
|
||||
rotated_image = rotate_image_360(image, angle)
|
||||
result = F09.align_to_satellite(rotated_image, satellite_tile, tile_bounds)
|
||||
result = matcher.align_to_satellite(rotated_image, satellite_tile, tile_bounds)
|
||||
if result.matched and result.confidence > threshold:
|
||||
precise_angle = calculate_precise_angle(result.homography, angle)
|
||||
update_heading(flight_id, frame_id, precise_angle, timestamp)
|
||||
@@ -153,7 +163,7 @@ return None # No match found
|
||||
**Processing Flow**:
|
||||
1. For each 30° step:
|
||||
- Rotate image via rotate_image_360()
|
||||
- Call F09 Metric Refinement.align_to_satellite(rotated_image, satellite_tile, tile_bounds)
|
||||
- Call matcher.align_to_satellite(rotated_image, satellite_tile, tile_bounds)
|
||||
- Check if match found
|
||||
2. If match found:
|
||||
- Calculate precise angle from homography via calculate_precise_angle()
|
||||
@@ -379,7 +389,7 @@ List[np.ndarray] # Rotated images (same dimensions)
|
||||
|
||||
---
|
||||
|
||||
### `try_chunk_rotation_steps(chunk_images: List[np.ndarray], satellite_tile: np.ndarray, tile_bounds: TileBounds) -> Optional[RotationResult]`
|
||||
### `try_chunk_rotation_steps(chunk_images: List[np.ndarray], satellite_tile: np.ndarray, tile_bounds: TileBounds, matcher: IImageMatcher) -> Optional[RotationResult]`
|
||||
|
||||
**Description**: Performs 30° rotation sweep on entire chunk, rotating all images at each step and delegating matching to F09 Metric Refinement.
|
||||
|
||||
@@ -391,6 +401,7 @@ List[np.ndarray] # Rotated images (same dimensions)
|
||||
chunk_images: List[np.ndarray] # Chunk images
|
||||
satellite_tile: np.ndarray # Reference satellite tile
|
||||
tile_bounds: TileBounds # GPS bounds and GSD of satellite tile (for F09)
|
||||
matcher: IImageMatcher # Injected matcher
|
||||
```
|
||||
|
||||
**Output**:
|
||||
@@ -407,7 +418,7 @@ RotationResult:
|
||||
```
|
||||
For angle in [0°, 30°, 60°, 90°, 120°, 150°, 180°, 210°, 240°, 270°, 300°, 330°]:
|
||||
rotated_chunk = rotate_chunk_360(chunk_images, angle)
|
||||
result = F09.align_chunk_to_satellite(rotated_chunk, satellite_tile, tile_bounds)
|
||||
result = matcher.align_chunk_to_satellite(rotated_chunk, satellite_tile, tile_bounds)
|
||||
if result.matched and result.confidence > threshold:
|
||||
precise_angle = calculate_precise_angle(result.homography, angle)
|
||||
return RotationResult(matched=True, initial_angle=angle, precise_angle=precise_angle, ...)
|
||||
@@ -417,7 +428,7 @@ return None # No match found
|
||||
**Processing Flow**:
|
||||
1. For each 30° step:
|
||||
- Rotate all chunk images via rotate_chunk_360()
|
||||
- Call F09 Metric Refinement.align_chunk_to_satellite(rotated_chunk, satellite_tile, tile_bounds)
|
||||
- Call matcher.align_chunk_to_satellite(rotated_chunk, satellite_tile, tile_bounds)
|
||||
- Check if match found
|
||||
2. If match found:
|
||||
- Calculate precise angle from homography via calculate_precise_angle()
|
||||
@@ -497,8 +508,8 @@ return None # No match found
|
||||
## Dependencies
|
||||
|
||||
### Internal Components
|
||||
- **F09 Metric Refinement**: For matching during rotation sweep (align_to_satellite, align_chunk_to_satellite). F06 rotates images, F09 performs the actual matching.
|
||||
- **H07 Image Rotation Utils**: For image rotation and angle calculations
|
||||
- **Injected Matcher (F09)**.
|
||||
|
||||
**Note**:
|
||||
- `TileBounds` data model is imported from F09 Metric Refinement.
|
||||
@@ -541,4 +552,3 @@ class RotationConfig(BaseModel):
|
||||
confidence_threshold: float = 0.7 # For accepting match
|
||||
history_size: int = 10 # Number of headings to track
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user