wikillm

Paper · 2024-09-29 · cs.CV

OrientedFormer: An End-to-End Transformer-Based Oriented Object Detector in Remote Sensing Images

Transformer detector for oriented boxes in remote-sensing images. Boxes become Gaussians for the positional encoding; decoder self-attention gets Gaussian Wasserstein distance biases; cross-attention samples features at points rotated by box angle. Author-reported ResNet-50 AP50: 67.28 on DIOR-R, 75.37 on DOTA-v1.0 (+1.16 and +1.21 over ARS-DETR).

Object detectionObject queries (learned query slots in transformer decoders)Positional encodingBipartite matching for set-prediction lossesoriented-object-detectionremote-sensingdetrpositional-encodingcross-attention

arXivPDFCodeMarkdown17 min read

AI-compiled by claude-haiku-5-5 on 2026-10-18, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Photos taken from satellites and aircraft show objects such as planes, ships and vehicles. These objects are often tilted at arbitrary angles and packed closely together. A standard detector draws upright rectangles around objects, which fit tilted objects poorly.

This paper builds on a detector that uses a transformer to predict all objects in one pass, with no hand-written step to remove duplicate boxes afterwards. The authors adapt that design to tilted rectangles in three places. First, each tilted rectangle is turned into a soft blob, so its position, size and angle are described in one shared way. Second, the attention that lets predictions interact is given a bias based on how far apart the blobs are, which helps the model avoid duplicate predictions. Third, when the model reads image features for an object, it looks at points arranged around the object and rotates that arrangement to match the object's tilt.

The authors report better accuracy than earlier detectors of this kind on several remote-sensing benchmarks, while training for fewer epochs. All numbers are theirs, and the detector is built on existing detection code, so the card's pitfalls section matters as much as the headline results.

TL;DR

OrientedFormer is an end-to-end transformer detector for rotated boxes in remote-sensing images. It adds three things to a DETR-style decoder: a Gaussian positional encoding of (x, y, w, h, θ), a bias from Gaussian Wasserstein distances in decoder self-attention, and a cross-attention whose sampling points rotate with each box angle §3.3 §3.4 §3.5. Author-reported ResNet-50 results are 67.28 AP50 on DIOR-R and 75.37 on DOTA-v1.0 single-scale, against 66.12 and 74.16 for ARS-DETR tab. 3 tab. 4. The official code is Apache-2.0 and differs from the paper in several places, including a learnable bias scale and an NMS step in its query initialisation (see Paper vs code). Training takes 12 epochs in the authors' runs, against 36 for two end-to-end baselines §4.8, but the model is about 2.8 times the FLOPs of those baselines tab. 14.

Problem

Oriented objects rotate freely, and transformer detectors with positional encodings for upright boxes miss this in three ways §1.

  1. The encoding covers position and size but not angle, so the model cannot tell box orientation from the query itself §1 §2.3.
  2. Self-attention sees only the content of each query. It does not see the geometric relation between the boxes that the queries describe §1 §2.2.
  3. Cross-attention samples image features at points that do not line up with a tilted box, so the features it reads are misaligned with the object §1 §2.2.

The method assumes a one-to-one assignment between predictions and objects, trained with a Hungarian match and no hand-designed post-processing §3.6. The code adds a DDQ-style query initialisation that does use NMS (see Paper vs code).

Method

Overview. The encoder is not used. Multi-scale backbone features are mapped to a common width D = 256 §3.1. Queries are initialised by an enhancement method §3.1 fig. 2. Each object query has a content part Q_c (N × D) and a positional part Q_p (N × 5), where N is the number of queries and Q_p holds the oriented box §3.2. Each decoder layer runs self-attention, oriented cross-attention and a feed-forward network. It then predicts classes and boxes and updates Q_p from Q_c §3.1 alg. 1. The loss is applied to every decoder layer §3.6.

