Downstream evaluation: vanishing points

How useful are the segments? Calibrated Manhattan-frame (camera-rotation) estimation on York Urban (outdoor) and NYU (indoor), plus a full error-source decomposition and a fair "best estimator per detector" protocol.

1. Protocol

Hand-labelled line annotations are incomplete and geometrically coarse, so detectors are NOT scored against them. Instead each detector's segments feed the same calibrated Manhattan-frame estimator, and the recovered three orthogonal vanishing directions are compared with the datasets' reliable rotation ground truth. York Urban Database: 102 outdoor images. NYU-VP: 1033 indoor images. (The dataset images are not redistributed here — tools/yud_export.py / tools/nyu_export.py build the manifests from the official downloads; this page is numbers-only.)

2. Results with a fixed common estimator

detectorYork Urban (outdoor)
median err
NYU (indoor)
median err
SweepLSD1.04°12.7°
SweepLSD + optional linker0.99°10.7°
LSD0.92°10.7°
EDLines (ED_Lib)0.98°10.4°
ELSED0.96°10.4°
hand-labelled GT lines (estimator ceiling)0.59°6.0°

ELSED and the linker rows were measured in a verification re-run with the same estimator (the re-run reproduces the other rows within ≤0.2°). The linker row is the interesting one: re-assembling fragments across junction cuts feeds directly through to downstream support — indoors it moves SweepLSD from 12.7° into the LSD/ELSED band.

Read indoor medians with care. The indoor error distribution is bimodal: an image either succeeds (≈1.5°) or the frame search locks onto the wrong structure (≈27°). The median is just the mixing ratio of those two modes — even the hand-labelled ceiling sits at 6°. NYU is a clutter-robustness stress test, not a precision benchmark.

3. Where the differences actually come from

A per-line decomposition against the ground-truth axes (per-line residual angle, inlier support per axis, oracle/refinement splits) shows:

4. The estimator choice flips the ranking (fair protocol)

Because the differences are support-driven, they depend strongly on how the estimator weighs lines. A declared menu of twelve estimator variants, identical for every detector (line weighting × inlier band × search strength × vertical prior), was evaluated with selection and evaluation on separate data (split-half cross-validation within each dataset: variants selected by median error on one half, scored on the other, test halves pooled):

datasetdetectormedian err (CV)<2°<5°detect msVP est. mstotal ms
NYU (indoor), split-half CVSweepLSD6.08°33.2%48.6%1.52.13.7
ELSED7.67°32.4%47.1%4.01.65.7
LSD7.87°29.2%46.4%27.13.030.1
EDLines (ED_Lib)8.09°30.5%45.7%5.82.98.9
York Urban (outdoor), split-half CVELSED0.82°84.3%96.1%5.52.88.4
LSD0.83°93.1%96.1%32.03.735.7
SweepLSD0.94°85.3%95.1%1.82.44.2
EDLines (ED_Lib)1.00°89.2%98.0%7.33.511.0

Time columns: medians at 640×480, all detectors built with one toolchain and measured in one window, interleaved image-by-image (detection: median of 15 runs; VP estimation: median of 5 runs of each image's cross-validated pick, timed on the exact segments behind the accuracy columns, with the estimator's scoring stage AVX2-vectorized — output verified bit-identical to the scalar code over all 68,100 menu evaluations).

