Train on the GPU box. Send the infer box a small graph.

oriented-det writes a pre-NMS ONNX file. The graph decodes the boxes. A few lines of Python prepare the image and run the rotated NMS. The machine that runs it needs numpy, Pillow, and ONNX Runtime.

For a tiled optical scene at 1024 pixels, that is enough to ship this week. The commands are below.

ONNX Runtime overlay — Rotated FCOS DOTA 1× Hub on the export demo tile (score ≥ 0.20, NMS 0.1)

ONNX Runtime overlay — Rotated FCOS DOTA 1× Hub on the export demo tile (score ≥ 0.20, NMS 0.1)


Producer vs consumer Link to heading

Producer (checkpoint → ONNX), from a checkout:

uv pip install -e ".[export]"
odet pretrained download rotated_fcos_dota_le90_1x
make export-onnx
# or:
odet export onnx \
  --config runs/rotated_fcos/<ts>/config.json \
  --checkpoint runs/rotated_fcos/<ts>/checkpoints/checkpoint_best.pth \
  --output ./onnx_export/model.onnx

This is odet export (same CLI as python -m export).

Modes: rotated_fcos_pre_nms (default), oriented_rcnn_pre_nms, faster_rcnn_pre_nms.

Consumer (infer only):

pip install -r export/requirements-runtime.txt
# or from the copied bundle:
cd onnx_export
pip install -r requirements-runtime.txt
python demo.py
from PIL import Image
from export.runtime import detect_image  # or: from runtime import detect_image

dets = detect_image(Image.open("tile.jpg"), "onnx_export/model.onnx")
# each det: cx, cy, w, h, angle_rad, score, label, class_name

Artifacts land in onnx_export/: model.onnx, model.export_meta.json, and copies of preprocess / nms / postprocess / runtime.


Same tile, PyTorch vs ORT Link to heading

Input is the fixed 1024×1024 export demo tile (already matches the DOTA canvas — no sliding window).

Input — Pleiades Neo planes demo tile used by make export-demo

Input — Pleiades Neo planes demo tile used by make export-demo

PyTorch — odet image-demo with hf://rotated_fcos_dota_le90_1x (score ≥ 0.20, NMS 0.1)

PyTorch — odet image-demo with hf://rotated_fcos_dota_le90_1x (score ≥ 0.20, NMS 0.1)

ONNX Runtime — odet export demo on the same checkpoint graph

ONNX Runtime — odet export demo on the same checkpoint graph

On this run both paths kept 6 boxes after NMS (4 plane, 2 helicopter) at score ≥ 0.20 / NMS IoU 0.1. See export/PARITY.md for the parity protocol.


What is in graph — and what is not Link to heading

In this releaseOut of graph
Rotated FCOS / Oriented R-CNN / Faster R-CNNRetinaNet detect (heads-only subgraph only)
Fixed 1024×1024 canvas (DOTA tiles)keep_ratio + pad (HRSC / SSDD / HRSID)
Decode inside ONNX; numpy rotated NMSSliding-window tiling

ONNX input is NCHW RGB, already mean/std-normalized — do not feed raw JPEGs into the graph. Sliding-window large scenes still go through PyTorch odet image-demo / odet preds until tiling lands in the export path.



Written on October 8, 2026 by Jeff Faudi. Link to heading