ADR-0003: Native RiO-DETR OBB integration
- Status: Superseded (previously Proposed) —
Pose/OBB support was removed from the library on 2026-09-25. The implementation is
preserved in the
archive/pose-obb-gstreamertag. - Date: 2026-09-07
- Deciders: nitid maintainers
- Related: ADR-0002, RiO-DETR
Context
nitid is expanding from D-FINE-family detection, instance segmentation, semantic segmentation, and DETRPose into oriented object detection. The public API is also moving toward a model-family-neutral constructor:
from nitid import NITID
model = NITID("model1s", task="obb")
The local RiO-DETR-master checkout contains the OBB implementation chosen for this integration. The
released code is a clean RT-DETRv2-OBB framework, not the complete paper implementation. Its README
states that paper-specific RiO-DETR improvements were not released because of institutional IP
restrictions, while the released framework includes baseline RT-DETR-OBB code and pretrained weights.
This means nitid should advertise the integration as RiO-DETR/RT-DETRv2-OBB-backed oriented detection,
not as a full reproduction of unreleased paper internals.
The OBB path is structurally separate from D-FINE segmentation and DETRPose. It includes its own decoder, denoising logic, criterion, matcher, postprocessor, DOTA-style datasets, OBB transforms, and evaluation code. The integration must therefore be native and registry-driven rather than a small conditional branch inside existing D-FINE detection code.
Source extraction map
The audit identified these RiO-DETR source areas as integration candidates:
| Area | RiO-DETR source | Purpose in nitid |
|---|---|---|
| OBB decoder | engine/rtv4/rtdetrv2_obb_decoder.py |
Build RT-DETRv2-OBB heads for task="obb" |
| OBB denoising | engine/rtv4/denoising_obb.py |
Training-time denoising groups |
| OBB criterion | engine/rtv4/rtv4_obb_criterion.py |
loss_focal, loss_l1, loss_kld |
| OBB matcher | engine/rtv4/obb_matcher.py |
Hungarian matching with class, KLD/GD, and optional Hausdorff costs |
| OBB box math | engine/rtv4/utils_obb.py and engine/rtv4/box_ops.py |
KLD/GD loss and rotated-box utilities |
| OBB postprocessor | engine/rtv4/postprocessor.py::PostProcessorOBB |
Convert logits and normalized OBB predictions to deployment outputs |
| OBB transforms | engine/data/transforms/transforms_obb.py and mosaic_obb.py |
Resize, flip, crop, mosaic, sanitize, and convert OBB annotations |
| DOTA dataset | engine/data/dataset/dota_dataset.py |
Parse DOTA text annotations |
| DIOR-R/FAIR1M/HRSC adapters | engine/data/dataset/dior_dataset.py, fair1m_dataset.py, hrsc_dataset.py |
Optional compatibility targets after DOTA path is stable |
| Evaluator | engine/data/dataset/dota_evaluator.py |
DOTA-style OBB mAP and submission artifacts |
| Visualization | engine/misc/vis_obb.py |
Reference plotting behavior for rotated boxes |
| Export references | tools/deployment/export_onnx.py, tools/inference/onnx_inf.py |
Shape/output contract checks for deployment |
The integration should not import from RiO-DETR-master at runtime and should not package the
reference checkout. Adapted code must live inside the installable nitid package with attribution where
required. The repository-root THIRD_PARTY_NOTICES.md records the released
framework attribution, inherited upstream notices, and audited source revisions.
OBB representation contract
RiO-DETR uses a five-value oriented box internally:
cx, cy, w, h, angle_norm
where angle_norm is normalized over [0, 1] and maps to [0, 180] degrees. The released
postprocessor converts normalized predictions to:
cx, cy, w, h, angle_radians
by multiplying the angle channel by pi. It returns:
labels, boxes, scores
in deploy mode, where boxes has shape [B, N, 5].
nitid should keep the RiO-compatible representation internally for checkpoint compatibility, but expose a more ergonomic public result object:
result.obb.xywhr # cx, cy, w, h, angle in radians
result.obb.xyxyxyxy # polygon corners for drawing/export consumers
result.obb.conf
result.obb.cls
For ONNX export, the first supported contract should mirror RiO-DETR deploy mode:
labels, boxes, scores
with boxes = [cx, cy, w, h, angle_radians]. Polygon output can be added later if deployment consumers
need an angle-free format.
Model and weight metadata
The checked-in model zoo manifests under RiO-DETR-master/model_zoo/rtdetrv2_obb/ define released
weights hosted on Hugging Face at RicePasteM/RT-DETR-OBB.
Supported release families found in the manifests:
| Weights key | Variants | Notes |
|---|---|---|
diorr |
n, s, m, l, x |
DIOR-R pretrained OBB weights |
dota_1_ss |
n, s, m, l, x |
DOTA-v1.0 single-scale weights |
dota_1_ms |
m, x |
DOTA-v1.0 multi-scale weights |
Suggested nitid aliases:
| User value | Registry key |
|---|---|
default |
dota_1_ss |
dota, dota_ss |
dota_1_ss |
dota_ms |
dota_1_ms |
diorr |
diorr |
NITID("model1s", task="obb", weights="default") should resolve to the RT-DETRv2-OBB-S DOTA-v1.0
single-scale checkpoint unless later benchmarks justify a different default.
Dataset contract
The first supported OBB dataset format should be DOTA-style because it is the native path in RiO-DETR:
dataset/
├── train/
│ ├── images/
│ └── annfiles/
└── val/
├── images/
└── annfiles/
Each annotation file contains one object per line:
x1 y1 x2 y2 x3 y3 x4 y4 class_name difficulty
nitid dataset YAML should remain explicit and task-aware:
task: obb
path: datasets/dota8
train: train/images
val: val/images
train_ann: train/annfiles
val_ann: val/annfiles
names:
0: plane
1: ship
YOLO OBB labels can be added after DOTA parsing, training, and validation are stable.
Options considered
- Import
RiO-DETR-masterdirectly. This is fastest initially, but leaks another registry, training framework, config loader, dependency surface, and path assumptions into nitid. - Vendor the full RiO-DETR tree. This preserves upstream structure but makes nitid look like a wrapper around multiple application repositories and complicates packaging, testing, and docs.
- Native port of only required OBB components. This requires more careful extraction but keeps nitid installable, coherent, task-aware, and compatible with its existing training/inference/export conventions.
- Reimplement OBB support from scratch. This maximizes control but loses compatibility with released RiO-DETR checkpoints and repeats substantial tested upstream work.
Decision
Choose option 3. RiO-DETR OBB support will be implemented natively inside nitid. The reference checkout is development-only and must not be imported or required at runtime.
The integration will proceed in this order:
- add the model-family-neutral
NITIDregistry and model-name parser; - port the minimal RT-DETRv2-OBB architecture, postprocessor, criterion, matcher, and OBB utilities;
- register cleaned OBB configs for
model1{n,s,m,l,x}; - add task-aware pretrained weight resolution from the RiO-DETR manifests;
- add native
Results.obbrepresentation and plotting; - enable prediction and export;
- add DOTA-style dataset parsing;
- add OBB training and validation;
- update docs, examples, packaging checks, and release tests.
Consequences
nitid becomes responsible for maintaining the adapted OBB path, including checkpoint compatibility, device support, tests, docs, and attribution. This is more work than direct importing, but it keeps the library self-contained and avoids another long-lived external runtime dependency.
The first OBB release should be conservative: DOTA-style data, RiO-compatible [cx, cy, w, h,
angle_radians] prediction/export boxes, and the pretrained variants verified from the provided
manifests. DIOR-R, FAIR1M, HRSC2016, YOLO OBB labels, polygon export, and DOTA online submission
workflows should be added only after the core OBB path is tested.
Because the released RiO-DETR repository explicitly excludes some paper-specific improvements, nitid must avoid overclaiming paper-level RiO-DETR reproduction. The supported feature should be described as native oriented object detection using the released RiO-DETR/RT-DETRv2-OBB implementation and weights.