"""
Object Detection in Satellite Imagery using YOLO.
"""
from dataclasses import dataclass
from typing import List, Optional
import numpy as np
import structlog
from geosight.config import settings
logger = structlog.get_logger(__name__)
@dataclass
class Detection:
"""Single object detection result."""
class_name: str
confidence: float
bbox: tuple # (x1, y1, x2, y2)
center: tuple # (x, y)
SUPPORTED_OBJECTS = [
"ship", "aircraft", "vehicle", "building",
"solar_panel", "storage_tank", "sports_field"
]
class ObjectDetector:
"""YOLO-based object detector for satellite imagery."""
def __init__(self, device: Optional[str] = None):
self.device = device or settings.model.inference_device
self._model = None
async def detect(
self,
image: np.ndarray,
object_types: List[str] = None,
confidence_threshold: float = 0.5,
) -> List[Detection]:
"""
Detect objects in satellite image.
Returns:
List of Detection objects
"""
if object_types is None:
object_types = ["ship", "aircraft", "building"]
# For demo, generate synthetic detections
return self._generate_demo_detections(image.shape[:2], object_types, confidence_threshold)
def _generate_demo_detections(
self,
image_shape: tuple,
object_types: List[str],
min_confidence: float,
) -> List[Detection]:
"""Generate demo detections."""
np.random.seed(123)
height, width = image_shape
detections = []
num_objects = np.random.randint(3, 10)
for _ in range(num_objects):
obj_type = np.random.choice(object_types)
confidence = np.random.uniform(min_confidence, 0.95)
# Random bounding box
x1 = np.random.randint(0, width - 50)
y1 = np.random.randint(0, height - 50)
w = np.random.randint(20, 80)
h = np.random.randint(20, 80)
detections.append(Detection(
class_name=obj_type,
confidence=float(confidence),
bbox=(x1, y1, x1 + w, y1 + h),
center=(x1 + w // 2, y1 + h // 2),
))
return detections