component assesment and fixes done

This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-11-30 16:09:31 +02:00
parent a172b21aac
commit ce9760fcbe
22 changed files with 681 additions and 1844 deletions
@@ -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
```