feat: stage6 — Image Pipeline (F05) and Rotation Manager (F06)

This commit is contained in:
Yuzviak
2026-03-22 22:51:00 +02:00
parent a2fb9ab404
commit 9ef046d623
9 changed files with 653 additions and 26 deletions
+68
View File
@@ -0,0 +1,68 @@
"""Image Input Pipeline schemas (Component F05)."""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
import numpy as np
class ImageBatch(BaseModel):
"""Batch of raw images for processing."""
images: list[bytes]
filenames: list[str]
start_sequence: int
end_sequence: int
batch_number: int
class ImageMetadata(BaseModel):
"""Extracted metadata from an image."""
sequence: int
filename: str
dimensions: tuple[int, int]
file_size: int
timestamp: datetime
exif_data: Optional[dict] = None
class ValidationResult(BaseModel):
"""Result of batch validation."""
valid: bool
errors: list[str]
class ProcessingStatus(BaseModel):
"""Status of image pipeline processing."""
flight_id: str
total_images: int
processed_images: int
current_sequence: int
queued_batches: int
processing_rate: float
class ImageData:
"""Loaded image ready for processing."""
# Using normal class instead of BaseModel for np.ndarray support
def __init__(
self,
flight_id: str,
sequence: int,
filename: str,
image: np.ndarray,
metadata: ImageMetadata
):
self.flight_id = flight_id
self.sequence = sequence
self.filename = filename
self.image = image
self.metadata = metadata
class ProcessedBatch:
"""Batch of decoded images."""
def __init__(self, images: list[ImageData], batch_id: str, start_sequence: int, end_sequence: int):
self.images = images
self.batch_id = batch_id
self.start_sequence = start_sequence
self.end_sequence = end_sequence
+38
View File
@@ -0,0 +1,38 @@
"""Rotation schemas (Component F06)."""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
import numpy as np
class RotationResult(BaseModel):
"""Result of a rotation sweep alignment."""
matched: bool
initial_angle: float
precise_angle: float
confidence: float
# We will exclude np.ndarray from BaseModel to avoid validation issues,
# but store it as an attribute if needed or use arbitrary_types_allowed.
model_config = {"arbitrary_types_allowed": True}
homography: Optional[np.ndarray] = None
inlier_count: int = 0
class HeadingHistory(BaseModel):
"""Flight heading tracking history."""
flight_id: str
current_heading: Optional[float] = None
heading_history: list[float] = []
last_update: Optional[datetime] = None
sharp_turns: int = 0
class RotationConfig(BaseModel):
"""Configuration for rotation sweeps."""
step_angle: float = 30.0
sharp_turn_threshold: float = 45.0
confidence_threshold: float = 0.7
history_size: int = 10