Gaussian positional encoding §3.3 fig. 3. An oriented box (x, y, w, h, θ) is a 2-D Gaussian with mean (x, y) and covariance R · diag(w²/4, h²/4) · Rᵀ, where R is the rotation by θ eq. 2. The standard sinusoidal encoding eq. 1 is rewritten as a sine and cosine of a scaled coordinate eq. 3. Its value under a Gaussian input is the expectation of the sine or cosine, which equals the sine or cosine of the mean damped by exp(−σ²/2) eq. 4 eq. 5. The Gaussian positional encoding is that expectation for each coordinate, computed with the scaled covariance, so only the diagonal of the covariance is needed eq. 6 eq. 7.

Wasserstein self-attention §3.4 fig. 4. For two boxes with Gaussians N(μ₁, Σ₁) and N(μ₂, Σ₂), the squared 2-Wasserstein distance is ‖μ₁ − μ₂‖² plus the trace of Σ₁ + Σ₂ − 2(Σ₁^½ Σ₂ Σ₁^½)^½ eq. 8. The paper rescales this into a bias G_ij = log(1/(τ + d_ij) + ε), with τ = 1 and ε = 10⁻⁷, where d_ij is the distance itself eq. 9. Coinciding queries get G = 0, and far-apart queries get about log ε §3.4. The attention logits are (Q_c + φ)(Q_c + φ)ᵀ / √d_q + G, and the values are Q_c eq. 10. The bias adds no parameters, and the paper gives the cost as O(D²N + DN²) §3.4.

Oriented cross-attention §3.5 fig. 5. A positional query (x, y, w, h, θ) is converted to (x, y, z, r, θ) with z = log₂√(wh) and r = log₂(h/w) eq. 11. Offsets (Δx, Δy, Δz) come from a linear layer on Q_c eq. 12. The offsets are scaled by the box size, and the in-plane pair is rotated by θ eq. 13 eq. 14. Values are bilinear samples of every feature level at the rotated points divided by the level stride eq. 15. Each level is weighted by a sigmoid of the squared gap between the sampling depth z̃ and log₂ of the stride, with softness η = 2 eq. 16. A channel gate eq. 17 and then a spatial gate eq. 18 are applied, both computed from Q_c. The heads are flattened, projected to width D, and added back to Q_c §3.5. The paper gives g = 64 heads and O = 32 points per head as the default tab. 9. The paper lists four ways this differs from deformable attention: it rotates points, uses three attention types, learns its positional queries, and samples in a virtual 3-D space §3.5.

Matching and loss §3.6 alg. 1 eq. 19. Predictions are matched to objects one-to-one with the Hungarian algorithm. The loss is 2 times a focal classification loss, plus 2 times an L1 box loss, plus 5 times a rotated-IoU loss eq. 19 §4.2.

The pseudocode below is written from the equations and the algorithm. Paper vs code lists where the official code differs.

Pseudocode
# Gaussian positional encoding of one oriented box  [§3.3] [eq. 2] [eq. 6]
# Input:  box (x, y, w, h, theta); temperature T; num_feats (64)
# Output: encoding of length 4 * num_feats (256)

