mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 04:06:37 +00:00
feat: stage6 — Image Pipeline (F05) and Rotation Manager (F06)
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user