Indoors SweepLSD wins every fair protocol — now including against ELSED — once the estimator counts each line as one vote (length-weighted voting lets long clutter contours hijack the search; SweepLSD's support is many short-but-accurate lines). The optional linker compounds the indoor lead: under the identical menu and cross-validation it scores 5.23° (outdoor CV median 0.93°, indistinguishable from the linker-less 0.94°). Outdoors the result is a metric-dependent near-tie: ELSED and LSD share the best median while LSD clearly leads recall at 2°. The estimator that measured best overall — unit-weight voting × vertical-prior seed × strong candidate search — is exactly what examples/manhattan_frame.cpp implements, so the recommended configuration ships as working code.

Takeaway. "Which detector is best for vanishing points?" has no detector-only answer: it is a property of the (detector × estimator) pair. Two sets of indoor numbers appear on this page and they are measured differently, so to be explicit: the table above is the cross-validated protocol (variants selected on one half of the data, scored on the other), where SweepLSD is best at 6.08° and 5.23° with the linker. The figures usually quoted for the shipped library are the single recommended estimator run on every image, without selection: there SweepLSD measures 5.98°, and 5.25° with the optional linker — the best of all detector/estimator combinations tested (best non-SweepLSD: ELSED at 6.53°). The two protocols agree on the ordering. Either way SweepLSD stays 4.6× / 5.2× / 25× faster than ELSED / ED_Lib / LSD upstream of the estimator at Full-HD — and 2.6× / 3.8× / 17.6× on the 640×480 frames this study actually runs on (table above). Because the task is the vanishing points, not the segments, the table also prices the downstream. The estimation stage was profiled and optimized for this measurement (its former hotspot, the candidates×lines inlier scoring, is AVX2-vectorized with bit-identical output); even so it costs 1.6–3.7 ms per frame at 640×480 — the remaining work is the multi-start refinement's serial per-seed eigensolves, which cannot be batched without changing the result — and for the fastest detector that still exceeds SweepLSD's own 1.5–1.8 ms detection. End-to-end SweepLSD is the fastest pipeline on both datasets (3.7 ms on NYU against ELSED's 5.7), but the margin over ELSED compresses to 1.5–2.0×: at this resolution the shared estimator, not the detector, bounds the frame time — a property of the task, not of an unoptimized implementation. At high resolution the picture inverts — estimation stays a few milliseconds (5–6 ms at 4K; it scales with surviving lines, not pixels) while detection grows with pixel count (30–580 ms of detection at 4K on the applications page).
Reproduce it. Build with -DSWEEPLSD_BUILD_BENCH=ON; export the manifests with tools/yud_export.py (York Urban) / tools/nyu_export.py (NYU-VP); run sweeplsd_yud_eval <manifest> [--gtlines ...] [--edreal-dir ...] [--elsed-dir ...]. The fair protocol is a committed tool: sweeplsd_vp_bestcfg writes one CSV row per (image, detector, variant) and tools/vp_bestcfg_cv.py performs the split-half cross-validated aggregation (the rule reproduces the original study's published numbers exactly from its surviving records). sweeplsd_vp_bestcfg --time-runs R adds an est_ms column (downstream calibrate + Manhattan estimation, median of R runs), and vp_bestcfg_cv.py --det-dir method=DIR attaches per-image detection times in the runner file format to produce the detect / est / total columns. The recommended estimator ships as sweeplsd_manhattan / examples/manhattan_frame.cpp.
Refreshed 2026-07. The fair-protocol table was re-measured in a single run of all four detectors over the identical 12-variant menu (ELSED added); the linker rows come from the same runs. Under the fixed common estimator the re-run reproduces the §2 table within ≤0.2° — every ranking and takeaway on this page is from internally-consistent, same-run data.
Time columns added 2026-08. Detection was re-measured with all four detectors compiled by the same GCC 15.2, one process per image, interleaved image-by-image in a single window (the cross-window comparison trap). The re-generated segments reproduce the accuracy table exactly for SweepLSD (deterministic), to float rounding for ELSED (≤2×10⁻⁵ px), and to ±1–2 segments per frame for ED_Lib, whose edge chaining is build-sensitive (its NYU CV median moves 8.09°→8.95° between compiler builds of the same source and OpenCV version — the ranking is unaffected; the accuracy columns keep the stored segments' published values, and its estimation time is measured on those same stored segments). LSD's own double-precision detection is also build-sensitive at the last-bit level: recompiling it with a different GCC generation moves its cross-validated York Urban median between 0.83° and 0.94° (ELSED's and SweepLSD's by ≤0.02°; every NYU median reproduces to 0.01°) — so LSD's outdoor lead over SweepLSD is within build jitter, the stable outdoor read is ELSED ≈0.1° ahead of both, and the indoor ordering is unaffected. The estimator's scoring stage was AVX2-vectorized for the timing study, verified bit-identical to the scalar code over all 68,100 menu evaluations, both datasets.