Why detection at sea is different

Every object-detection tutorial ends with a confident bounding box around a coffee mug. The ocean disagrees with tutorials. At sea you get sun glare that saturates half the frame, whitecaps that look exactly like small buoys, a horizon that rolls ±15°, and salt spray on the lens dome within twenty minutes.

This note documents the perception stack for Remora, our autonomous surface drone, from dataset to a 21 FPS deployment on a Jetson Orin Nano.

The dataset problem

Public maritime datasets exist (Singapore Maritime, SeaShips) but they’re mostly shot from shore or large ships. From a drone 40 cm above the waterline, everything looks different. We built our own set:

  • 3,800 frames extracted from GoPro runs at the local harbour and offshore.
  • Classes: buoy_nav, buoy_mooring, vessel, kayak_sup, swimmer, debris.
  • Annotation in CVAT, roughly 30 hours of clicking.

Two augmentations mattered more than all others combined: horizontal flip and simulated glare (random white ellipse composited at 40–80% opacity). Glare augmentation alone cut daytime false negatives by a third.

Model and training

YOLOv8n, 640 px input, 120 epochs on a desktop RTX 3060:

yolo detect train data=remora.yaml model=yolov8n.pt \
  imgsz=640 epochs=120 batch=32 hsv_v=0.6 fliplr=0.5

Results on the held-out sea-state-3 test set:

ClassmAP@50
buoy_nav0.91
vessel0.88
swimmer0.79
debris0.54

Debris is hard. Debris will stay hard.

Deployment on the Jetson

Export to TensorRT with FP16 is the whole game:

yolo export model=best.pt format=engine half=True
  • PyTorch on Orin Nano: ~7 FPS
  • TensorRT FP16: 21 FPS at 640 px, ~11 W total board power

The detector feeds a simple tracker (ByteTrack) and publishes obstacle bearings to the autopilot over MAVLink OBSTACLE_DISTANCE messages. The autopilot does the actual avoiding — the neural net is only allowed to be an advisor, never a captain.

Failure log

  • Rolling horizon confused early models into detecting “vessels” in wave crests. Fix: IMU-driven horizon crop before inference.
  • Lens fouling: after 40 min, salt film cut confidence ~20% across all classes. Fix in progress: hydrophobic coating + a wiper we will absolutely over-engineer.
  • Low sun: below 15° sun elevation, swimmer recall drops badly. Operational rule for now: no autonomous transits at dawn/dusk near bathers.

Next

Thermal camera fusion for the dawn/dusk gap, and self-supervised pretraining on the 200k unlabeled frames sitting on the NAS.