def gaussian_pe(box, temperature, num_feats):
    # Mean is the centre of the box  [eq. 2]
    mean = (box.x, box.y)                                   # (2,)
    # Covariance from size and angle: R diag(w^2/4, h^2/4) R^T  [eq. 2]
    rot = rotation_matrix(box.theta)                        # (2, 2)
    cov = rot @ diag(box.w ** 2 / 4, box.h ** 2 / 4) @ rot.T  # (2, 2)
    var = diagonal(cov)                                     # (2,)
    encoding = []
    for coord in (0, 1):                                    # x, then y
        for k in range(num_feats):
            # Frequency for index k, shared by the sine and cosine  [eq. 1]
            freq = temperature ** (2 * (k // 2) / num_feats)
            # Expectation of sin and cos under the scaled Gaussian  [eq. 6]
            damp = exp(-0.5 * var[coord] / freq ** 2)
            encoding.append(damp * sin(mean[coord] / freq))
            encoding.append(damp * cos(mean[coord] / freq))
    return encoding
Pseudocode
# Squared 2-Wasserstein distance between two boxes' Gaussians  [eq. 8]
# Input:  means (2,), covariances (2, 2) for boxes a and b
# Output: scalar

def squared_wasserstein(mean_a, cov_a, mean_b, cov_b):
    # Squared distance between the centres  [eq. 8]
    centre = sum((mean_a - mean_b) ** 2)
    # Covariance term: Tr(A + B - 2 (A^1/2 B A^1/2)^1/2)  [eq. 8]
    root = sqrtm(sqrtm(cov_a) @ cov_b @ sqrtm(cov_a))
    return centre + trace(cov_a + cov_b - 2 * root)
Pseudocode
# Gaussian Wasserstein bias for all pairs of N queries  [§3.4] [eq. 9]
# Input:  means (N, 2), covs (N, 2, 2)
# Output: bias (N, N), added to the attention logits

def wasserstein_bias(means, covs, tau=1.0, eps=1e-7):
    bias = zeros(N, N)                                      # (N, N)
    for i in range(N):
        for j in range(N):
            sq = squared_wasserstein(means[i], covs[i], means[j], covs[j])
            dist = sqrt(sq)
            # Zero for coinciding queries, about log(eps) for distant ones
            bias[i, j] = log(1.0 / (tau + dist) + eps)
    return bias
Pseudocode
# Wasserstein self-attention, one head  [§3.4] [eq. 10]
# Input:  content (N, D), pe (N, D), bias (N, N), head width d_q
# Output: updated content (N, D)

def wasserstein_self_attention(content, pe, bias, d_q):
    # Positional encoding enters the scores only  [eq. 10]
    keys_input = content + pe                               # (N, D)
    scores = keys_input @ keys_input.T / sqrt(d_q) + bias   # (N, N)
    # Values are the plain content queries  [eq. 10]
    return softmax(scores, axis=-1) @ content               # (N, D)
Pseudocode
# Oriented cross-attention for one query  [§3.5] [eq. 11]-[eq. 18]
# Input:  features f^l with strides s^l; content (D,); box (x, y, w, h, t)
# Output: content update (D,)

def oriented_cross_attention(features, strides, content, box):
    # Virtual coordinates of the box  [eq. 11]
    z = log2(sqrt(box.w * box.h))
    r = log2(box.h / box.w)
    # Offsets per head and point, from the content query  [eq. 12]
    offsets = linear(content).reshape(g, O, 3)              # (g, O, 3)
    # Offsets scaled by box size; exponent z - r/2 is what [eq. 11] implies
    dx = offsets[..., 0] * 2 ** (z - r / 2)                 # (g, O)
    dy = offsets[..., 1] * 2 ** (z + r / 2)                 # (g, O)
    # Rotate the offsets about the box centre by its angle  [eq. 14]
    cos_t, sin_t = cos(box.t), sin(box.t)
    points_x = box.x + cos_t * dx - sin_t * dy              # (g, O)
    points_y = box.y + sin_t * dx + cos_t * dy              # (g, O)
    # Sampling depth of each point  [eq. 13]
    z_points = z + offsets[..., 2]                          # (g, O)
    values = zeros(g, O, D // g)
    for level, stride in zip(features, strides):
        # Scale weight of this level for each point  [eq. 16], eta = 2
        weight = sigmoid(-(z_points - log2(stride)) ** 2 / 2.0)
        # Bilinear sample of this level at the points / stride  [eq. 15]
        sampled = bilinear(level, stack(points_x, points_y) / stride)
        values += weight * sampled
    # Channel gate from the content, then spatial gate  [eq. 17] [eq. 18]
    values = channel_gate(content) * values
    values = spatial_gate(content) * values
    # Flatten heads and points, project to D, add back  [§3.5]
    return linear_out(values.flatten()) + content
Pseudocode
# Training loss over all decoder layers  [§3.6] [eq. 19] [alg. 1]
# Input:  per-layer class scores and boxes; ground-truth boxes and classes
# Output: scalar loss

def training_loss(layers, gt_boxes, gt_classes):
    total = 0.0
    for layer in layers:
        # One-to-one Hungarian matching of predictions to objects  [§3.6]
        pred_idx, gt_idx = hungarian(layer.scores, layer.boxes,
                                     gt_boxes, gt_classes)
        # Weights 2, 2 and 5 for focal, L1 and rotated IoU  [§4.2] [alg. 1]
        total += 2.0 * focal_loss(layer.scores, pred_idx, gt_classes)
        total += 2.0 * l1_loss(layer.boxes[pred_idx], gt_boxes[gt_idx])
        total += 5.0 * rotated_iou_loss(layer.boxes[pred_idx],
                                        gt_boxes[gt_idx])
    return total

Hyperparameters

Values marked "code" were read from the official repository at code_commit. Where the paper and the config differ, both are shown in Paper vs code.

NameValueWhereNotes
OptimiserAdamW, β = (0.9, 0.999)tab. 2Config sets AdamW with lr and weight decay only (betas not set) orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Base learning rate5e-5§4.2 tab. 2Same config, lr orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Weight decay1e-6tab. 2Same config orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Batch size4 (2 GPUs × 2 images)§4.2 tab. 2Base dataset has batch 2 per GPU [code: configs/base/datasets/dior.py#L37]
Epochs12 (DIOR-R, DOTA 1x); 24 (HRSC2016, ICDAR2015)§4.2 tab. 21x schedule has 12 epochs [code: configs/base/schedules/schedule_1x.py#L2]
Learning-rate decayDivided by 10 at epochs 8 and 11 (16 and 22 for 24-epoch runs)§4.2 tab. 2Milestones 8 and 11 [code: configs/base/schedules/schedule_1x.py#L19]
Warm-up500 iterations, factor 0.333tab. 2Not found in the OrientedFormer configs or schedule_1x (grep)
Gradient clippingTable labels: value 1.0, norm 2.0tab. 2Config: max_norm 1, norm_type 2 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Loss weightsRotated IoU 5, focal 2, L1 2§4.2 alg. 1 eq. 19Decoder weights orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Matching cost weightsNot stated§3.6Code: focal 2, L1 2, IoU 5 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Object queries N300 (default)§3.2 tab. 9Ablation 100 to 500 tab. 9 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Channel width D256§3.1 §3.2orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Decoder layers2alg. 1orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Feature levels L5 in the algorithm; 4 backbone layers chosen in the ablationalg. 1 tab. 15Code uses 5 strides 4 to 64 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Heads g64tab. 9Ablation 8 to 128 tab. 9 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Sampling points O32 per headtab. 9Ablation 8 to 128 tab. 9 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Scale softness η2eq. 16 §3.5Code default oriented_attention.py
Wasserstein τ, ετ = 1; ε = 1e-7eq. 9Code default τ orientedformer_decoder_layer.py and ε orientedformer_decoder_layer.py
Self-attention headsNot stated§3.4Code: 8 heads orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Gate reductionNot stated§3.5Code: reduction 4, hidden width 64 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
FFN widthNot stated§3.1Code: 2048 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py
Input sizeDOTA 1024 × 1024; DIOR-R 800 × 800; ICDAR 800 × 800; HRSC 512 to 800 range§4.2DOTA resize to 1024 [code: configs/base/datasets/dota.py#L10]
AugmentationRandom flips§4.2DOTA: flip probability 0.75 in horizontal, vertical and diagonal directions [code: configs/base/datasets/dota.py#L10-L16]
BackboneResNet-50, ResNet-101, Swin-T, LSK-T (ImageNet pre-trained)§4.2 tab. 3ResNet-50 with frozen stage 1 in config orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py

Results

All numbers are author-reported. Baseline numbers are copied from the baseline papers, except ICDAR2015, where the authors re-implemented baselines in MMRotate §4.3. Setup: 2 × RTX 2080 Ti, MMRotate-based code §4.2. Dataset sizes: DIOR-R 23,463 images and 20 classes; DOTA-v1.0 2,806 images and 15 classes; DOTA-v2.0 11,268 images and 18 classes §4.1.

SettingMetricBaselineThis paperSource
DIOR-R, ResNet-50, 1xAP50ARS-DETR 66.12; DCFL 66.8067.28tab. 3
DIOR-R, Swin-TAP50not given68.84tab. 3
DIOR-R, LSK-TAP50not given65.07tab. 3
DOTA-v1.0, ResNet-50, single-scaleAP50ARS-DETR 74.16; Oriented R-CNN 75.8775.37tab. 4
DOTA-v1.0, ResNet-50, multi-scaleAP50SCRDet++ (R101) 76.2079.06tab. 4
DOTA-v1.0, Swin-T / ResNet-101AP50not given75.88 / 75.92tab. 4
DOTA-v1.5, ResNet-50, single-scaleAP50ReDet 66.8667.06tab. 5
DOTA-v2.0, ResNet-50AP50Oriented R-CNN 53.28; DCFL 51.5754.27tab. 8
HRSC2016, ResNet-50mAP (VOC07 / VOC12)Oriented R-CNN 90.40 / 96.5090.17 / 96.48tab. 7
ICDAR2015, ResNet-50Precision / Recall / FRoI Transformer 78.2 / 80.7 / 79.485.3 / 74.2 / 79.4tab. 6

Convergence §4.8 fig. 8 fig. 9. On DIOR-R with 12 epochs and 300 queries, the ResNet-50 model reaches 67.3 AP50, against 31.2 for Deformable DETR-O with CSL and 38.9 for ARS-DETR (text values). On DOTA-v1.0, it reaches 75.37 in 12 epochs, against 74.16 for ARS-DETR and 69.48 for Deformable DETR-O, both at 36 epochs §4.8.

Ablations (AP50, DIOR-R, ResNet-50 unless stated).

StudySettings and AP50Source
Object queries100: 65.16; 200: 66.42; 300: 67.28; 400: 67.13; 500: 66.93tab. 9 (a)
Sampling points per head8: 65.60; 16: 67.02; 32: 67.28; 64: 66.27; 128: 66.97tab. 9 (b)
Heads8: 66.33; 16: 66.63; 32: 66.73; 64: 67.28; 128: 66.78tab. 9 (c)
Positional encodingnone: 66.85; deformable: 65.97; DAB: 66.03; learnable: 64.27; Gaussian: 67.28tab. 10
Self-attention biasnone: 67.03; IoF: 66.57; IoU: 67.08; Wasserstein: 67.28tab. 12
Modules (DIOR-R)none: 62.69; Gaussian PE + Wasserstein: 63.08; cross-attention: 65.78; Wasserstein + cross: 66.85; Gaussian PE + cross: 67.03; all three: 67.28tab. 11
Modules (DOTA-v1.0, AP50)none: 73.81; Gaussian PE + Wasserstein: 74.55; cross: 74.64; Wasserstein + cross: 74.69; Gaussian PE + cross: 74.76; all three: 75.37tab. 13
Sampling offsetsfixed: 65.98; deformable: 66.66; random: 66.70; oriented: 67.28tab. 16
Backbone layers used1: 56.21; 2: 60.69; 3: 66.37; 4: 67.28tab. 15

Speed and size (DOTA-v1.0, tab. 14). OrientedFormer with ResNet-50 runs at 11.4 FPS with 44M parameters and 529 GFLOPs, and reaches 75.37 AP50. ARS-DETR runs at 10.1 FPS with 42M parameters and 186 GFLOPs (74.16 AP50). Deformable DETR-O runs at 10.8 FPS with 41M parameters and 186 GFLOPs (69.48 AP50). Two-stage and one-stage CNN detectors in the same table run between 6.1 and 17.7 FPS.

Paper vs code

Repository: https://github.com/wokaikaixinxin/OrientedFormer at cb760790ccf1d5f9d9504e10c2c25cc2ee410fcb (Apache-2.0). It is linked from the paper's abstract, and it contains MMRotate code alongside projects/OrientedFormer, where the method lives. The repository was read at this commit; the multi-scale DOTA config (orientedformer_le90_r50_q300_layer2_head64_point32_1x_dotav1.0-ms.py) was not inspected.

  • Learnable bias scale. The paper's self-attention bias is G added to the logits as is eq. 10. The code multiplies G by a learnable scalar per head (8 heads), initialised uniformly in [0, 4], which the paper does not describe orientedformer_decoder_layer.py orientedformer_decoder_layer.py orientedformer_decoder_layer.py. The code's constant τ = 1 orientedformer_decoder_layer.py shares the name of the learnable parameter, which is a different quantity.
  • Distance normalisation. The code divides the Wasserstein distance by 2 · (det Σ_i · det Σ_j)^(1/8) by default, a step not in the paper orientedformer_decoder_layer.py. The paper's only rescaling is the log(1/(τ + d) + ε) step eq. 9.
  • Value tensor in self-attention. The code passes content + positional encoding as the one argument to the self-attention module orientedformer_decoder_layer.py. The paper uses plain Q_c as the value eq. 10. Whether the value is the same tensor depends on the mmcv MultiheadAttention default, which is not in this repository and was not checked.
  • Sampling-point exponent. The paper's sampling formula uses 2^(z−r) and 2^(z+r) eq. 13. The code uses 2^(z∓r/2) oriented_attention.py, which matches the paper's own definitions of z and r eq. 11.
  • Rotation centre. The paper rotates the sampled point (x̃, ỹ) eq. 14. The code rotates the offset around the box centre and then adds the centre oriented_attention.py. The code matches the stated aim of rotating around the positional query §1.
  • Gate layers. The paper writes γ1 twice in the channel gate eq. 17 and "Linear and ReLU" for the spatial gate eq. 18. The code uses two distinct bias-free linear layers per gate, with hidden width D/4 oriented_attention.py oriented_attention.py.
  • Offset initialisation. The code zeros the offset weights and sets their biases: x and y uniform in ±0.5 (the number of points is not a square), and Δz to −1 oriented_attention.py. The paper does not state this.
  • Losses and matching in the query initialiser. The paper says focal loss and one-to-one Hungarian matching §3.6. The DDQ-style query-initialisation head uses QualityFocalLoss with a top-k Hungarian assigner (k = 8) orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py. The decoder layers use the focal loss (γ = 2, α = 0.25, weight 2) with one-to-one matching orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py.
  • NMS. The paper's claim is that no post-processing is needed §1 §3.6. The query-initialisation head applies rotated NMS at IoU 0.7 to the top 1000 candidates before selecting queries orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py oriented_ddq_fcn.py.
  • Feature levels. The algorithm and the default config use 5 levels with strides 4 to 64 alg. 1 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py. The text picks "4 layers" as the best setting §4.10 tab. 15. The table rows are backbone layers, so the two are not the same count.
  • Warm-up. Table 2 lists 500 warm-up iterations with factor 0.333 tab. 2. Neither the OrientedFormer configs nor configs/_base_/schedules/schedule_1x.py contain a warm-up setting.
  • Augmentation. The paper says random flips §4.2. The DOTA config uses flips with probability 0.75 in horizontal, vertical and diagonal directions [code: configs/base/datasets/dota.py#L10-L16]. The DIOR config uses probability 0.75 [code: configs/base/datasets/dior.py#L10-L15].
  • Cropping. The paper crops DOTA into 1024 × 1024 patches with 200-pixel overlap §4.2. The training pipeline reads a pre-split directory and resizes to 1024 [code: configs/base/datasets/dota.py#L5] [code: configs/base/datasets/dota.py#L10]. The split script was not inspected.
  • Clipping labels. Table 2 labels the values "clip gradient value 1.0" and "clip gradient norm 2.0". The config sets max_norm 1 and norm_type 2 orientedformer_le90_r50_q300_layer2_head64_point32_1x_dior.py. These are the same settings under different labels.

Pitfalls

  • Two different τ. The code's learnable per-head τ scales the bias, and the constant τ = 1 sits inside the distance term. Implementing from the paper alone gives the bias without the learnable scale, which changes the attention behaviour.
  • Distance normalisation. Following the code means dividing the distance by the extra scale term, so the bias values differ from Eq. 9 as printed orientedformer_decoder_layer.py. Far pairs approach log(1e-7) ≈ −16.1, because the bias is log(1/(τ + d) + ε) and the square roots are clamped at 1e-7 orientedformer_decoder_layer.py.
  • Sampling exponent. Eq. 13 as printed (2^(z−r)) does not match the paper's own definitions of z and r (Eq. 11). Follow the definitions, which the code does.
  • Rotation about the origin. Read literally, Eq. 14 rotates coordinates about the image origin, which would move every sample far from its box. The intended meaning, and the code's behaviour, is rotation about the box centre.
  • Hidden NMS. The end-to-end claim holds for the decoder output, but query selection in the code uses NMS. A re-implementation that drops it will get different queries.
  • Cost hidden in the abstract. The paper states the parameter count is slightly larger than the baselines §4.9. The table shows 529 GFLOPs against 186 for ARS-DETR and Deformable DETR-O tab. 14, about 2.8 times the compute.
  • Ablation text vs table. §4.4 says the sampling-point count goes "from 4 to 32", but the table starts at 8 with 65.60 tab. 9 (b).
  • DOTA-v1.5 caption and AP. Table 5 is captioned as small-object results, but its AP50 column is not the mean of the six classes shown (for OrientedFormer that mean is 64.58, against 67.06). The AP50 is probably over all 16 classes, but the paper does not say so.
  • Not uniformly best. Oriented R-CNN (ResNet-50) has higher AP50 than OrientedFormer on DOTA-v1.0 single-scale (75.87 against 75.37) and higher mAP on HRSC2016 (90.40 against 90.17 at VOC07). The text calls the HRSC2016 result competitive. Read the comparisons from the tables.
  • ICDAR baselines. These were re-implemented by the authors in MMRotate with the same settings §4.3, so they are not the baselines' own published numbers.
  • Hardware for training. The paper trains on two RTX 2080 Ti GPUs with a batch of 4 §4.2. Speed numbers in Table 14 do not state the hardware they were measured on.
  • Version. The fetched source is the version recorded in the metadata (v2). Equation and table numbers follow that source.

Lineage

  • Builds on: DETR for the set-prediction decoder and the Hungarian matching §2.1 §3.6. Deformable DETR, the deformable-attention baseline it is compared with §2.2. DAB-DETR for box-based positional encoding §2.3. DDQ for the query-initialisation method, which the code uses in its query-selection head §3.1. Mip-NeRF is cited for the Gaussian expectation identity §3.3.
  • Compared against: ARS-DETR (closest end-to-end baseline), AO2-DETR and Deformable DETR-O with CSL as end-to-end baselines §4.3 tab. 4. CNN detectors including DCFL, Oriented R-CNN and RoI Transformer tab. 3 tab. 4 tab. 8.
  • Superseded by: not known from the content of this wiki.

Source and license

Adapted from “OrientedFormer: An End-to-End Transformer-Based Oriented Object Detector in Remote Sensing Images” by Zeyu Ding, Yong Zhou, Jiaqi Zhao, Hancheng Zhu, Wen-Liang Du, Rui Yao, Abdulmotaleb El Saddik (arXiv:2409.19648), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/wokaikaixinxin/OrientedFormer at commit cb760790ccf1 (Apache-2.0). Any quoted code is shown under that license.